@unchainedshop/api 4.0.0-rc.10 → 4.0.0-rc.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/mcp/index.d.ts.map +1 -1
- package/lib/mcp/index.js +6 -0
- package/lib/mcp/index.js.map +1 -1
- package/lib/mcp/tools/delivery/createDeliveryProviderHandler.d.ts +44 -0
- package/lib/mcp/tools/delivery/createDeliveryProviderHandler.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/createDeliveryProviderHandler.js +50 -0
- package/lib/mcp/tools/delivery/createDeliveryProviderHandler.js.map +1 -0
- package/lib/mcp/tools/delivery/deliveryInterfacesHandler.d.ts +20 -0
- package/lib/mcp/tools/delivery/deliveryInterfacesHandler.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/deliveryInterfacesHandler.js +45 -0
- package/lib/mcp/tools/delivery/deliveryInterfacesHandler.js.map +1 -0
- package/lib/mcp/tools/delivery/deliveryProvider.d.ts +20 -0
- package/lib/mcp/tools/delivery/deliveryProvider.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/deliveryProvider.js +43 -0
- package/lib/mcp/tools/delivery/deliveryProvider.js.map +1 -0
- package/lib/mcp/tools/delivery/deliveryProvidersCountHandler.d.ts +20 -0
- package/lib/mcp/tools/delivery/deliveryProvidersCountHandler.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/deliveryProvidersCountHandler.js +36 -0
- package/lib/mcp/tools/delivery/deliveryProvidersCountHandler.js.map +1 -0
- package/lib/mcp/tools/delivery/deliveryProvidersListHandler.d.ts +24 -0
- package/lib/mcp/tools/delivery/deliveryProvidersListHandler.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/deliveryProvidersListHandler.js +44 -0
- package/lib/mcp/tools/delivery/deliveryProvidersListHandler.js.map +1 -0
- package/lib/mcp/tools/delivery/index.d.ts +4 -0
- package/lib/mcp/tools/delivery/index.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/index.js +17 -0
- package/lib/mcp/tools/delivery/index.js.map +1 -0
- package/lib/mcp/tools/delivery/removeDeliveryProviderHandler.d.ts +20 -0
- package/lib/mcp/tools/delivery/removeDeliveryProviderHandler.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/removeDeliveryProviderHandler.js +37 -0
- package/lib/mcp/tools/delivery/removeDeliveryProviderHandler.js.map +1 -0
- package/lib/mcp/tools/delivery/updateDeliveryProviderHandler.d.ts +96 -0
- package/lib/mcp/tools/delivery/updateDeliveryProviderHandler.d.ts.map +1 -0
- package/lib/mcp/tools/delivery/updateDeliveryProviderHandler.js +54 -0
- package/lib/mcp/tools/delivery/updateDeliveryProviderHandler.js.map +1 -0
- package/lib/mcp/tools/order/getMonthlySalesBreakdownHandler.d.ts +36 -0
- package/lib/mcp/tools/order/getMonthlySalesBreakdownHandler.d.ts.map +1 -0
- package/lib/mcp/tools/order/getMonthlySalesBreakdownHandler.js +89 -0
- package/lib/mcp/tools/order/getMonthlySalesBreakdownHandler.js.map +1 -0
- package/lib/mcp/tools/order/getSalesSummaryHandler.d.ts +40 -0
- package/lib/mcp/tools/order/getSalesSummaryHandler.d.ts.map +1 -0
- package/lib/mcp/tools/order/getSalesSummaryHandler.js +90 -0
- package/lib/mcp/tools/order/getSalesSummaryHandler.js.map +1 -0
- package/lib/mcp/tools/order/getTopCustomersHandler.d.ts +52 -0
- package/lib/mcp/tools/order/getTopCustomersHandler.d.ts.map +1 -0
- package/lib/mcp/tools/order/getTopCustomersHandler.js +114 -0
- package/lib/mcp/tools/order/getTopCustomersHandler.js.map +1 -0
- package/lib/mcp/tools/order/getTopSellingProductsHandler.d.ts +28 -0
- package/lib/mcp/tools/order/getTopSellingProductsHandler.d.ts.map +1 -0
- package/lib/mcp/tools/order/getTopSellingProductsHandler.js +99 -0
- package/lib/mcp/tools/order/getTopSellingProductsHandler.js.map +1 -0
- package/lib/mcp/tools/order/index.d.ts +4 -0
- package/lib/mcp/tools/order/index.d.ts.map +1 -0
- package/lib/mcp/tools/order/index.js +13 -0
- package/lib/mcp/tools/order/index.js.map +1 -0
- package/lib/mcp/tools/order/ordersListHandler.d.ts +108 -0
- package/lib/mcp/tools/order/ordersListHandler.d.ts.map +1 -0
- package/lib/mcp/tools/order/ordersListHandler.js +91 -0
- package/lib/mcp/tools/order/ordersListHandler.js.map +1 -0
- package/lib/mcp/tools/payment/createPaymentProviderHandler.d.ts.map +1 -1
- package/lib/mcp/tools/payment/createPaymentProviderHandler.js +5 -2
- package/lib/mcp/tools/payment/createPaymentProviderHandler.js.map +1 -1
- package/lib/mcp/tools/payment/index.js +1 -1
- package/lib/mcp/tools/payment/index.js.map +1 -1
- package/lib/mcp/tools/payment/paymentInterfacesHandler.d.ts +2 -2
- package/lib/mcp/tools/payment/paymentInterfacesHandler.d.ts.map +1 -1
- package/lib/mcp/tools/payment/paymentInterfacesHandler.js +7 -5
- package/lib/mcp/tools/payment/paymentInterfacesHandler.js.map +1 -1
- package/lib/mcp/tools/payment/paymentProviderByIdHandler.js +1 -1
- package/lib/mcp/tools/payment/paymentProviderByIdHandler.js.map +1 -1
- package/lib/mcp/tools/payment/paymentProvidersListHandler.d.ts +4 -0
- package/lib/mcp/tools/payment/paymentProvidersListHandler.d.ts.map +1 -1
- package/lib/mcp/tools/payment/paymentProvidersListHandler.js +12 -3
- package/lib/mcp/tools/payment/paymentProvidersListHandler.js.map +1 -1
- package/lib/mcp/tools/payment/removePaymentProviderHandler.d.ts.map +1 -1
- package/lib/mcp/tools/payment/removePaymentProviderHandler.js +5 -4
- package/lib/mcp/tools/payment/removePaymentProviderHandler.js.map +1 -1
- package/lib/mcp/tools/payment/updatePaymentProviderHandler.d.ts +66 -10
- package/lib/mcp/tools/payment/updatePaymentProviderHandler.d.ts.map +1 -1
- package/lib/mcp/tools/payment/updatePaymentProviderHandler.js +18 -3
- package/lib/mcp/tools/payment/updatePaymentProviderHandler.js.map +1 -1
- package/lib/mcp/tools/warehousing/createWarehousingProviderHandler.d.ts +44 -0
- package/lib/mcp/tools/warehousing/createWarehousingProviderHandler.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/createWarehousingProviderHandler.js +48 -0
- package/lib/mcp/tools/warehousing/createWarehousingProviderHandler.js.map +1 -0
- package/lib/mcp/tools/warehousing/index.d.ts +4 -0
- package/lib/mcp/tools/warehousing/index.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/index.js +17 -0
- package/lib/mcp/tools/warehousing/index.js.map +1 -0
- package/lib/mcp/tools/warehousing/removeWarehousingProviderHandler.d.ts +20 -0
- package/lib/mcp/tools/warehousing/removeWarehousingProviderHandler.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/removeWarehousingProviderHandler.js +39 -0
- package/lib/mcp/tools/warehousing/removeWarehousingProviderHandler.js.map +1 -0
- package/lib/mcp/tools/warehousing/updateWarehousingProviderHandler.d.ts +96 -0
- package/lib/mcp/tools/warehousing/updateWarehousingProviderHandler.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/updateWarehousingProviderHandler.js +58 -0
- package/lib/mcp/tools/warehousing/updateWarehousingProviderHandler.js.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingInterfacesHandler.d.ts +20 -0
- package/lib/mcp/tools/warehousing/warehousingInterfacesHandler.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingInterfacesHandler.js +45 -0
- package/lib/mcp/tools/warehousing/warehousingInterfacesHandler.js.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingProviderHandler.d.ts +20 -0
- package/lib/mcp/tools/warehousing/warehousingProviderHandler.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingProviderHandler.js +45 -0
- package/lib/mcp/tools/warehousing/warehousingProviderHandler.js.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersCountHandler.d.ts +20 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersCountHandler.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersCountHandler.js +36 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersCountHandler.js.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersListHandler.d.ts +24 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersListHandler.d.ts.map +1 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersListHandler.js +44 -0
- package/lib/mcp/tools/warehousing/warehousingProvidersListHandler.js.map +1 -0
- package/lib/mcp/utils/orderFilters.d.ts +22 -0
- package/lib/mcp/utils/orderFilters.d.ts.map +1 -0
- package/lib/mcp/utils/orderFilters.js +34 -0
- package/lib/mcp/utils/orderFilters.js.map +1 -0
- package/lib/mcp/utils/sharedSchemas.d.ts +11 -0
- package/lib/mcp/utils/sharedSchemas.d.ts.map +1 -0
- package/lib/mcp/utils/sharedSchemas.js +11 -0
- package/lib/mcp/utils/sharedSchemas.js.map +1 -0
- package/lib/resolvers/queries/delivery/deliveryInterfaces.d.ts +2 -2
- package/lib/resolvers/queries/delivery/deliveryInterfaces.d.ts.map +1 -1
- package/lib/resolvers/queries/delivery/deliveryInterfaces.js +6 -4
- package/lib/resolvers/queries/delivery/deliveryInterfaces.js.map +1 -1
- package/lib/resolvers/queries/orders/orders.d.ts.map +1 -1
- package/lib/resolvers/queries/orders/orders.js +21 -4
- package/lib/resolvers/queries/orders/orders.js.map +1 -1
- package/lib/resolvers/queries/orders/ordersCount.d.ts.map +1 -1
- package/lib/resolvers/queries/orders/ordersCount.js +17 -1
- package/lib/resolvers/queries/orders/ordersCount.js.map +1 -1
- package/lib/resolvers/queries/payment/paymentInterfaces.d.ts.map +1 -1
- package/lib/resolvers/queries/payment/paymentInterfaces.js +5 -3
- package/lib/resolvers/queries/payment/paymentInterfaces.js.map +1 -1
- package/lib/resolvers/queries/warehousing/warehousingInterfaces.d.ts.map +1 -1
- package/lib/resolvers/queries/warehousing/warehousingInterfaces.js +5 -3
- package/lib/resolvers/queries/warehousing/warehousingInterfaces.js.map +1 -1
- package/lib/schema/query.d.ts.map +1 -1
- package/lib/schema/query.js +14 -4
- package/lib/schema/query.js.map +1 -1
- package/package.json +1 -1
- package/src/mcp/index.ts +6 -1
- package/src/mcp/tools/delivery/createDeliveryProviderHandler.ts +62 -0
- package/src/mcp/tools/delivery/deliveryInterfacesHandler.ts +56 -0
- package/src/mcp/tools/delivery/deliveryProvider.ts +51 -0
- package/src/mcp/tools/delivery/deliveryProvidersCountHandler.ts +46 -0
- package/src/mcp/tools/delivery/deliveryProvidersListHandler.ts +54 -0
- package/src/mcp/tools/delivery/index.ts +74 -0
- package/src/mcp/tools/delivery/removeDeliveryProviderHandler.ts +45 -0
- package/src/mcp/tools/delivery/updateDeliveryProviderHandler.ts +68 -0
- package/src/mcp/tools/order/getMonthlySalesBreakdownHandler.ts +106 -0
- package/src/mcp/tools/order/getSalesSummaryHandler.ts +103 -0
- package/src/mcp/tools/order/getTopCustomersHandler.ts +124 -0
- package/src/mcp/tools/order/getTopSellingProductsHandler.ts +112 -0
- package/src/mcp/tools/order/index.ts +50 -0
- package/src/mcp/tools/order/ordersListHandler.ts +119 -0
- package/src/mcp/tools/payment/createPaymentProviderHandler.ts +7 -2
- package/src/mcp/tools/payment/index.ts +1 -1
- package/src/mcp/tools/payment/paymentInterfacesHandler.ts +13 -10
- package/src/mcp/tools/payment/paymentProviderByIdHandler.ts +1 -1
- package/src/mcp/tools/payment/paymentProvidersListHandler.ts +14 -4
- package/src/mcp/tools/payment/removePaymentProviderHandler.ts +6 -8
- package/src/mcp/tools/payment/updatePaymentProviderHandler.ts +23 -4
- package/src/mcp/tools/warehousing/createWarehousingProviderHandler.ts +61 -0
- package/src/mcp/tools/warehousing/index.ts +81 -0
- package/src/mcp/tools/warehousing/removeWarehousingProviderHandler.ts +46 -0
- package/src/mcp/tools/warehousing/updateWarehousingProviderHandler.ts +72 -0
- package/src/mcp/tools/warehousing/warehousingInterfacesHandler.ts +58 -0
- package/src/mcp/tools/warehousing/warehousingProviderHandler.ts +55 -0
- package/src/mcp/tools/warehousing/warehousingProvidersCountHandler.ts +46 -0
- package/src/mcp/tools/warehousing/warehousingProvidersListHandler.ts +55 -0
- package/src/mcp/utils/orderFilters.ts +52 -0
- package/src/mcp/utils/sharedSchemas.ts +12 -0
- package/src/resolvers/queries/delivery/deliveryInterfaces.ts +8 -4
- package/src/resolvers/queries/orders/orders.ts +25 -5
- package/src/resolvers/queries/orders/ordersCount.ts +21 -1
- package/src/resolvers/queries/payment/paymentInterfaces.ts +11 -7
- package/src/resolvers/queries/warehousing/warehousingInterfaces.ts +5 -3
- package/src/schema/query.ts +14 -4
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
|
|
5
|
+
const DeliveryProviderTypeEnum = z
|
|
6
|
+
.enum(['PICKUP', 'SHIPPING', 'LOCAL'])
|
|
7
|
+
.describe('Delivery provider type');
|
|
8
|
+
|
|
9
|
+
export const DeliveryProvidersCountSchema = {
|
|
10
|
+
type: DeliveryProviderTypeEnum.optional(),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const DeliveryProvidersCountZodSchema = z.object(DeliveryProvidersCountSchema);
|
|
14
|
+
export type DeliveryProvidersCountParams = z.infer<typeof DeliveryProvidersCountZodSchema>;
|
|
15
|
+
|
|
16
|
+
export async function deliveryProvidersCountHandler(
|
|
17
|
+
context: Context,
|
|
18
|
+
params: DeliveryProvidersCountParams,
|
|
19
|
+
) {
|
|
20
|
+
const { modules, userId } = context;
|
|
21
|
+
const { type } = params;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
log('handler deliveryProvidersCountHandler', { userId, type });
|
|
25
|
+
|
|
26
|
+
const count = await modules.delivery.count(params as any);
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
content: [
|
|
30
|
+
{
|
|
31
|
+
type: 'text' as const,
|
|
32
|
+
text: JSON.stringify({ count }),
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: 'text' as const,
|
|
41
|
+
text: `Error counting delivery providers: ${(error as Error).message}`,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
|
|
5
|
+
const DeliveryProviderTypeEnum = z
|
|
6
|
+
.enum(['PICKUP', 'SHIPPING', 'LOCAL'])
|
|
7
|
+
.describe('Delivery provider type');
|
|
8
|
+
|
|
9
|
+
export const DeliveryProvidersListSchema = {
|
|
10
|
+
type: DeliveryProviderTypeEnum.optional().describe('Optional filter by delivery provider type'),
|
|
11
|
+
queryString: z.string().min(1).optional().describe('Search by _id or adapterKey (partial match)'),
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const DeliveryProvidersListZodSchema = z.object(DeliveryProvidersListSchema);
|
|
15
|
+
export type DeliveryProvidersListParams = z.infer<typeof DeliveryProvidersListZodSchema>;
|
|
16
|
+
export async function deliveryProvidersListHandler(
|
|
17
|
+
context: Context,
|
|
18
|
+
params: DeliveryProvidersListParams,
|
|
19
|
+
) {
|
|
20
|
+
const { modules, userId } = context;
|
|
21
|
+
const { type, queryString } = params;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
log('handler deliveryProvidersListHandler', { userId, type, queryString });
|
|
25
|
+
|
|
26
|
+
const selector: Record<string, any> = {};
|
|
27
|
+
if (type) selector.type = type;
|
|
28
|
+
|
|
29
|
+
if (queryString) {
|
|
30
|
+
const regex = new RegExp(queryString, 'i');
|
|
31
|
+
selector.$or = [{ _id: regex }, { adapterKey: regex }];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const providers = await modules.delivery.findProviders(selector);
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
content: [
|
|
38
|
+
{
|
|
39
|
+
type: 'text' as const,
|
|
40
|
+
text: JSON.stringify({ providers }),
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return {
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: 'text' as const,
|
|
49
|
+
text: `Error fetching delivery providers: ${(error as Error).message}`,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import {
|
|
4
|
+
deliveryProvidersListHandler,
|
|
5
|
+
DeliveryProvidersListSchema,
|
|
6
|
+
} from './deliveryProvidersListHandler.js';
|
|
7
|
+
import {
|
|
8
|
+
deliveryProvidersCountHandler,
|
|
9
|
+
DeliveryProvidersCountSchema,
|
|
10
|
+
} from './deliveryProvidersCountHandler.js';
|
|
11
|
+
import { DeliveryProviderByIdSchema, deliveryProviderHandler } from './deliveryProvider.js';
|
|
12
|
+
import { deliveryInterfacesHandler, DeliveryInterfacesSchema } from './deliveryInterfacesHandler.js';
|
|
13
|
+
import {
|
|
14
|
+
createDeliveryProviderHandler,
|
|
15
|
+
CreateDeliveryProviderSchema,
|
|
16
|
+
} from './createDeliveryProviderHandler.js';
|
|
17
|
+
import {
|
|
18
|
+
updateDeliveryProviderHandler,
|
|
19
|
+
UpdateDeliveryProviderSchema,
|
|
20
|
+
} from './updateDeliveryProviderHandler.js';
|
|
21
|
+
import {
|
|
22
|
+
removeDeliveryProviderHandler,
|
|
23
|
+
RemoveDeliveryProviderSchema,
|
|
24
|
+
} from './removeDeliveryProviderHandler.js';
|
|
25
|
+
|
|
26
|
+
export const registerDeliveryProviderTools = (server: McpServer, context: Context) => {
|
|
27
|
+
server.tool(
|
|
28
|
+
'deliveryProviders_list',
|
|
29
|
+
'Get all delivery providers, optionally filtered by type.',
|
|
30
|
+
DeliveryProvidersListSchema,
|
|
31
|
+
async (params) => deliveryProvidersListHandler(context, params),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
server.tool(
|
|
35
|
+
'deliveryProviders_count',
|
|
36
|
+
'Returns total number of delivery providers, optionally filtered by type.',
|
|
37
|
+
DeliveryProvidersCountSchema,
|
|
38
|
+
async (params) => deliveryProvidersCountHandler(context, params),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
server.tool(
|
|
42
|
+
'deliveryProvider_get',
|
|
43
|
+
'Get a specific delivery provider by ID.',
|
|
44
|
+
DeliveryProviderByIdSchema,
|
|
45
|
+
async (params) => deliveryProviderHandler(context, params),
|
|
46
|
+
);
|
|
47
|
+
server.tool(
|
|
48
|
+
'deliveryInterfaces_list',
|
|
49
|
+
'Get all delivery interfaces filtered by type.',
|
|
50
|
+
DeliveryInterfacesSchema,
|
|
51
|
+
async (params) => deliveryInterfacesHandler(context, params),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
server.tool(
|
|
55
|
+
'deliveryProvider_add',
|
|
56
|
+
'Adds new delivery provider.',
|
|
57
|
+
CreateDeliveryProviderSchema,
|
|
58
|
+
async (params) => createDeliveryProviderHandler(context, params),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
server.tool(
|
|
62
|
+
'deliveryProvider_update',
|
|
63
|
+
'Updates the delivery provider specified.',
|
|
64
|
+
UpdateDeliveryProviderSchema,
|
|
65
|
+
async (params) => updateDeliveryProviderHandler(context, params),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
server.tool(
|
|
69
|
+
'deliveryProvider_remove',
|
|
70
|
+
'Soft deletes a delivery provider by setting its deleted timestamp.',
|
|
71
|
+
RemoveDeliveryProviderSchema,
|
|
72
|
+
async (params) => removeDeliveryProviderHandler(context, params),
|
|
73
|
+
);
|
|
74
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import { DeliverProviderNotFoundError } from '../../../errors.js';
|
|
5
|
+
|
|
6
|
+
export const RemoveDeliveryProviderSchema = {
|
|
7
|
+
deliveryProviderId: z.string().min(1).describe('ID of the delivery provider to soft delete'),
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const RemoveDeliveryProviderZodSchema = z.object(RemoveDeliveryProviderSchema);
|
|
11
|
+
export type RemoveDeliveryProviderParams = z.infer<typeof RemoveDeliveryProviderZodSchema>;
|
|
12
|
+
|
|
13
|
+
export async function removeDeliveryProviderHandler(
|
|
14
|
+
context: Context,
|
|
15
|
+
params: RemoveDeliveryProviderParams,
|
|
16
|
+
) {
|
|
17
|
+
const { modules, userId } = context;
|
|
18
|
+
const { deliveryProviderId } = params;
|
|
19
|
+
try {
|
|
20
|
+
log('handler removeDeliveryProviderHandler', { userId, deliveryProviderId });
|
|
21
|
+
|
|
22
|
+
const provider = await modules.delivery.findProvider({ deliveryProviderId });
|
|
23
|
+
if (!provider) throw new DeliverProviderNotFoundError({ deliveryProviderId });
|
|
24
|
+
|
|
25
|
+
const removed = await modules.delivery.delete(deliveryProviderId);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: 'text' as const,
|
|
31
|
+
text: JSON.stringify({ provider: removed }),
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return {
|
|
37
|
+
content: [
|
|
38
|
+
{
|
|
39
|
+
type: 'text' as const,
|
|
40
|
+
text: `Error removing delivery provider: ${(error as Error).message}`,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import { DeliverProviderNotFoundError } from '../../../errors.js';
|
|
5
|
+
|
|
6
|
+
const ConfigurationEntry = z.object({
|
|
7
|
+
key: z.string().min(1).describe('Configuration key'),
|
|
8
|
+
value: z.any().describe('Configuration value'),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export const UpdateDeliveryProviderSchema = {
|
|
12
|
+
deliveryProviderId: z.string().min(1).describe('ID of the delivery provider to update'),
|
|
13
|
+
deliveryProvider: z
|
|
14
|
+
.object({
|
|
15
|
+
configuration: z
|
|
16
|
+
.array(ConfigurationEntry)
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('List of key-value configuration entries'),
|
|
19
|
+
})
|
|
20
|
+
.refine(
|
|
21
|
+
(data) => {
|
|
22
|
+
const keys = data.configuration?.map((entry) => entry.key) || [];
|
|
23
|
+
return new Set(keys).size === keys.length;
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
message: 'Duplicate keys are not allowed in configuration.',
|
|
27
|
+
path: ['configuration'],
|
|
28
|
+
},
|
|
29
|
+
),
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const UpdateDeliveryProviderZodSchema = z.object(UpdateDeliveryProviderSchema);
|
|
33
|
+
export type UpdateDeliveryProviderParams = z.infer<typeof UpdateDeliveryProviderZodSchema>;
|
|
34
|
+
|
|
35
|
+
export async function updateDeliveryProviderHandler(
|
|
36
|
+
context: Context,
|
|
37
|
+
params: UpdateDeliveryProviderParams,
|
|
38
|
+
) {
|
|
39
|
+
const { modules, userId } = context;
|
|
40
|
+
const { deliveryProviderId, deliveryProvider } = params;
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
log('handler updateDeliveryProviderHandler', { userId, deliveryProviderId, deliveryProvider });
|
|
44
|
+
|
|
45
|
+
if (!(await modules.delivery.providerExists({ deliveryProviderId })))
|
|
46
|
+
throw new DeliverProviderNotFoundError({ deliveryProviderId });
|
|
47
|
+
|
|
48
|
+
const updated = await modules.delivery.update(deliveryProviderId, deliveryProvider as any);
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
content: [
|
|
52
|
+
{
|
|
53
|
+
type: 'text' as const,
|
|
54
|
+
text: JSON.stringify({ provider: updated }),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
} catch (error) {
|
|
59
|
+
return {
|
|
60
|
+
content: [
|
|
61
|
+
{
|
|
62
|
+
type: 'text' as const,
|
|
63
|
+
text: `Error updating delivery provider: ${(error as Error).message}`,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import { DateRangeSchema, OrderFilterSchema } from '../../utils/sharedSchemas.js';
|
|
5
|
+
import { formatSummaryMap, resolveDateRange, resolveOrderFilters } from '../../utils/orderFilters.js';
|
|
6
|
+
|
|
7
|
+
export const MonthlySalesBreakdownSchema = {
|
|
8
|
+
...DateRangeSchema,
|
|
9
|
+
...OrderFilterSchema,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const MonthlySalesBreakdownZodSchema = z.object(MonthlySalesBreakdownSchema);
|
|
13
|
+
export type MonthlySalesBreakdownParams = z.infer<typeof MonthlySalesBreakdownZodSchema>;
|
|
14
|
+
|
|
15
|
+
export async function getMonthlySalesBreakdownHandler(
|
|
16
|
+
context: Context,
|
|
17
|
+
params: MonthlySalesBreakdownParams,
|
|
18
|
+
) {
|
|
19
|
+
const { modules, userId } = context;
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
log('handler getMonthlySalesBreakdownHandler', { userId, params });
|
|
23
|
+
|
|
24
|
+
const { from, to, paymentProviderIds, deliveryProviderIds, status } = params;
|
|
25
|
+
|
|
26
|
+
const { startDate, endDate } = resolveDateRange(from, to);
|
|
27
|
+
const filters = await resolveOrderFilters(modules, { paymentProviderIds, deliveryProviderIds });
|
|
28
|
+
if (!filters) {
|
|
29
|
+
return {
|
|
30
|
+
content: [
|
|
31
|
+
{
|
|
32
|
+
type: 'text' as const,
|
|
33
|
+
text: JSON.stringify({
|
|
34
|
+
totalSalesAmount: 0,
|
|
35
|
+
orderCount: 0,
|
|
36
|
+
averageOrderValue: 0,
|
|
37
|
+
currencyCode: null,
|
|
38
|
+
summary: [],
|
|
39
|
+
dateRange: { start: startDate.toISOString(), end: endDate.toISOString() },
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const orders = await modules.orders.findOrders({
|
|
47
|
+
dateRange: { start: startDate.toISOString(), end: endDate.toISOString() },
|
|
48
|
+
status,
|
|
49
|
+
...filters,
|
|
50
|
+
} as any);
|
|
51
|
+
|
|
52
|
+
let totalSalesAmount = 0;
|
|
53
|
+
let orderCount = 0;
|
|
54
|
+
|
|
55
|
+
const monthlyMap = new Map<string, { sales: number; orders: number }>();
|
|
56
|
+
|
|
57
|
+
for (let i = 0; i < 12; i++) {
|
|
58
|
+
const date = new Date(endDate.getFullYear(), endDate.getMonth() - i, 1);
|
|
59
|
+
const label = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
|
|
60
|
+
monthlyMap.set(label, { sales: 0, orders: 0 });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
for (const order of orders) {
|
|
64
|
+
const orderDate = new Date(order.created);
|
|
65
|
+
if (orderDate < startDate || orderDate > endDate) continue;
|
|
66
|
+
|
|
67
|
+
orderCount++;
|
|
68
|
+
const itemsAmount = order.calculation?.find((c) => c.category === 'ITEMS')?.amount || 0;
|
|
69
|
+
totalSalesAmount += itemsAmount;
|
|
70
|
+
|
|
71
|
+
const label = `${orderDate.getFullYear()}-${String(orderDate.getMonth() + 1).padStart(2, '0')}`;
|
|
72
|
+
const entry = monthlyMap.get(label);
|
|
73
|
+
if (entry) {
|
|
74
|
+
entry.sales += itemsAmount;
|
|
75
|
+
entry.orders += 1;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const averageOrderValue = orderCount > 0 ? totalSalesAmount / orderCount : 0;
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: 'text' as const,
|
|
85
|
+
text: JSON.stringify({
|
|
86
|
+
totalSalesAmount,
|
|
87
|
+
orderCount,
|
|
88
|
+
averageOrderValue,
|
|
89
|
+
currencyCode: orders[0]?.currencyCode ?? null,
|
|
90
|
+
summary: formatSummaryMap(monthlyMap),
|
|
91
|
+
dateRange: { start: startDate.toISOString(), end: endDate.toISOString() },
|
|
92
|
+
}),
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return {
|
|
98
|
+
content: [
|
|
99
|
+
{
|
|
100
|
+
type: 'text' as const,
|
|
101
|
+
text: `Error fetching monthly sales breakdown: ${(error as Error).message}`,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import { DateRangeSchema, OrderFilterSchema } from '../../utils/sharedSchemas.js';
|
|
5
|
+
import { formatSummaryMap, resolveDateRange, resolveOrderFilters } from '../../utils/orderFilters.js';
|
|
6
|
+
|
|
7
|
+
export const SalesSummarySchema = {
|
|
8
|
+
...DateRangeSchema,
|
|
9
|
+
...OrderFilterSchema,
|
|
10
|
+
days: z.number().int().min(1).max(365).optional(),
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const SalesSummaryZodSchema = z.object(SalesSummarySchema);
|
|
14
|
+
export type SalesSummaryParams = z.infer<typeof SalesSummaryZodSchema>;
|
|
15
|
+
|
|
16
|
+
export async function getSalesSummaryHandler(context: Context, params: SalesSummaryParams) {
|
|
17
|
+
const { modules, userId } = context;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
log('handler getSalesSummaryHandler', { userId, params });
|
|
21
|
+
|
|
22
|
+
const { from, to, days = 30, paymentProviderIds, deliveryProviderIds, status } = params;
|
|
23
|
+
const { startDate, endDate } = resolveDateRange(from, to, days);
|
|
24
|
+
|
|
25
|
+
const filters = await resolveOrderFilters(modules, { paymentProviderIds, deliveryProviderIds });
|
|
26
|
+
if (!filters) {
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: 'text' as const,
|
|
31
|
+
text: JSON.stringify({
|
|
32
|
+
totalSalesAmount: 0,
|
|
33
|
+
orderCount: 0,
|
|
34
|
+
averageOrderValue: 0,
|
|
35
|
+
currencyCode: null,
|
|
36
|
+
summary: [],
|
|
37
|
+
dateRange: { start: startDate.toISOString(), end: endDate.toISOString() },
|
|
38
|
+
}),
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const orders = await modules.orders.findOrders({
|
|
45
|
+
dateRange: { start: startDate.toISOString(), end: endDate.toISOString() },
|
|
46
|
+
...filters,
|
|
47
|
+
status,
|
|
48
|
+
} as any);
|
|
49
|
+
|
|
50
|
+
let totalSalesAmount = 0;
|
|
51
|
+
let orderCount = 0;
|
|
52
|
+
|
|
53
|
+
const dateMap = new Map<string, { sales: number; orders: number }>();
|
|
54
|
+
for (let i = 0; i < days; i++) {
|
|
55
|
+
const date = new Date(endDate.getTime() - i * 86400000);
|
|
56
|
+
const label = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
57
|
+
dateMap.set(label, { sales: 0, orders: 0 });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (const order of orders) {
|
|
61
|
+
const orderDate = new Date(order.created);
|
|
62
|
+
if (orderDate < startDate || orderDate > endDate) continue;
|
|
63
|
+
|
|
64
|
+
orderCount++;
|
|
65
|
+
const itemsAmount = order.calculation?.find((c) => c.category === 'ITEMS')?.amount || 0;
|
|
66
|
+
totalSalesAmount += itemsAmount;
|
|
67
|
+
|
|
68
|
+
const label = orderDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
|
|
69
|
+
const entry = dateMap.get(label);
|
|
70
|
+
if (entry) {
|
|
71
|
+
entry.sales += itemsAmount;
|
|
72
|
+
entry.orders += 1;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const averageOrderValue = orderCount > 0 ? totalSalesAmount / orderCount : 0;
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: 'text' as const,
|
|
82
|
+
text: JSON.stringify({
|
|
83
|
+
totalSalesAmount,
|
|
84
|
+
orderCount,
|
|
85
|
+
averageOrderValue,
|
|
86
|
+
currencyCode: orders[0]?.currencyCode ?? null,
|
|
87
|
+
summary: formatSummaryMap(dateMap),
|
|
88
|
+
dateRange: { start: startDate.toISOString(), end: endDate.toISOString() },
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
} catch (error) {
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: 'text' as const,
|
|
98
|
+
text: `Error fetching sales summary: ${(error as Error).message}`,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Context } from '../../../context.js';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import { resolveDateRange } from '../../utils/orderFilters.js';
|
|
5
|
+
import { OrderStatus } from '@unchainedshop/core-orders';
|
|
6
|
+
|
|
7
|
+
export const GetTopCustomersSchema = {
|
|
8
|
+
limit: z.number().int().min(1).max(100).optional().describe('Max number of customers to return'),
|
|
9
|
+
status: z.string().optional().describe('Order status to filter by (e.g., CONFIRMED, DELIVERED)'),
|
|
10
|
+
dateRange: z
|
|
11
|
+
.object({
|
|
12
|
+
start: z.string().datetime().optional(),
|
|
13
|
+
end: z.string().datetime().optional(),
|
|
14
|
+
})
|
|
15
|
+
.optional()
|
|
16
|
+
.describe('Optional date range to filter orders'),
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const GetTopCustomersZodSchema = z.object(GetTopCustomersSchema);
|
|
20
|
+
export type GetTopCustomersParams = z.infer<typeof GetTopCustomersZodSchema>;
|
|
21
|
+
|
|
22
|
+
export async function getTopCustomersHandler(context: Context, params: GetTopCustomersParams) {
|
|
23
|
+
const { modules, userId, loaders } = context;
|
|
24
|
+
const { status, dateRange, limit = 10 } = params;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
log('handler getTopCustomersHandler', { userId, params });
|
|
28
|
+
|
|
29
|
+
const match: any = {};
|
|
30
|
+
const { startDate, endDate } = resolveDateRange(dateRange?.start, dateRange?.end);
|
|
31
|
+
|
|
32
|
+
const orders = await modules.orders.findOrders(
|
|
33
|
+
{
|
|
34
|
+
status: [OrderStatus.CONFIRMED, OrderStatus.FULLFILLED],
|
|
35
|
+
dateRange: { start: startDate.toISOString(), end: endDate.toISOString() },
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
projection: {
|
|
39
|
+
_id: 1,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const orderIds = orders.map(({ _id }) => _id);
|
|
45
|
+
if (startDate) match.created = { ...(match.created || {}), $gte: startDate };
|
|
46
|
+
if (endDate) match.created = { ...(match.created || {}), $lte: endDate };
|
|
47
|
+
if (status) match.status = status;
|
|
48
|
+
if (orderIds?.length) match._id = { $in: orderIds };
|
|
49
|
+
|
|
50
|
+
const topCustomers = await modules.orders.aggregateOrders({
|
|
51
|
+
match,
|
|
52
|
+
project: {
|
|
53
|
+
userId: 1,
|
|
54
|
+
created: 1,
|
|
55
|
+
itemAmount: {
|
|
56
|
+
$let: {
|
|
57
|
+
vars: {
|
|
58
|
+
item: {
|
|
59
|
+
$first: {
|
|
60
|
+
$filter: {
|
|
61
|
+
input: '$calculation',
|
|
62
|
+
as: 'c',
|
|
63
|
+
cond: { $eq: ['$$c.category', 'ITEMS'] },
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
in: '$$item.amount',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
group: {
|
|
73
|
+
_id: '$userId',
|
|
74
|
+
totalSpent: { $sum: '$itemAmount' },
|
|
75
|
+
orderCount: { $sum: 1 },
|
|
76
|
+
lastOrderDate: { $max: '$created' },
|
|
77
|
+
},
|
|
78
|
+
addFields: {
|
|
79
|
+
averageOrderValue: {
|
|
80
|
+
$cond: [{ $eq: ['$orderCount', 0] }, 0, { $divide: ['$totalSpent', '$orderCount'] }],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
sort: { totalSpent: -1 },
|
|
84
|
+
limit,
|
|
85
|
+
});
|
|
86
|
+
const normalizedCustomers = await Promise.all(
|
|
87
|
+
topCustomers.map(async (c) => {
|
|
88
|
+
const user = await modules.users.findUserById(c._id);
|
|
89
|
+
const avatar = await loaders.fileLoader.load({
|
|
90
|
+
fileId: user?.avatarId,
|
|
91
|
+
});
|
|
92
|
+
return {
|
|
93
|
+
userId: c._id?.toString?.() ?? null,
|
|
94
|
+
user: {
|
|
95
|
+
...user,
|
|
96
|
+
avatar,
|
|
97
|
+
},
|
|
98
|
+
totalSpent: c.totalSpent,
|
|
99
|
+
orderCount: c.orderCount,
|
|
100
|
+
lastOrderDate: c.lastOrderDate,
|
|
101
|
+
averageOrderValue: Math.round(c.averageOrderValue),
|
|
102
|
+
};
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
content: [
|
|
108
|
+
{
|
|
109
|
+
type: 'text' as const,
|
|
110
|
+
text: JSON.stringify({ customers: normalizedCustomers }),
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
} catch (error) {
|
|
115
|
+
return {
|
|
116
|
+
content: [
|
|
117
|
+
{
|
|
118
|
+
type: 'text' as const,
|
|
119
|
+
text: `Error fetching top customers: ${(error as Error).message}`,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|