|
@@ -579,56 +579,11 @@ async function handleGetOrder(args: Record<string, any>): Promise<ToolCallResult
|
|
|
const policy = getDataTypePolicy(accessConfig!, 'orders');
|
|
const policy = getDataTypePolicy(accessConfig!, 'orders');
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
- // Check if Qdrant is enabled for this store
|
|
|
|
|
- const qdrantConfig = await getStoreQdrantConfig(shop_id);
|
|
|
|
|
-
|
|
|
|
|
- if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncOrders) {
|
|
|
|
|
- console.log('[MCP ShopRenter] Using Qdrant for order lookup');
|
|
|
|
|
-
|
|
|
|
|
- // Query from Qdrant - scroll through orders to find matching order_id
|
|
|
|
|
- const orders = await queryQdrantOrders(
|
|
|
|
|
- shop_id,
|
|
|
|
|
- qdrantConfig.shopname,
|
|
|
|
|
- {},
|
|
|
|
|
- 100 // Get more to search through
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Find order by innerId (order number)
|
|
|
|
|
- const order = orders.find((o: any) =>
|
|
|
|
|
- o.orderNumber === order_id || o.id === order_id
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- if (!order) {
|
|
|
|
|
- return {
|
|
|
|
|
- content: [{
|
|
|
|
|
- type: 'text',
|
|
|
|
|
- text: JSON.stringify({
|
|
|
|
|
- error: `No order found with order number: ${order_id}`
|
|
|
|
|
- })
|
|
|
|
|
- }],
|
|
|
|
|
- isError: true
|
|
|
|
|
- };
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Clean response data
|
|
|
|
|
- const cleanedOrder = cleanResponseData(order);
|
|
|
|
|
-
|
|
|
|
|
- return {
|
|
|
|
|
- content: [{
|
|
|
|
|
- type: 'text',
|
|
|
|
|
- text: JSON.stringify({
|
|
|
|
|
- source: isApiOnlyMode(policy) ? 'api_direct' : 'qdrant',
|
|
|
|
|
- access_mode: policy,
|
|
|
|
|
- notice: isApiOnlyMode(policy) ? createApiOnlyNotice('orders') : undefined,
|
|
|
|
|
- order: cleanedOrder
|
|
|
|
|
- })
|
|
|
|
|
- }]
|
|
|
|
|
- };
|
|
|
|
|
- } else {
|
|
|
|
|
- console.log('[MCP ShopRenter] Qdrant not enabled, using ShopRenter API');
|
|
|
|
|
|
|
+ // Handle api_only mode OR sync mode without Qdrant: Use direct API
|
|
|
|
|
+ if (isApiOnlyMode(policy) || !isSyncAllowed(policy)) {
|
|
|
|
|
+ console.log('[MCP ShopRenter] Using direct API access');
|
|
|
|
|
|
|
|
// Search for order by innerId (customer-visible order number)
|
|
// Search for order by innerId (customer-visible order number)
|
|
|
- // The order_id parameter is actually the innerId from the customer's perspective
|
|
|
|
|
console.log('[MCP ShopRenter] Fetching order with innerId:', order_id);
|
|
console.log('[MCP ShopRenter] Fetching order with innerId:', order_id);
|
|
|
const response = await fetchOrders(shop_id, 0, 1, { innerId: order_id });
|
|
const response = await fetchOrders(shop_id, 0, 1, { innerId: order_id });
|
|
|
|
|
|
|
@@ -669,6 +624,105 @@ async function handleGetOrder(args: Record<string, any>): Promise<ToolCallResult
|
|
|
}]
|
|
}]
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // Handle sync mode: Use Qdrant if enabled
|
|
|
|
|
+ if (isSyncAllowed(policy)) {
|
|
|
|
|
+ const qdrantConfig = await getStoreQdrantConfig(shop_id);
|
|
|
|
|
+
|
|
|
|
|
+ if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncOrders) {
|
|
|
|
|
+ console.log('[MCP ShopRenter] Using Qdrant for order lookup');
|
|
|
|
|
+
|
|
|
|
|
+ // Query from Qdrant - scroll through orders to find matching order_id
|
|
|
|
|
+ const orders = await queryQdrantOrders(
|
|
|
|
|
+ shop_id,
|
|
|
|
|
+ qdrantConfig.shopname,
|
|
|
|
|
+ {},
|
|
|
|
|
+ 100 // Get more to search through
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // Find order by innerId (order number)
|
|
|
|
|
+ const order = orders.find((o: any) =>
|
|
|
|
|
+ o.orderNumber === order_id || o.id === order_id
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if (!order) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({
|
|
|
|
|
+ error: `No order found with order number: ${order_id}`
|
|
|
|
|
+ })
|
|
|
|
|
+ }],
|
|
|
|
|
+ isError: true
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Clean response data
|
|
|
|
|
+ const cleanedOrder = cleanResponseData(order);
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({
|
|
|
|
|
+ source: 'qdrant',
|
|
|
|
|
+ access_mode: 'sync',
|
|
|
|
|
+ order: cleanedOrder
|
|
|
|
|
+ })
|
|
|
|
|
+ }]
|
|
|
|
|
+ };
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log('[MCP ShopRenter] Qdrant not enabled, using ShopRenter API');
|
|
|
|
|
+
|
|
|
|
|
+ // Search for order by innerId (customer-visible order number)
|
|
|
|
|
+ console.log('[MCP ShopRenter] Fetching order with innerId:', order_id);
|
|
|
|
|
+ const response = await fetchOrders(shop_id, 0, 1, { innerId: order_id });
|
|
|
|
|
+
|
|
|
|
|
+ const orders = Array.isArray(response) ? response : (response.items || response.data || response.orders || []);
|
|
|
|
|
+
|
|
|
|
|
+ console.log('[MCP ShopRenter] API response:', { ordersCount: orders.length });
|
|
|
|
|
+
|
|
|
|
|
+ if (orders.length === 0) {
|
|
|
|
|
+ console.warn('[MCP ShopRenter] No order found with innerId:', order_id);
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({
|
|
|
|
|
+ error: `No order found with order number: ${order_id}`
|
|
|
|
|
+ })
|
|
|
|
|
+ }],
|
|
|
|
|
+ isError: true
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ console.log('[MCP ShopRenter] Order found:', { innerId: orders[0].innerId || orders[0].id });
|
|
|
|
|
+
|
|
|
|
|
+ // Format for LLM
|
|
|
|
|
+ const formattedOrder = formatOrderForLlm(orders[0]);
|
|
|
|
|
+
|
|
|
|
|
+ // Clean response data
|
|
|
|
|
+ const cleanedOrder = cleanResponseData(formattedOrder);
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({
|
|
|
|
|
+ source: 'api',
|
|
|
|
|
+ access_mode: 'sync',
|
|
|
|
|
+ order: cleanedOrder
|
|
|
|
|
+ })
|
|
|
|
|
+ }]
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Fallback (should not reach here)
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({ error: 'Invalid access policy configuration' })
|
|
|
|
|
+ }],
|
|
|
|
|
+ isError: true
|
|
|
|
|
+ };
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('[MCP ShopRenter] Error fetching order:', error);
|
|
console.error('[MCP ShopRenter] Error fetching order:', error);
|
|
|
return {
|
|
return {
|
|
@@ -727,83 +781,9 @@ async function handleListOrders(args: Record<string, any>): Promise<ToolCallResu
|
|
|
const policy = getDataTypePolicy(accessConfig!, 'orders');
|
|
const policy = getDataTypePolicy(accessConfig!, 'orders');
|
|
|
|
|
|
|
|
try {
|
|
try {
|
|
|
- // Check if Qdrant is enabled for this store
|
|
|
|
|
- const qdrantConfig = await getStoreQdrantConfig(shop_id);
|
|
|
|
|
-
|
|
|
|
|
- if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncOrders) {
|
|
|
|
|
- console.log('[MCP ShopRenter] Using Qdrant for orders');
|
|
|
|
|
-
|
|
|
|
|
- // Query from Qdrant with filters
|
|
|
|
|
- const qdrantOrders = await queryQdrantOrders(
|
|
|
|
|
- shop_id,
|
|
|
|
|
- qdrantConfig.shopname,
|
|
|
|
|
- { email, status },
|
|
|
|
|
- actualLimit
|
|
|
|
|
- );
|
|
|
|
|
-
|
|
|
|
|
- // Apply date filters client-side if provided
|
|
|
|
|
- let filteredOrders = qdrantOrders;
|
|
|
|
|
-
|
|
|
|
|
- if (createdAtMin) {
|
|
|
|
|
- const minDate = new Date(createdAtMin);
|
|
|
|
|
- filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
- const created = new Date(o.dateCreated || o.createdAt || 0);
|
|
|
|
|
- return created >= minDate;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (createdAtMax) {
|
|
|
|
|
- const maxDate = new Date(createdAtMax);
|
|
|
|
|
- filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
- const created = new Date(o.dateCreated || o.createdAt || 0);
|
|
|
|
|
- return created <= maxDate;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (updatedAtMin) {
|
|
|
|
|
- const minDate = new Date(updatedAtMin);
|
|
|
|
|
- filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
- const updated = new Date(o.dateUpdated || o.updatedAt || 0);
|
|
|
|
|
- return updated >= minDate;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (updatedAtMax) {
|
|
|
|
|
- const maxDate = new Date(updatedAtMax);
|
|
|
|
|
- filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
- const updated = new Date(o.dateUpdated || o.updatedAt || 0);
|
|
|
|
|
- return updated <= maxDate;
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // Limit after filtering
|
|
|
|
|
- filteredOrders = filteredOrders.slice(0, actualLimit);
|
|
|
|
|
-
|
|
|
|
|
- // Clean response data
|
|
|
|
|
- const cleanedOrders = cleanResponseData(filteredOrders);
|
|
|
|
|
-
|
|
|
|
|
- return {
|
|
|
|
|
- content: [{
|
|
|
|
|
- type: 'text',
|
|
|
|
|
- text: JSON.stringify({
|
|
|
|
|
- count: filteredOrders.length,
|
|
|
|
|
- limit: actualLimit,
|
|
|
|
|
- source: 'qdrant',
|
|
|
|
|
- access_mode: 'sync',
|
|
|
|
|
- filters_applied: {
|
|
|
|
|
- createdAtMin,
|
|
|
|
|
- createdAtMax,
|
|
|
|
|
- updatedAtMin,
|
|
|
|
|
- updatedAtMax,
|
|
|
|
|
- email,
|
|
|
|
|
- status
|
|
|
|
|
- },
|
|
|
|
|
- orders: cleanedOrders
|
|
|
|
|
- })
|
|
|
|
|
- }]
|
|
|
|
|
- };
|
|
|
|
|
- } else {
|
|
|
|
|
- console.log('[MCP ShopRenter] Qdrant not enabled, using ShopRenter API');
|
|
|
|
|
|
|
+ // Handle api_only mode: Direct API call
|
|
|
|
|
+ if (isApiOnlyMode(policy)) {
|
|
|
|
|
+ console.log('[MCP ShopRenter] Using direct API access (api_only mode)');
|
|
|
|
|
|
|
|
// Build filters using correct parameter names
|
|
// Build filters using correct parameter names
|
|
|
const filters: ShopRenterOrderFilters = {};
|
|
const filters: ShopRenterOrderFilters = {};
|
|
@@ -835,9 +815,9 @@ async function handleListOrders(args: Record<string, any>): Promise<ToolCallResu
|
|
|
text: JSON.stringify({
|
|
text: JSON.stringify({
|
|
|
count: formattedOrders.length,
|
|
count: formattedOrders.length,
|
|
|
limit: actualLimit,
|
|
limit: actualLimit,
|
|
|
- source: isApiOnlyMode(policy) ? 'api_direct' : 'api',
|
|
|
|
|
- access_mode: policy,
|
|
|
|
|
- notice: isApiOnlyMode(policy) ? createApiOnlyNotice('orders') : undefined,
|
|
|
|
|
|
|
+ source: 'api_direct',
|
|
|
|
|
+ access_mode: 'api_only',
|
|
|
|
|
+ notice: createApiOnlyNotice('orders'),
|
|
|
filters_applied: {
|
|
filters_applied: {
|
|
|
createdAtMin,
|
|
createdAtMin,
|
|
|
createdAtMax,
|
|
createdAtMax,
|
|
@@ -851,6 +831,142 @@ async function handleListOrders(args: Record<string, any>): Promise<ToolCallResu
|
|
|
}]
|
|
}]
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // Handle sync mode: Use Qdrant or SQL cache
|
|
|
|
|
+ if (isSyncAllowed(policy)) {
|
|
|
|
|
+ // Check if Qdrant is enabled for this store
|
|
|
|
|
+ const qdrantConfig = await getStoreQdrantConfig(shop_id);
|
|
|
|
|
+
|
|
|
|
|
+ if (qdrantConfig && qdrantConfig.enabled && qdrantConfig.syncOrders) {
|
|
|
|
|
+ console.log('[MCP ShopRenter] Using Qdrant for orders');
|
|
|
|
|
+
|
|
|
|
|
+ // Query from Qdrant with filters
|
|
|
|
|
+ const qdrantOrders = await queryQdrantOrders(
|
|
|
|
|
+ shop_id,
|
|
|
|
|
+ qdrantConfig.shopname,
|
|
|
|
|
+ { email, status },
|
|
|
|
|
+ actualLimit
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ // Apply date filters client-side if provided
|
|
|
|
|
+ let filteredOrders = qdrantOrders;
|
|
|
|
|
+
|
|
|
|
|
+ if (createdAtMin) {
|
|
|
|
|
+ const minDate = new Date(createdAtMin);
|
|
|
|
|
+ filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
+ const created = new Date(o.dateCreated || o.createdAt || 0);
|
|
|
|
|
+ return created >= minDate;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (createdAtMax) {
|
|
|
|
|
+ const maxDate = new Date(createdAtMax);
|
|
|
|
|
+ filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
+ const created = new Date(o.dateCreated || o.createdAt || 0);
|
|
|
|
|
+ return created <= maxDate;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (updatedAtMin) {
|
|
|
|
|
+ const minDate = new Date(updatedAtMin);
|
|
|
|
|
+ filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
+ const updated = new Date(o.dateUpdated || o.updatedAt || 0);
|
|
|
|
|
+ return updated >= minDate;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (updatedAtMax) {
|
|
|
|
|
+ const maxDate = new Date(updatedAtMax);
|
|
|
|
|
+ filteredOrders = filteredOrders.filter((o: any) => {
|
|
|
|
|
+ const updated = new Date(o.dateUpdated || o.updatedAt || 0);
|
|
|
|
|
+ return updated <= maxDate;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Limit after filtering
|
|
|
|
|
+ filteredOrders = filteredOrders.slice(0, actualLimit);
|
|
|
|
|
+
|
|
|
|
|
+ // Clean response data
|
|
|
|
|
+ const cleanedOrders = cleanResponseData(filteredOrders);
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({
|
|
|
|
|
+ count: filteredOrders.length,
|
|
|
|
|
+ limit: actualLimit,
|
|
|
|
|
+ source: 'qdrant',
|
|
|
|
|
+ access_mode: 'sync',
|
|
|
|
|
+ filters_applied: {
|
|
|
|
|
+ createdAtMin,
|
|
|
|
|
+ createdAtMax,
|
|
|
|
|
+ updatedAtMin,
|
|
|
|
|
+ updatedAtMax,
|
|
|
|
|
+ email,
|
|
|
|
|
+ status
|
|
|
|
|
+ },
|
|
|
|
|
+ orders: cleanedOrders
|
|
|
|
|
+ })
|
|
|
|
|
+ }]
|
|
|
|
|
+ };
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log('[MCP ShopRenter] Qdrant not enabled, using ShopRenter API');
|
|
|
|
|
+
|
|
|
|
|
+ // Build filters using correct parameter names
|
|
|
|
|
+ const filters: ShopRenterOrderFilters = {};
|
|
|
|
|
+ if (status) filters.status = status;
|
|
|
|
|
+ if (email) filters.email = email;
|
|
|
|
|
+ if (createdAtMin) filters.createdAtMin = createdAtMin;
|
|
|
|
|
+ if (createdAtMax) filters.createdAtMax = createdAtMax;
|
|
|
|
|
+ if (updatedAtMin) filters.updatedAtMin = updatedAtMin;
|
|
|
|
|
+ if (updatedAtMax) filters.updatedAtMax = updatedAtMax;
|
|
|
|
|
+
|
|
|
|
|
+ // Fetch orders from ShopRenter API
|
|
|
|
|
+ const response = await fetchOrders(shop_id, 0, actualLimit, filters);
|
|
|
|
|
+ const orders = Array.isArray(response) ? response : (response.items || response.data || response.orders || []);
|
|
|
|
|
+
|
|
|
|
|
+ console.log('[MCP ShopRenter] API response:', { ordersCount: orders.length });
|
|
|
|
|
+
|
|
|
|
|
+ // Apply limit
|
|
|
|
|
+ const limitedOrders = orders.slice(0, actualLimit);
|
|
|
|
|
+
|
|
|
|
|
+ // Format for LLM (now preserves all ShopRenter fields)
|
|
|
|
|
+ const formattedOrders = limitedOrders.map(formatOrderForLlm);
|
|
|
|
|
+
|
|
|
|
|
+ // Clean response data (removes URLs, empty values)
|
|
|
|
|
+ const cleanedOrders = cleanResponseData(formattedOrders);
|
|
|
|
|
+
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({
|
|
|
|
|
+ count: formattedOrders.length,
|
|
|
|
|
+ limit: actualLimit,
|
|
|
|
|
+ source: 'api',
|
|
|
|
|
+ access_mode: 'sync',
|
|
|
|
|
+ filters_applied: {
|
|
|
|
|
+ createdAtMin,
|
|
|
|
|
+ createdAtMax,
|
|
|
|
|
+ updatedAtMin,
|
|
|
|
|
+ updatedAtMax,
|
|
|
|
|
+ email,
|
|
|
|
|
+ status
|
|
|
|
|
+ },
|
|
|
|
|
+ orders: cleanedOrders
|
|
|
|
|
+ })
|
|
|
|
|
+ }]
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Fallback (should not reach here)
|
|
|
|
|
+ return {
|
|
|
|
|
+ content: [{
|
|
|
|
|
+ type: 'text',
|
|
|
|
|
+ text: JSON.stringify({ error: 'Invalid access policy configuration' })
|
|
|
|
|
+ }],
|
|
|
|
|
+ isError: true
|
|
|
|
|
+ };
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('[MCP ShopRenter] Error fetching orders:', error);
|
|
console.error('[MCP ShopRenter] Error fetching orders:', error);
|
|
|
return {
|
|
return {
|