medusa-plugin-statistics 0.1.0

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.
Files changed (44) hide show
  1. package/.medusa/server/medusa-config.d.ts +1 -0
  2. package/.medusa/server/medusa-config.js +23 -0
  3. package/.medusa/server/src/admin/index.js +790 -0
  4. package/.medusa/server/src/admin/index.mjs +789 -0
  5. package/.medusa/server/src/api/admin/mcp/route.d.ts +4 -0
  6. package/.medusa/server/src/api/admin/mcp/route.js +60 -0
  7. package/.medusa/server/src/api/admin/statistics/layout/route.d.ts +4 -0
  8. package/.medusa/server/src/api/admin/statistics/layout/route.js +37 -0
  9. package/.medusa/server/src/api/admin/statistics/low-stock/route.d.ts +3 -0
  10. package/.medusa/server/src/api/admin/statistics/low-stock/route.js +85 -0
  11. package/.medusa/server/src/api/admin/statistics/recalculate/route.d.ts +3 -0
  12. package/.medusa/server/src/api/admin/statistics/recalculate/route.js +32 -0
  13. package/.medusa/server/src/api/admin/statistics/recent-orders/route.d.ts +3 -0
  14. package/.medusa/server/src/api/admin/statistics/recent-orders/route.js +19 -0
  15. package/.medusa/server/src/api/admin/statistics/route.d.ts +3 -0
  16. package/.medusa/server/src/api/admin/statistics/route.js +55 -0
  17. package/.medusa/server/src/api/middlewares.d.ts +2 -0
  18. package/.medusa/server/src/api/middlewares.js +44 -0
  19. package/.medusa/server/src/api/validators.d.ts +85 -0
  20. package/.medusa/server/src/api/validators.js +30 -0
  21. package/.medusa/server/src/jobs/update-statistics.d.ts +7 -0
  22. package/.medusa/server/src/jobs/update-statistics.js +165 -0
  23. package/.medusa/server/src/mcp/server.d.ts +3 -0
  24. package/.medusa/server/src/mcp/server.js +23 -0
  25. package/.medusa/server/src/mcp/tools/customers.d.ts +3 -0
  26. package/.medusa/server/src/mcp/tools/customers.js +72 -0
  27. package/.medusa/server/src/mcp/tools/inventory.d.ts +3 -0
  28. package/.medusa/server/src/mcp/tools/inventory.js +70 -0
  29. package/.medusa/server/src/mcp/tools/orders.d.ts +3 -0
  30. package/.medusa/server/src/mcp/tools/orders.js +80 -0
  31. package/.medusa/server/src/mcp/tools/products.d.ts +3 -0
  32. package/.medusa/server/src/mcp/tools/products.js +72 -0
  33. package/.medusa/server/src/mcp/tools/query.d.ts +3 -0
  34. package/.medusa/server/src/mcp/tools/query.js +42 -0
  35. package/.medusa/server/src/modules/statistics/index.d.ts +22 -0
  36. package/.medusa/server/src/modules/statistics/index.js +25 -0
  37. package/.medusa/server/src/modules/statistics/migrations/Migration20260409171831.d.ts +5 -0
  38. package/.medusa/server/src/modules/statistics/migrations/Migration20260409171831.js +15 -0
  39. package/.medusa/server/src/modules/statistics/models/statistics-daily.d.ts +13 -0
  40. package/.medusa/server/src/modules/statistics/models/statistics-daily.js +18 -0
  41. package/.medusa/server/src/modules/statistics/service.d.ts +18 -0
  42. package/.medusa/server/src/modules/statistics/service.js +9 -0
  43. package/LICENSE +21 -0
  44. package/package.json +97 -0
@@ -0,0 +1,4 @@
1
+ import { AuthenticatedMedusaRequest, MedusaResponse } from '@medusajs/framework/http';
2
+ export declare const POST: (req: AuthenticatedMedusaRequest, res: MedusaResponse) => Promise<void>;
3
+ export declare const GET: (_req: AuthenticatedMedusaRequest, res: MedusaResponse) => Promise<void>;
4
+ export declare const DELETE: (_req: AuthenticatedMedusaRequest, res: MedusaResponse) => Promise<void>;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DELETE = exports.GET = exports.POST = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
6
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
+ const server_1 = require("../../../mcp/server");
8
+ // Store transports by session ID for stateful MCP connections
9
+ const sessions = {};
10
+ const POST = async (req, res) => {
11
+ try {
12
+ const sessionId = req.headers['mcp-session-id'];
13
+ let transport;
14
+ if (sessionId && sessions[sessionId]) {
15
+ // Reuse existing session transport
16
+ transport = sessions[sessionId];
17
+ }
18
+ else if (!sessionId && (0, types_js_1.isInitializeRequest)(req.body)) {
19
+ // New initialization request
20
+ transport = new streamableHttp_js_1.StreamableHTTPServerTransport({
21
+ sessionIdGenerator: () => (0, node_crypto_1.randomUUID)(),
22
+ enableJsonResponse: true,
23
+ onsessioninitialized: (id) => {
24
+ sessions[id] = transport;
25
+ }
26
+ });
27
+ const server = (0, server_1.createMcpServer)(req.scope);
28
+ await server.connect(transport);
29
+ }
30
+ else {
31
+ res.status(400).json({
32
+ jsonrpc: '2.0',
33
+ error: { code: -32000, message: 'Bad Request: No valid session. Send initialize first.' },
34
+ id: null
35
+ });
36
+ return;
37
+ }
38
+ await transport.handleRequest(req, res, req.body);
39
+ }
40
+ catch (err) {
41
+ console.error('[MCP] Error:', err);
42
+ if (!res.headersSent) {
43
+ res.status(500).json({
44
+ jsonrpc: '2.0',
45
+ error: { code: -32603, message: 'Internal server error' },
46
+ id: null
47
+ });
48
+ }
49
+ }
50
+ };
51
+ exports.POST = POST;
52
+ const GET = async (_req, res) => {
53
+ res.writeHead(405).end(JSON.stringify({ error: 'Method not allowed' }));
54
+ };
55
+ exports.GET = GET;
56
+ const DELETE = async (_req, res) => {
57
+ res.writeHead(405).end(JSON.stringify({ error: 'Method not allowed' }));
58
+ };
59
+ exports.DELETE = DELETE;
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL21jcC9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBd0M7QUFFeEMsMEZBQWtHO0FBQ2xHLGlFQUF3RTtBQUN4RSxnREFBcUQ7QUFFckQsOERBQThEO0FBQzlELE1BQU0sUUFBUSxHQUFrRCxFQUFFLENBQUE7QUFFM0QsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQStCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ2xGLElBQUksQ0FBQztRQUNKLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQXVCLENBQUE7UUFDckUsSUFBSSxTQUF3QyxDQUFBO1FBRTVDLElBQUksU0FBUyxJQUFJLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3RDLG1DQUFtQztZQUNuQyxTQUFTLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQ2hDLENBQUM7YUFBTSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUEsOEJBQW1CLEVBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDeEQsNkJBQTZCO1lBQzdCLFNBQVMsR0FBRyxJQUFJLGlEQUE2QixDQUFDO2dCQUM3QyxrQkFBa0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFBLHdCQUFVLEdBQUU7Z0JBQ3RDLGtCQUFrQixFQUFFLElBQUk7Z0JBQ3hCLG9CQUFvQixFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUU7b0JBQzVCLFFBQVEsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUE7Z0JBQ3pCLENBQUM7YUFDRCxDQUFDLENBQUE7WUFFRixNQUFNLE1BQU0sR0FBRyxJQUFBLHdCQUFlLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ3pDLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUNoQyxDQUFDO2FBQU0sQ0FBQztZQUNQLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUNwQixPQUFPLEVBQUUsS0FBSztnQkFDZCxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLHVEQUF1RCxFQUFFO2dCQUN6RixFQUFFLEVBQUUsSUFBSTthQUNSLENBQUMsQ0FBQTtZQUNGLE9BQU07UUFDUCxDQUFDO1FBRUQsTUFBTSxTQUFTLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2xELENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2QsT0FBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDbEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0QixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDcEIsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRTtnQkFDekQsRUFBRSxFQUFFLElBQUk7YUFDUixDQUFDLENBQUE7UUFDSCxDQUFDO0lBQ0YsQ0FBQztBQUNGLENBQUMsQ0FBQTtBQXhDWSxRQUFBLElBQUksUUF3Q2hCO0FBRU0sTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUFFLElBQWdDLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ2xGLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDLENBQUE7QUFDeEUsQ0FBQyxDQUFBO0FBRlksUUFBQSxHQUFHLE9BRWY7QUFFTSxNQUFNLE1BQU0sR0FBRyxLQUFLLEVBQUUsSUFBZ0MsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDckYsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEtBQUssRUFBRSxvQkFBb0IsRUFBRSxDQUFDLENBQUMsQ0FBQTtBQUN4RSxDQUFDLENBQUE7QUFGWSxRQUFBLE1BQU0sVUFFbEIifQ==
@@ -0,0 +1,4 @@
1
+ import { AuthenticatedMedusaRequest, MedusaResponse } from '@medusajs/framework/http';
2
+ import { AdminSaveStatisticsLayoutType } from '../../../validators';
3
+ export declare const GET: (req: AuthenticatedMedusaRequest, res: MedusaResponse) => Promise<void>;
4
+ export declare const POST: (req: AuthenticatedMedusaRequest<AdminSaveStatisticsLayoutType>, res: MedusaResponse) => Promise<void>;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = exports.GET = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const GET = async (req, res) => {
6
+ const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
7
+ const userId = req.auth_context.actor_id;
8
+ const { data: [user] } = await query.graph({
9
+ entity: 'user',
10
+ fields: ['id', 'metadata'],
11
+ filters: { id: userId }
12
+ });
13
+ const layout = user?.metadata?.statistics_layout ?? null;
14
+ res.json({ layout });
15
+ };
16
+ exports.GET = GET;
17
+ const POST = async (req, res) => {
18
+ const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
19
+ const userService = req.scope.resolve(utils_1.Modules.USER);
20
+ const userId = req.auth_context.actor_id;
21
+ const { data: [user] } = await query.graph({
22
+ entity: 'user',
23
+ fields: ['id', 'metadata'],
24
+ filters: { id: userId }
25
+ });
26
+ const existingMetadata = user?.metadata ?? {};
27
+ await userService.updateUsers({
28
+ id: userId,
29
+ metadata: {
30
+ ...existingMetadata,
31
+ statistics_layout: req.validatedBody.layout
32
+ }
33
+ });
34
+ res.json({ layout: req.validatedBody.layout });
35
+ };
36
+ exports.POST = POST;
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3N0YXRpc3RpY3MvbGF5b3V0L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUE4RTtBQUd2RSxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQUUsR0FBK0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDakYsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUE7SUFFeEMsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzFDLE1BQU0sRUFBRSxNQUFNO1FBQ2QsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQztRQUMxQixPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFO0tBQ3ZCLENBQUMsQ0FBQTtJQUVGLE1BQU0sTUFBTSxHQUFJLElBQVksRUFBRSxRQUFRLEVBQUUsaUJBQWlCLElBQUksSUFBSSxDQUFBO0lBRWpFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFBO0FBQ3JCLENBQUMsQ0FBQTtBQWJZLFFBQUEsR0FBRyxPQWFmO0FBRU0sTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUN4QixHQUE4RCxFQUM5RCxHQUFtQixFQUNsQixFQUFFO0lBQ0gsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEUsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ25ELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFBO0lBRXhDLE1BQU0sRUFBRSxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztRQUMxQyxNQUFNLEVBQUUsTUFBTTtRQUNkLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUM7UUFDMUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRTtLQUN2QixDQUFDLENBQUE7SUFFRixNQUFNLGdCQUFnQixHQUFJLElBQVksRUFBRSxRQUFRLElBQUksRUFBRSxDQUFBO0lBRXRELE1BQU8sV0FBbUIsQ0FBQyxXQUFXLENBQUM7UUFDdEMsRUFBRSxFQUFFLE1BQU07UUFDVixRQUFRLEVBQUU7WUFDVCxHQUFHLGdCQUFnQjtZQUNuQixpQkFBaUIsRUFBRSxHQUFHLENBQUMsYUFBYSxDQUFDLE1BQU07U0FDM0M7S0FDRCxDQUFDLENBQUE7SUFFRixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQTtBQUMvQyxDQUFDLENBQUE7QUF6QlksUUFBQSxJQUFJLFFBeUJoQiJ9
@@ -0,0 +1,3 @@
1
+ import { AuthenticatedMedusaRequest, MedusaResponse } from '@medusajs/framework/http';
2
+ import { AdminGetLowStockType } from '../../../validators';
3
+ export declare const GET: (req: AuthenticatedMedusaRequest<AdminGetLowStockType>, res: MedusaResponse) => Promise<void>;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const GET = async (req, res) => {
6
+ const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
7
+ const logger = req.scope.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
8
+ const { threshold } = req.validatedQuery;
9
+ try {
10
+ // Get all stock locations
11
+ const { data: locations } = await query.graph({
12
+ entity: 'stock_location',
13
+ fields: ['id', 'name']
14
+ });
15
+ const locationMap = new Map(locations.map(l => [l.id, l.name]));
16
+ // Get all inventory items with location levels
17
+ const { data: items } = await query.graph({
18
+ entity: 'inventory_item',
19
+ fields: [
20
+ 'id', 'sku', 'title',
21
+ 'location_levels.id',
22
+ 'location_levels.stocked_quantity',
23
+ 'location_levels.location_id'
24
+ ],
25
+ pagination: { take: 200 }
26
+ });
27
+ const warnings = [];
28
+ for (const item of items) {
29
+ for (const level of item.location_levels ?? []) {
30
+ const locationId = level.location_id;
31
+ if (!locationId)
32
+ continue;
33
+ const locationName = locationMap.get(locationId) ?? 'Unknown';
34
+ // Query stock lots for this item at this location
35
+ const { data: lots } = await query.graph({
36
+ entity: 'stock_lot',
37
+ fields: ['id', 'stocked_quantity', 'enabled'],
38
+ filters: {
39
+ inventory_item_id: item.id,
40
+ stock_location_id: locationId
41
+ }
42
+ });
43
+ const enabledLots = lots.filter(l => l.enabled);
44
+ if (enabledLots.length === 0) {
45
+ warnings.push({
46
+ inventory_item_id: item.id,
47
+ sku: item.sku,
48
+ title: item.title,
49
+ location_name: locationName,
50
+ location_id: locationId,
51
+ reason: 'no_lots',
52
+ available_quantity: 0
53
+ });
54
+ }
55
+ else {
56
+ const totalAvailable = enabledLots.reduce((sum, l) => sum + (l.stocked_quantity ?? 0), 0);
57
+ if (totalAvailable < threshold) {
58
+ warnings.push({
59
+ inventory_item_id: item.id,
60
+ sku: item.sku,
61
+ title: item.title,
62
+ location_name: locationName,
63
+ location_id: locationId,
64
+ reason: 'low_stock',
65
+ available_quantity: totalAvailable
66
+ });
67
+ }
68
+ }
69
+ }
70
+ }
71
+ // Sort: no_lots first, then by available_quantity ascending
72
+ warnings.sort((a, b) => {
73
+ if (a.reason !== b.reason)
74
+ return a.reason === 'no_lots' ? -1 : 1;
75
+ return a.available_quantity - b.available_quantity;
76
+ });
77
+ res.json({ warnings });
78
+ }
79
+ catch (err) {
80
+ logger.error(`low-stock error: ${err.message}`);
81
+ res.status(500).json({ error: err.message });
82
+ }
83
+ };
84
+ exports.GET = GET;
85
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3N0YXRpc3RpY3MvbG93LXN0b2NrL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUFxRTtBQUc5RCxNQUFNLEdBQUcsR0FBRyxLQUFLLEVBQ3ZCLEdBQXFELEVBQ3JELEdBQW1CLEVBQ2xCLEVBQUU7SUFDSCxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNoRSxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUNsRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsR0FBRyxDQUFDLGNBQXNDLENBQUE7SUFFaEUsSUFBSSxDQUFDO1FBQ0osMEJBQTBCO1FBQzFCLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQzdDLE1BQU0sRUFBRSxnQkFBZ0I7WUFDeEIsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQztTQUN0QixDQUFDLENBQUE7UUFDRixNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBRSxTQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBRTFFLCtDQUErQztRQUMvQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztZQUN6QyxNQUFNLEVBQUUsZ0JBQWdCO1lBQ3hCLE1BQU0sRUFBRTtnQkFDUCxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU87Z0JBQ3BCLG9C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
@@ -0,0 +1,3 @@
1
+ import { AuthenticatedMedusaRequest, MedusaResponse } from '@medusajs/framework/http';
2
+ import { AdminRecalculateStatisticsType } from '../../../validators';
3
+ export declare const POST: (req: AuthenticatedMedusaRequest<AdminRecalculateStatisticsType>, res: MedusaResponse) => Promise<void>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = void 0;
4
+ const statistics_1 = require("../../../../modules/statistics");
5
+ const update_statistics_1 = require("../../../../jobs/update-statistics");
6
+ async function recalculateAll(req) {
7
+ const statisticsService = req.scope.resolve(statistics_1.STATISTICS_MODULE);
8
+ // Find the earliest existing stat to know how far back to go
9
+ const allStats = await statisticsService.listStatisticsDailies({}, { order: { date: 'ASC' }, take: 1 });
10
+ const now = new Date();
11
+ const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
12
+ // Default to 30 days back if no existing stats
13
+ let startDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 30));
14
+ if (allStats.length > 0) {
15
+ const earliest = new Date(allStats[0].date);
16
+ if (earliest < startDate) {
17
+ startDate = earliest;
18
+ }
19
+ }
20
+ // Recompute each day from startDate through today
21
+ const current = new Date(startDate);
22
+ while (current <= today) {
23
+ await (0, update_statistics_1.computeStatsForDay)(req.scope, new Date(current));
24
+ current.setUTCDate(current.getUTCDate() + 1);
25
+ }
26
+ }
27
+ const POST = async (req, res) => {
28
+ await recalculateAll(req);
29
+ res.json({ success: true });
30
+ };
31
+ exports.POST = POST;
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3N0YXRpc3RpY3MvcmVjYWxjdWxhdGUvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsK0RBQWtFO0FBRWxFLDBFQUF1RTtBQUV2RSxLQUFLLFVBQVUsY0FBYyxDQUFDLEdBQStCO0lBQzVELE1BQU0saUJBQWlCLEdBQXNCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDhCQUFpQixDQUFDLENBQUE7SUFFakYsNkRBQTZEO0lBQzdELE1BQU0sUUFBUSxHQUFHLE1BQU0saUJBQWlCLENBQUMscUJBQXFCLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBRXZHLE1BQU0sR0FBRyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUE7SUFDdEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLEVBQUUsR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFFM0YsK0NBQStDO0lBQy9DLElBQUksU0FBUyxHQUFHLElBQUksSUFBSSxDQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsRUFBRSxHQUFHLENBQUMsV0FBVyxFQUFFLEVBQUUsR0FBRyxDQUFDLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUN4RSxDQUFBO0lBQ0QsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFFLFFBQVEsQ0FBQyxDQUFDLENBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNwRCxJQUFJLFFBQVEsR0FBRyxTQUFTLEVBQUUsQ0FBQztZQUMxQixTQUFTLEdBQUcsUUFBUSxDQUFBO1FBQ3JCLENBQUM7SUFDRixDQUFDO0lBRUQsa0RBQWtEO0lBQ2xELE1BQU0sT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ25DLE9BQU8sT0FBTyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3pCLE1BQU0sSUFBQSxzQ0FBa0IsRUFBQyxHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7UUFDdEQsT0FBTyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDN0MsQ0FBQztBQUNGLENBQUM7QUFFTSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQ3hCLEdBQStELEVBQy9ELEdBQW1CLEVBQ2xCLEVBQUU7SUFDSCxNQUFNLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN6QixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7QUFDNUIsQ0FBQyxDQUFBO0FBTlksUUFBQSxJQUFJLFFBTWhCIn0=
@@ -0,0 +1,3 @@
1
+ import { AuthenticatedMedusaRequest, MedusaResponse } from '@medusajs/framework/http';
2
+ import { AdminGetRecentOrdersType } from '../../../validators';
3
+ export declare const GET: (req: AuthenticatedMedusaRequest<AdminGetRecentOrdersType>, res: MedusaResponse) => Promise<void>;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const GET = async (req, res) => {
6
+ const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
7
+ const { limit } = req.validatedQuery;
8
+ const { data: orders } = await query.graph({
9
+ entity: 'order',
10
+ fields: [
11
+ 'id', 'display_id', 'status', 'email', 'total', 'created_at',
12
+ 'customer.first_name', 'customer.last_name'
13
+ ],
14
+ pagination: { take: limit, order: { created_at: 'DESC' } }
15
+ });
16
+ res.json({ orders });
17
+ };
18
+ exports.GET = GET;
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3N0YXRpc3RpY3MvcmVjZW50LW9yZGVycy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFBcUU7QUFHOUQsTUFBTSxHQUFHLEdBQUcsS0FBSyxFQUN2QixHQUF5RCxFQUN6RCxHQUFtQixFQUNsQixFQUFFO0lBQ0gsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUNBQXlCLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEUsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQyxjQUEwQyxDQUFBO0lBRWhFLE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzFDLE1BQU0sRUFBRSxPQUFPO1FBQ2YsTUFBTSxFQUFFO1lBQ1AsSUFBSSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxZQUFZO1lBQzVELHFCQUFxQixFQUFFLG9CQUFvQjtTQUMzQztRQUNELFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxFQUFFO0tBQzFELENBQUMsQ0FBQTtJQUVGLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFBO0FBQ3JCLENBQUMsQ0FBQTtBQWpCWSxRQUFBLEdBQUcsT0FpQmYifQ==
@@ -0,0 +1,3 @@
1
+ import { AuthenticatedMedusaRequest, MedusaResponse } from '@medusajs/framework/http';
2
+ import { AdminGetStatisticsType } from '../../validators';
3
+ export declare const GET: (req: AuthenticatedMedusaRequest<AdminGetStatisticsType>, res: MedusaResponse) => Promise<void>;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = void 0;
4
+ const statistics_1 = require("../../../modules/statistics");
5
+ const GET = async (req, res) => {
6
+ const statisticsService = req.scope.resolve(statistics_1.STATISTICS_MODULE);
7
+ const { period, start_date, end_date } = req.validatedQuery;
8
+ const now = new Date();
9
+ let startDate;
10
+ let endDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1));
11
+ if (start_date && end_date) {
12
+ startDate = new Date(start_date);
13
+ endDate = new Date(end_date);
14
+ }
15
+ else {
16
+ switch (period) {
17
+ case 'today':
18
+ startDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
19
+ break;
20
+ case 'month':
21
+ startDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 30));
22
+ break;
23
+ case 'week':
24
+ default:
25
+ startDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() - 7));
26
+ break;
27
+ }
28
+ }
29
+ const statistics = await statisticsService.listStatisticsDailies({
30
+ date: {
31
+ $gte: startDate,
32
+ $lt: endDate
33
+ }
34
+ }, { order: { date: 'ASC' } });
35
+ // Compute aggregated totals across the period
36
+ const totals = {
37
+ revenue_total: 0,
38
+ order_count: 0,
39
+ average_order_value: 0,
40
+ new_customer_count: 0,
41
+ returning_customer_count: 0,
42
+ pending_fulfillment_count: statistics.length > 0 ? statistics[statistics.length - 1].pending_fulfillment_count : 0,
43
+ low_stock_count: statistics.length > 0 ? statistics[statistics.length - 1].low_stock_count : 0
44
+ };
45
+ for (const stat of statistics) {
46
+ totals.revenue_total += stat.revenue_total;
47
+ totals.order_count += stat.order_count;
48
+ totals.new_customer_count += stat.new_customer_count;
49
+ totals.returning_customer_count += stat.returning_customer_count;
50
+ }
51
+ totals.average_order_value = totals.order_count > 0 ? totals.revenue_total / totals.order_count : 0;
52
+ res.json({ statistics, totals, period });
53
+ };
54
+ exports.GET = GET;
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3N0YXRpc3RpY3Mvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsNERBQStEO0FBSXhELE1BQU0sR0FBRyxHQUFHLEtBQUssRUFDdkIsR0FBdUQsRUFDdkQsR0FBbUIsRUFDbEIsRUFBRTtJQUNILE1BQU0saUJBQWlCLEdBQXNCLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLDhCQUFpQixDQUFDLENBQUE7SUFDakYsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEdBQUcsR0FBRyxDQUFDLGNBQXdDLENBQUE7SUFFckYsTUFBTSxHQUFHLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQTtJQUN0QixJQUFJLFNBQWUsQ0FBQTtJQUNuQixJQUFJLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsRUFBRSxHQUFHLENBQUMsV0FBVyxFQUFFLEVBQUUsR0FBRyxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFFL0YsSUFBSSxVQUFVLElBQUksUUFBUSxFQUFFLENBQUM7UUFDNUIsU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ2hDLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUM3QixDQUFDO1NBQU0sQ0FBQztRQUNQLFFBQVEsTUFBTSxFQUFFLENBQUM7WUFDaEIsS0FBSyxPQUFPO2dCQUNYLFNBQVMsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsRUFBRSxHQUFHLENBQUMsV0FBVyxFQUFFLEVBQUUsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQTtnQkFDekYsTUFBSztZQUNOLEtBQUssT0FBTztnQkFDWCxTQUFTLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLEVBQUUsR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLEdBQUcsQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFBO2dCQUM5RixNQUFLO1lBQ04sS0FBSyxNQUFNLENBQUM7WUFDWjtnQkFDQyxTQUFTLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLEVBQUUsR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLEdBQUcsQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUM3RixNQUFLO1FBQ1AsQ0FBQztJQUNGLENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxNQUFNLGlCQUFpQixDQUFDLHFCQUFxQixDQUMvRDtRQUNDLElBQUksRUFBRTtZQUNMLElBQUksRUFBRSxTQUFTO1lBQ2YsR0FBRyxFQUFFLE9BQU87U0FDWjtLQUNNLEVBQ1IsRUFBRSxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FDMUIsQ0FBQTtJQUVELDhDQUE4QztJQUM5QyxNQUFNLE1BQU0sR0FBRztRQUNkLGFBQWEsRUFBRSxDQUFDO1FBQ2hCLFdBQVcsRUFBRSxDQUFDO1FBQ2QsbUJBQW1CLEVBQUUsQ0FBQztRQUN0QixrQkFBa0IsRUFBRSxDQUFDO1FBQ3JCLHdCQUF3QixFQUFFLENBQUM7UUFDM0IseUJBQXlCLEVBQUUsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFFLFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBUyxDQUFDLHlCQUF5QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNILGVBQWUsRUFBRSxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUUsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFTLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQ3ZHLENBQUE7SUFFRCxLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQW1CLEVBQUUsQ0FBQztRQUN4QyxNQUFNLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUE7UUFDMUMsTUFBTSxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFBO1FBQ3RDLE1BQU0sQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUE7UUFDcEQsTUFBTSxDQUFDLHdCQUF3QixJQUFJLElBQUksQ0FBQyx3QkFBd0IsQ0FBQTtJQUNqRSxDQUFDO0lBRUQsTUFBTSxDQUFDLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVuRyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFBO0FBQ3pDLENBQUMsQ0FBQTtBQTVEWSxRQUFBLEdBQUcsT0E0RGYifQ==
@@ -0,0 +1,2 @@
1
+ declare const _default: import("@medusajs/framework/http").MiddlewaresConfig;
2
+ export default _default;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const http_1 = require("@medusajs/framework/http");
4
+ const validators_1 = require("./validators");
5
+ function exposeMcpHeaders(req, res, next) {
6
+ res.setHeader('Access-Control-Expose-Headers', 'mcp-session-id');
7
+ res.setHeader('Access-Control-Allow-Headers', [res.getHeader('Access-Control-Allow-Headers') ?? '', 'mcp-session-id']
8
+ .filter(Boolean)
9
+ .join(', '));
10
+ next();
11
+ }
12
+ exports.default = (0, http_1.defineMiddlewares)([
13
+ {
14
+ matcher: '/admin/mcp',
15
+ method: ['GET', 'POST', 'DELETE'],
16
+ middlewares: [exposeMcpHeaders]
17
+ },
18
+ {
19
+ matcher: '/admin/statistics',
20
+ method: ['GET'],
21
+ middlewares: [(0, http_1.validateAndTransformQuery)(validators_1.AdminGetStatistics, { isList: false })]
22
+ },
23
+ {
24
+ matcher: '/admin/statistics/recalculate',
25
+ method: ['POST'],
26
+ middlewares: [(0, http_1.validateAndTransformBody)(validators_1.AdminRecalculateStatistics)]
27
+ },
28
+ {
29
+ matcher: '/admin/statistics/recent-orders',
30
+ method: ['GET'],
31
+ middlewares: [(0, http_1.validateAndTransformQuery)(validators_1.AdminGetRecentOrders, { isList: false })]
32
+ },
33
+ {
34
+ matcher: '/admin/statistics/low-stock',
35
+ method: ['GET'],
36
+ middlewares: [(0, http_1.validateAndTransformQuery)(validators_1.AdminGetLowStock, { isList: false })]
37
+ },
38
+ {
39
+ matcher: '/admin/statistics/layout',
40
+ method: ['POST'],
41
+ middlewares: [(0, http_1.validateAndTransformBody)(validators_1.AdminSaveStatisticsLayout)]
42
+ }
43
+ ]);
44
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbURBTWlDO0FBRWpDLDZDQU1xQjtBQUVyQixTQUFTLGdCQUFnQixDQUN4QixHQUFrQixFQUNsQixHQUFtQixFQUNuQixJQUFrQjtJQUVsQixHQUFHLENBQUMsU0FBUyxDQUFDLCtCQUErQixFQUFFLGdCQUFnQixDQUFDLENBQUE7SUFDaEUsR0FBRyxDQUFDLFNBQVMsQ0FDWiw4QkFBOEIsRUFDOUIsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLDhCQUE4QixDQUFDLElBQUksRUFBRSxFQUFFLGdCQUFnQixDQUFDO1NBQ3JFLE1BQU0sQ0FBQyxPQUFPLENBQUM7U0FDZixJQUFJLENBQUMsSUFBSSxDQUFDLENBQ1osQ0FBQTtJQUNELElBQUksRUFBRSxDQUFBO0FBQ1AsQ0FBQztBQUVELGtCQUFlLElBQUEsd0JBQWlCLEVBQUM7SUFDaEM7UUFDQyxPQUFPLEVBQUUsWUFBWTtRQUNyQixNQUFNLEVBQUUsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQztRQUNqQyxXQUFXLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztLQUMvQjtJQUNEO1FBQ0MsT0FBTyxFQUFFLG1CQUFtQjtRQUM1QixNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUM7UUFDZixXQUFXLEVBQUUsQ0FBQyxJQUFBLGdDQUF5QixFQUFDLCtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7S0FDL0U7SUFDRDtRQUNDLE9BQU8sRUFBRSwrQkFBK0I7UUFDeEMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDO1FBQ2hCLFdBQVcsRUFBRSxDQUFDLElBQUEsK0JBQXdCLEVBQUMsdUNBQTBCLENBQUMsQ0FBQztLQUNuRTtJQUNEO1FBQ0MsT0FBTyxFQUFFLGlDQUFpQztRQUMxQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUM7UUFDZixXQUFXLEVBQUUsQ0FBQyxJQUFBLGdDQUF5QixFQUFDLGlDQUFvQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7S0FDakY7SUFDRDtRQUNDLE9BQU8sRUFBRSw2QkFBNkI7UUFDdEMsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDO1FBQ2YsV0FBVyxFQUFFLENBQUMsSUFBQSxnQ0FBeUIsRUFBQyw2QkFBZ0IsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0tBQzdFO0lBQ0Q7UUFDQyxPQUFPLEVBQUUsMEJBQTBCO1FBQ25DLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQztRQUNoQixXQUFXLEVBQUUsQ0FBQyxJQUFBLCtCQUF3QixFQUFDLHNDQUF5QixDQUFDLENBQUM7S0FDbEU7Q0FDRCxDQUFDLENBQUEifQ==
@@ -0,0 +1,85 @@
1
+ import { z } from '@medusajs/framework/zod';
2
+ export declare const AdminGetStatistics: z.ZodObject<{
3
+ period: z.ZodDefault<z.ZodOptional<z.ZodEnum<["today", "week", "month"]>>>;
4
+ start_date: z.ZodOptional<z.ZodString>;
5
+ end_date: z.ZodOptional<z.ZodString>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ period: "today" | "week" | "month";
8
+ start_date?: string | undefined;
9
+ end_date?: string | undefined;
10
+ }, {
11
+ period?: "today" | "week" | "month" | undefined;
12
+ start_date?: string | undefined;
13
+ end_date?: string | undefined;
14
+ }>;
15
+ export type AdminGetStatisticsType = z.infer<typeof AdminGetStatistics>;
16
+ export declare const AdminRecalculateStatistics: z.ZodObject<{
17
+ date: z.ZodOptional<z.ZodString>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ date?: string | undefined;
20
+ }, {
21
+ date?: string | undefined;
22
+ }>;
23
+ export type AdminRecalculateStatisticsType = z.infer<typeof AdminRecalculateStatistics>;
24
+ export declare const AdminGetRecentOrders: z.ZodObject<{
25
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ limit: number;
28
+ }, {
29
+ limit?: number | undefined;
30
+ }>;
31
+ export type AdminGetRecentOrdersType = z.infer<typeof AdminGetRecentOrders>;
32
+ export declare const AdminGetLowStock: z.ZodObject<{
33
+ threshold: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
34
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
35
+ }, "strip", z.ZodTypeAny, {
36
+ limit: number;
37
+ threshold: number;
38
+ }, {
39
+ limit?: number | undefined;
40
+ threshold?: number | undefined;
41
+ }>;
42
+ export type AdminGetLowStockType = z.infer<typeof AdminGetLowStock>;
43
+ export declare const AdminSaveStatisticsLayout: z.ZodObject<{
44
+ layout: z.ZodArray<z.ZodObject<{
45
+ widget_id: z.ZodString;
46
+ x: z.ZodNumber;
47
+ y: z.ZodNumber;
48
+ w: z.ZodNumber;
49
+ h: z.ZodNumber;
50
+ visible: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
51
+ }, "strip", z.ZodTypeAny, {
52
+ widget_id: string;
53
+ x: number;
54
+ y: number;
55
+ w: number;
56
+ h: number;
57
+ visible: boolean;
58
+ }, {
59
+ widget_id: string;
60
+ x: number;
61
+ y: number;
62
+ w: number;
63
+ h: number;
64
+ visible?: boolean | undefined;
65
+ }>, "many">;
66
+ }, "strip", z.ZodTypeAny, {
67
+ layout: {
68
+ widget_id: string;
69
+ x: number;
70
+ y: number;
71
+ w: number;
72
+ h: number;
73
+ visible: boolean;
74
+ }[];
75
+ }, {
76
+ layout: {
77
+ widget_id: string;
78
+ x: number;
79
+ y: number;
80
+ w: number;
81
+ h: number;
82
+ visible?: boolean | undefined;
83
+ }[];
84
+ }>;
85
+ export type AdminSaveStatisticsLayoutType = z.infer<typeof AdminSaveStatisticsLayout>;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AdminSaveStatisticsLayout = exports.AdminGetLowStock = exports.AdminGetRecentOrders = exports.AdminRecalculateStatistics = exports.AdminGetStatistics = void 0;
4
+ const zod_1 = require("@medusajs/framework/zod");
5
+ exports.AdminGetStatistics = zod_1.z.object({
6
+ period: zod_1.z.enum(['today', 'week', 'month']).optional().default('week'),
7
+ start_date: zod_1.z.string().optional(),
8
+ end_date: zod_1.z.string().optional()
9
+ });
10
+ exports.AdminRecalculateStatistics = zod_1.z.object({
11
+ date: zod_1.z.string().optional()
12
+ });
13
+ exports.AdminGetRecentOrders = zod_1.z.object({
14
+ limit: zod_1.z.coerce.number().int().min(1).max(50).optional().default(10)
15
+ });
16
+ exports.AdminGetLowStock = zod_1.z.object({
17
+ threshold: zod_1.z.coerce.number().int().min(0).optional().default(10),
18
+ limit: zod_1.z.coerce.number().int().min(1).max(100).optional().default(20)
19
+ });
20
+ exports.AdminSaveStatisticsLayout = zod_1.z.object({
21
+ layout: zod_1.z.array(zod_1.z.object({
22
+ widget_id: zod_1.z.string(),
23
+ x: zod_1.z.number(),
24
+ y: zod_1.z.number(),
25
+ w: zod_1.z.number(),
26
+ h: zod_1.z.number(),
27
+ visible: zod_1.z.boolean().optional().default(true)
28
+ }))
29
+ });
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdG9ycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcGkvdmFsaWRhdG9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpREFBMkM7QUFFOUIsUUFBQSxrQkFBa0IsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQzFDLE1BQU0sRUFBRSxPQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDckUsVUFBVSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDakMsUUFBUSxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDL0IsQ0FBQyxDQUFBO0FBR1csUUFBQSwwQkFBMEIsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ2xELElBQUksRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQzNCLENBQUMsQ0FBQTtBQUdXLFFBQUEsb0JBQW9CLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM1QyxLQUFLLEVBQUUsT0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Q0FDcEUsQ0FBQyxDQUFBO0FBR1csUUFBQSxnQkFBZ0IsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3hDLFNBQVMsRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO0lBQ2hFLEtBQUssRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztDQUNyRSxDQUFDLENBQUE7QUFHVyxRQUFBLHlCQUF5QixHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDakQsTUFBTSxFQUFFLE9BQUMsQ0FBQyxLQUFLLENBQUMsT0FBQyxDQUFDLE1BQU0sQ0FBQztRQUN4QixTQUFTLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRTtRQUNyQixDQUFDLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRTtRQUNiLENBQUMsRUFBRSxPQUFDLENBQUMsTUFBTSxFQUFFO1FBQ2IsQ0FBQyxFQUFFLE9BQUMsQ0FBQyxNQUFNLEVBQUU7UUFDYixDQUFDLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRTtRQUNiLE9BQU8sRUFBRSxPQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztLQUM3QyxDQUFDLENBQUM7Q0FDSCxDQUFDLENBQUEifQ==
@@ -0,0 +1,7 @@
1
+ import { MedusaContainer } from '@medusajs/framework/types';
2
+ export declare function computeStatsForDay(container: MedusaContainer, day: Date): Promise<void>;
3
+ export default function updateStatisticsJob(container: MedusaContainer): Promise<void>;
4
+ export declare const config: {
5
+ name: string;
6
+ schedule: string;
7
+ };