@endora-commerce/mod-carts 0.100.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.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/admin/components/CartApprovalPolicyPanel.d.ts +51 -0
- package/dist/admin/components/CartApprovalPolicyPanel.d.ts.map +1 -0
- package/dist/admin/components/CartApprovalPolicyPanel.js +59 -0
- package/dist/admin/components/CartApprovalPolicyPanel.js.map +1 -0
- package/dist/admin/index.d.ts +38 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +73 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/CartDetail.d.ts +3 -0
- package/dist/admin/pages/CartDetail.d.ts.map +1 -0
- package/dist/admin/pages/CartDetail.js +74 -0
- package/dist/admin/pages/CartDetail.js.map +1 -0
- package/dist/admin/pages/CartsList.d.ts +3 -0
- package/dist/admin/pages/CartsList.d.ts.map +1 -0
- package/dist/admin/pages/CartsList.js +90 -0
- package/dist/admin/pages/CartsList.js.map +1 -0
- package/dist/admin/zones/CartApprovalPolicy.d.ts +29 -0
- package/dist/admin/zones/CartApprovalPolicy.d.ts.map +1 -0
- package/dist/admin/zones/CartApprovalPolicy.js +11 -0
- package/dist/admin/zones/CartApprovalPolicy.js.map +1 -0
- package/dist/backend/cli/abandonment-sweep.d.ts +64 -0
- package/dist/backend/cli/abandonment-sweep.d.ts.map +1 -0
- package/dist/backend/cli/abandonment-sweep.js +17 -0
- package/dist/backend/cli/abandonment-sweep.js.map +1 -0
- package/dist/backend/entities/cart-audit-entry.entity.d.ts +29 -0
- package/dist/backend/entities/cart-audit-entry.entity.d.ts.map +1 -0
- package/dist/backend/entities/cart-audit-entry.entity.js +109 -0
- package/dist/backend/entities/cart-audit-entry.entity.js.map +1 -0
- package/dist/backend/entities/cart-item.entity.d.ts +42 -0
- package/dist/backend/entities/cart-item.entity.d.ts.map +1 -0
- package/dist/backend/entities/cart-item.entity.js +119 -0
- package/dist/backend/entities/cart-item.entity.js.map +1 -0
- package/dist/backend/entities/cart.entity.d.ts +96 -0
- package/dist/backend/entities/cart.entity.d.ts.map +1 -0
- package/dist/backend/entities/cart.entity.js +207 -0
- package/dist/backend/entities/cart.entity.js.map +1 -0
- package/dist/backend/index.d.ts +122 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +184 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +31 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +95 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.d.ts +101 -0
- package/dist/backend/routes.d.ts.map +1 -0
- package/dist/backend/routes.js +620 -0
- package/dist/backend/routes.js.map +1 -0
- package/dist/backend/routes.organization.d.ts +29 -0
- package/dist/backend/routes.organization.d.ts.map +1 -0
- package/dist/backend/routes.organization.js +150 -0
- package/dist/backend/routes.organization.js.map +1 -0
- package/dist/backend/services/cart-abandonment-settings.d.ts +34 -0
- package/dist/backend/services/cart-abandonment-settings.d.ts.map +1 -0
- package/dist/backend/services/cart-abandonment-settings.js +55 -0
- package/dist/backend/services/cart-abandonment-settings.js.map +1 -0
- package/dist/backend/services/cart-abandonment-worker.d.ts +110 -0
- package/dist/backend/services/cart-abandonment-worker.d.ts.map +1 -0
- package/dist/backend/services/cart-abandonment-worker.js +185 -0
- package/dist/backend/services/cart-abandonment-worker.js.map +1 -0
- package/dist/backend/services/cart-admin-service.d.ts +58 -0
- package/dist/backend/services/cart-admin-service.d.ts.map +1 -0
- package/dist/backend/services/cart-admin-service.js +397 -0
- package/dist/backend/services/cart-admin-service.js.map +1 -0
- package/dist/backend/services/cart-approval-service.d.ts +147 -0
- package/dist/backend/services/cart-approval-service.d.ts.map +1 -0
- package/dist/backend/services/cart-approval-service.js +242 -0
- package/dist/backend/services/cart-approval-service.js.map +1 -0
- package/dist/backend/services/cart-audit-service.d.ts +75 -0
- package/dist/backend/services/cart-audit-service.d.ts.map +1 -0
- package/dist/backend/services/cart-audit-service.js +70 -0
- package/dist/backend/services/cart-audit-service.js.map +1 -0
- package/dist/backend/services/cart-conversion-service.d.ts +104 -0
- package/dist/backend/services/cart-conversion-service.d.ts.map +1 -0
- package/dist/backend/services/cart-conversion-service.js +175 -0
- package/dist/backend/services/cart-conversion-service.js.map +1 -0
- package/dist/backend/services/cart-coupon-service.d.ts +129 -0
- package/dist/backend/services/cart-coupon-service.d.ts.map +1 -0
- package/dist/backend/services/cart-coupon-service.js +244 -0
- package/dist/backend/services/cart-coupon-service.js.map +1 -0
- package/dist/backend/services/cart-organization-visibility-service.d.ts +43 -0
- package/dist/backend/services/cart-organization-visibility-service.d.ts.map +1 -0
- package/dist/backend/services/cart-organization-visibility-service.js +98 -0
- package/dist/backend/services/cart-organization-visibility-service.js.map +1 -0
- package/dist/backend/services/cart-placement-apply-port.d.ts +38 -0
- package/dist/backend/services/cart-placement-apply-port.d.ts.map +1 -0
- package/dist/backend/services/cart-placement-apply-port.js +71 -0
- package/dist/backend/services/cart-placement-apply-port.js.map +1 -0
- package/dist/backend/services/cart-pricing-recompute.d.ts +62 -0
- package/dist/backend/services/cart-pricing-recompute.d.ts.map +1 -0
- package/dist/backend/services/cart-pricing-recompute.js +131 -0
- package/dist/backend/services/cart-pricing-recompute.js.map +1 -0
- package/dist/backend/services/cart-query-service.d.ts +29 -0
- package/dist/backend/services/cart-query-service.d.ts.map +1 -0
- package/dist/backend/services/cart-query-service.js +40 -0
- package/dist/backend/services/cart-query-service.js.map +1 -0
- package/dist/backend/services/cart-read-port.d.ts +40 -0
- package/dist/backend/services/cart-read-port.d.ts.map +1 -0
- package/dist/backend/services/cart-read-port.js +144 -0
- package/dist/backend/services/cart-read-port.js.map +1 -0
- package/dist/backend/services/cart-recompute-cache.d.ts +49 -0
- package/dist/backend/services/cart-recompute-cache.d.ts.map +1 -0
- package/dist/backend/services/cart-recompute-cache.js +56 -0
- package/dist/backend/services/cart-recompute-cache.js.map +1 -0
- package/dist/backend/services/cart-service.d.ts +165 -0
- package/dist/backend/services/cart-service.d.ts.map +1 -0
- package/dist/backend/services/cart-service.js +556 -0
- package/dist/backend/services/cart-service.js.map +1 -0
- package/dist/backend/services/cart-state-machine.d.ts +51 -0
- package/dist/backend/services/cart-state-machine.d.ts.map +1 -0
- package/dist/backend/services/cart-state-machine.js +74 -0
- package/dist/backend/services/cart-state-machine.js.map +1 -0
- package/dist/backend/services/cart-upsell-service.d.ts +57 -0
- package/dist/backend/services/cart-upsell-service.d.ts.map +1 -0
- package/dist/backend/services/cart-upsell-service.js +100 -0
- package/dist/backend/services/cart-upsell-service.js.map +1 -0
- package/dist/backend/services/customer-group-resolver.d.ts +27 -0
- package/dist/backend/services/customer-group-resolver.d.ts.map +1 -0
- package/dist/backend/services/customer-group-resolver.js +32 -0
- package/dist/backend/services/customer-group-resolver.js.map +1 -0
- package/dist/manifest.d.ts +221 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +224 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260611T140352_carts_consolidation.d.ts +43 -0
- package/dist/migrations/20260611T140352_carts_consolidation.d.ts.map +1 -0
- package/dist/migrations/20260611T140352_carts_consolidation.js +237 -0
- package/dist/migrations/20260611T140352_carts_consolidation.js.map +1 -0
- package/dist/migrations/20260611T140413_carts_cart_item_packaging.d.ts +12 -0
- package/dist/migrations/20260611T140413_carts_cart_item_packaging.d.ts.map +1 -0
- package/dist/migrations/20260611T140413_carts_cart_item_packaging.js +20 -0
- package/dist/migrations/20260611T140413_carts_cart_item_packaging.js.map +1 -0
- package/dist/migrations/20260818T081253_carts_cart_completed_order_fk.d.ts +50 -0
- package/dist/migrations/20260818T081253_carts_cart_completed_order_fk.d.ts.map +1 -0
- package/dist/migrations/20260818T081253_carts_cart_completed_order_fk.js +62 -0
- package/dist/migrations/20260818T081253_carts_cart_completed_order_fk.js.map +1 -0
- package/dist/migrations/20260830T112911_carts_organization_attribution_check.d.ts +67 -0
- package/dist/migrations/20260830T112911_carts_organization_attribution_check.d.ts.map +1 -0
- package/dist/migrations/20260830T112911_carts_organization_attribution_check.js +121 -0
- package/dist/migrations/20260830T112911_carts_organization_attribution_check.js.map +1 -0
- package/dist/migrations/index.d.ts +30 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +35 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/ports/index.d.ts +106 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +2 -0
- package/dist/ports/index.js.map +1 -0
- package/docs/carts.md +232 -0
- package/i18n/en.json +96 -0
- package/i18n/pl.json +96 -0
- package/package.json +107 -0
- package/tailwind.css +14 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { adminCartsListQuerySchema, adminRejectCartSchema, setCartApprovalPolicySchema, ERROR_CODES, } from '@endora-commerce/contracts';
|
|
2
|
+
import { HttpError } from '@endora-commerce/platform/http';
|
|
3
|
+
export async function registerCartsAdminRoutes(app, deps) {
|
|
4
|
+
const { cartAdminService, requireAdmin, resolveAdminUserId } = deps;
|
|
5
|
+
app.get('/api/v1/admin/carts', { preHandler: requireAdmin('carts:read') }, async (request) => {
|
|
6
|
+
const raw = (request.query ?? {});
|
|
7
|
+
// Fastify query parser delivers repeated keys as arrays; explicit
|
|
8
|
+
// status / approvalStatus are accepted as comma-separated strings
|
|
9
|
+
// too for ergonomic curl use.
|
|
10
|
+
const normalised = { ...raw };
|
|
11
|
+
for (const arrKey of ['status', 'approvalStatus']) {
|
|
12
|
+
const v = normalised[arrKey];
|
|
13
|
+
if (typeof v === 'string') {
|
|
14
|
+
normalised[arrKey] = v.split(',').filter((s) => s.length > 0);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const parsed = adminCartsListQuerySchema.parse(normalised);
|
|
18
|
+
return cartAdminService.list(parsed);
|
|
19
|
+
});
|
|
20
|
+
app.get('/api/v1/admin/carts/:id', { preHandler: requireAdmin('carts:read') }, async (request) => {
|
|
21
|
+
return cartAdminService.getById(request.params.id);
|
|
22
|
+
});
|
|
23
|
+
app.get('/api/v1/admin/carts/:id/audit', { preHandler: requireAdmin('carts:read') }, async (request) => {
|
|
24
|
+
const page = request.query.page ? Math.max(1, Number.parseInt(request.query.page, 10)) : 1;
|
|
25
|
+
const pageSize = request.query.pageSize
|
|
26
|
+
? Math.max(1, Math.min(200, Number.parseInt(request.query.pageSize, 10)))
|
|
27
|
+
: 50;
|
|
28
|
+
return cartAdminService.getAudit(request.params.id, page, pageSize);
|
|
29
|
+
});
|
|
30
|
+
app.post('/api/v1/admin/carts/:id/reject', {
|
|
31
|
+
preHandler: requireAdmin('carts:reject'),
|
|
32
|
+
schema: { body: adminRejectCartSchema },
|
|
33
|
+
}, async (request) => {
|
|
34
|
+
const adminUserId = resolveAdminUserId(request);
|
|
35
|
+
if (!adminUserId) {
|
|
36
|
+
throw new HttpError(401, ERROR_CODES.UNAUTHORIZED, 'Admin session required.');
|
|
37
|
+
}
|
|
38
|
+
const body = adminRejectCartSchema.parse(request.body);
|
|
39
|
+
return cartAdminService.reject(request.params.id, adminUserId, body.reason);
|
|
40
|
+
});
|
|
41
|
+
/**
|
|
42
|
+
* Feature 027 US4 — admin proxy for the per-Organization
|
|
43
|
+
* `requires_cart_approval` policy. Same semantics as the Org-Admin
|
|
44
|
+
* self-service route under `/api/v1/organization/policies/cart-approval`
|
|
45
|
+
* but the actor is a platform admin (and consequently the audit
|
|
46
|
+
* row's actor_type is `platform_admin`).
|
|
47
|
+
*/
|
|
48
|
+
if (deps.cartApprovalService) {
|
|
49
|
+
/**
|
|
50
|
+
* The read half, added by feature 091's P7b
|
|
51
|
+
* (`contracts/admin-component-contribution.md` §10.5).
|
|
52
|
+
*
|
|
53
|
+
* This module owned the `PATCH` and no `GET`, so the panel that rendered
|
|
54
|
+
* the toggle took its initial value as a prop from `organizations`' detail
|
|
55
|
+
* payload. As an `organization.detail.after` contribution it has no such
|
|
56
|
+
* prop — the other three contributors want neither it nor the request — so
|
|
57
|
+
* it reads its own state here.
|
|
58
|
+
*
|
|
59
|
+
* **`customers:manage`, the same code as the `PATCH`**, so read and write
|
|
60
|
+
* agree on one code: an operator who can see the toggle can use it, which
|
|
61
|
+
* is what a contribution's `requiredPermission` exists to guarantee. The
|
|
62
|
+
* response is the `PATCH`'s own `cartApprovalPolicyResponseSchema` shape,
|
|
63
|
+
* for the same reason one code is better than two.
|
|
64
|
+
*/
|
|
65
|
+
app.get('/api/v1/admin/organizations/:id/cart-approval-policy', { preHandler: requireAdmin('customers:manage') }, async (request) => {
|
|
66
|
+
const org = await deps.cartApprovalService.getPolicyByAdmin(request.params.id);
|
|
67
|
+
return {
|
|
68
|
+
data: {
|
|
69
|
+
organizationId: org.id,
|
|
70
|
+
requiresCartApproval: org.requiresCartApproval,
|
|
71
|
+
updatedAt: org.updatedAt.toISOString(),
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
app.patch('/api/v1/admin/organizations/:id/cart-approval-policy', {
|
|
76
|
+
preHandler: requireAdmin('customers:manage'),
|
|
77
|
+
schema: { body: setCartApprovalPolicySchema },
|
|
78
|
+
}, async (request) => {
|
|
79
|
+
const adminUserId = resolveAdminUserId(request);
|
|
80
|
+
if (!adminUserId) {
|
|
81
|
+
throw new HttpError(401, ERROR_CODES.UNAUTHORIZED, 'Admin session required.');
|
|
82
|
+
}
|
|
83
|
+
const body = setCartApprovalPolicySchema.parse(request.body);
|
|
84
|
+
const org = await deps.cartApprovalService.setPolicyByAdmin(request.params.id, adminUserId, body.requiresCartApproval);
|
|
85
|
+
return {
|
|
86
|
+
data: {
|
|
87
|
+
organizationId: org.id,
|
|
88
|
+
requiresCartApproval: org.requiresCartApproval,
|
|
89
|
+
updatedAt: org.updatedAt.toISOString(),
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=routes.admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.admin.js","sourceRoot":"","sources":["../../src/backend/routes.admin.ts"],"names":[],"mappings":"AACA,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,2BAA2B,EAC3B,WAAW,GACZ,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AA8B3D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,GAAoB,EACpB,IAA0B;IAE1B,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAC;IAEpE,GAAG,CAAC,GAAG,CACL,qBAAqB,EACrB,EAAE,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,EAC1C,KAAK,EAAE,OAAO,EAAE,EAAE;QAChB,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;QAC7D,kEAAkE;QAClE,kEAAkE;QAClE,8BAA8B;QAC9B,MAAM,UAAU,GAA4B,EAAE,GAAG,GAAG,EAAE,CAAC;QACvD,KAAK,MAAM,MAAM,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE,CAAC;YAClD,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YAC7B,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAChE,CAAC;QACH,CAAC;QACD,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC3D,OAAO,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,GAAG,CACL,yBAAyB,EACzB,EAAE,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,EAC1C,KAAK,EAAE,OAAO,EAAE,EAAE;QAChB,OAAO,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrD,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,GAAG,CACL,+BAA+B,EAC/B,EAAE,UAAU,EAAE,YAAY,CAAC,YAAY,CAAC,EAAE,EAC1C,KAAK,EAAE,OAAO,EAAE,EAAE;QAChB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3F,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ;YACrC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;YACzE,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACtE,CAAC,CACF,CAAC;IAEF,GAAG,CAAC,IAAI,CACN,gCAAgC,EAChC;QACE,UAAU,EAAE,YAAY,CAAC,cAAc,CAAC;QACxC,MAAM,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE;KACxC,EACD,KAAK,EAAE,OAAO,EAAE,EAAE;QAChB,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAChD,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,IAAI,GAAG,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvD,OAAO,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC9E,CAAC,CACF,CAAC;IAEF;;;;;;OAMG;IACH,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B;;;;;;;;;;;;;;;WAeG;QACH,GAAG,CAAC,GAAG,CACL,sDAAsD,EACtD,EAAE,UAAU,EAAE,YAAY,CAAC,kBAAkB,CAAC,EAAE,EAChD,KAAK,EAAE,OAAO,EAAE,EAAE;YAChB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,mBAAoB,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAChF,OAAO;gBACL,IAAI,EAAE;oBACJ,cAAc,EAAE,GAAG,CAAC,EAAE;oBACtB,oBAAoB,EAAE,GAAG,CAAC,oBAAoB;oBAC9C,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE;iBACvC;aACF,CAAC;QACJ,CAAC,CACF,CAAC;QAEF,GAAG,CAAC,KAAK,CACP,sDAAsD,EACtD;YACE,UAAU,EAAE,YAAY,CAAC,kBAAkB,CAAC;YAC5C,MAAM,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE;SAC9C,EACD,KAAK,EAAE,OAAO,EAAE,EAAE;YAChB,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;YAChF,CAAC;YACD,MAAM,IAAI,GAAG,2BAA2B,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,mBAAoB,CAAC,gBAAgB,CAC1D,OAAO,CAAC,MAAM,CAAC,EAAE,EACjB,WAAW,EACX,IAAI,CAAC,oBAAoB,CAC1B,CAAC;YACF,OAAO;gBACL,IAAI,EAAE;oBACJ,cAAc,EAAE,GAAG,CAAC,EAAE;oBACtB,oBAAoB,EAAE,GAAG,CAAC,oBAAoB;oBAC9C,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE;iBACvC;aACF,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { FastifyInstance, FastifyRequest } from 'fastify';
|
|
2
|
+
import { type CatalogProductReadPort } from '@endora-commerce/contracts';
|
|
3
|
+
import type { CartService } from './services/cart-service.js';
|
|
4
|
+
import type { CartUpsellService } from './services/cart-upsell-service.js';
|
|
5
|
+
import type { CartCouponService } from './services/cart-coupon-service.js';
|
|
6
|
+
import type { CartConversionService } from './services/cart-conversion-service.js';
|
|
7
|
+
import type { CartPricingRecompute } from './services/cart-pricing-recompute.js';
|
|
8
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
9
|
+
export interface CartsDeps {
|
|
10
|
+
cartService: CartService;
|
|
11
|
+
/**
|
|
12
|
+
* Feature 027 — Up-sell aggregator. Optional so legacy compositions
|
|
13
|
+
* that haven't yet wired the new service still build successfully;
|
|
14
|
+
* production composition (commerceModule) provides it.
|
|
15
|
+
*/
|
|
16
|
+
cartUpsellService?: CartUpsellService;
|
|
17
|
+
/**
|
|
18
|
+
* Feature 027 — pushes a cart line into the buyer's named Purchase
|
|
19
|
+
* List. Cross-module call to ShoppingListService.addItem; optional
|
|
20
|
+
* for the same reason as above.
|
|
21
|
+
*/
|
|
22
|
+
pushLineToShoppingList?: (input: {
|
|
23
|
+
customerAccountId: string;
|
|
24
|
+
organizationId: string | null;
|
|
25
|
+
shoppingListId: string;
|
|
26
|
+
productId: string;
|
|
27
|
+
variantId: string | null;
|
|
28
|
+
quantity: number;
|
|
29
|
+
}) => Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Feature 027 US2 — coupon application service. Optional so legacy
|
|
32
|
+
* compositions still build; production wires it. Also drives the
|
|
33
|
+
* `reevaluateOnRead` auto-drop in the GET handler when a previously-
|
|
34
|
+
* applied code no longer fits the cart.
|
|
35
|
+
*/
|
|
36
|
+
cartCouponService?: CartCouponService;
|
|
37
|
+
/**
|
|
38
|
+
* Feature 027 US3 — three conversions (Cart→QR, QR→Cart, ShoppingList→Cart).
|
|
39
|
+
* Optional so legacy compositions still build.
|
|
40
|
+
*/
|
|
41
|
+
cartConversionService?: CartConversionService;
|
|
42
|
+
/**
|
|
43
|
+
* Feature 027 §R5 — re-pricing on read. When wired, every full-cart
|
|
44
|
+
* read calls the helper to refresh `cart_items.unit_price` from the
|
|
45
|
+
* customer's currently resolved price list (Redis-cached for 30 s).
|
|
46
|
+
* The response uses the recomputed prices; the snapshotted column is
|
|
47
|
+
* kept for audit / diff.
|
|
48
|
+
*/
|
|
49
|
+
cartPricingRecompute?: CartPricingRecompute;
|
|
50
|
+
/**
|
|
51
|
+
* Feature 027 US3 — ShoppingListService.convertToCart bridge for the
|
|
52
|
+
* `POST /api/v1/cart/from-shopping-list/:listId` endpoint. Returns the
|
|
53
|
+
* cart-side append result.
|
|
54
|
+
*/
|
|
55
|
+
appendShoppingListToCart?: (input: {
|
|
56
|
+
customerAccountId: string;
|
|
57
|
+
organizationId: string | null;
|
|
58
|
+
shoppingListId: string;
|
|
59
|
+
}) => Promise<{
|
|
60
|
+
cartId: string;
|
|
61
|
+
appendedLineCount: number;
|
|
62
|
+
droppedLines: Array<{
|
|
63
|
+
productId: string;
|
|
64
|
+
productName: string;
|
|
65
|
+
reason: string;
|
|
66
|
+
}>;
|
|
67
|
+
}>;
|
|
68
|
+
resolveCartActor: (request: FastifyRequest) => {
|
|
69
|
+
customer?: {
|
|
70
|
+
customerAccountId: string;
|
|
71
|
+
organizationId: string | null;
|
|
72
|
+
};
|
|
73
|
+
anonymousToken?: string;
|
|
74
|
+
};
|
|
75
|
+
emFactory: () => EntityManager;
|
|
76
|
+
/**
|
|
77
|
+
* `catalog`'s product read model (feature 075, Phase C). The cart
|
|
78
|
+
* serializer resolves each line's display name, slug and sku from it; it
|
|
79
|
+
* used to `em.find(Product, …)` against `catalog`'s table, so a switched-off
|
|
80
|
+
* `catalog` still named the products on a cart it had stopped serving.
|
|
81
|
+
*/
|
|
82
|
+
catalogProducts: CatalogProductReadPort;
|
|
83
|
+
/**
|
|
84
|
+
* Optional gate — when provided, signed-in customers whose Organization
|
|
85
|
+
* is not `active` (pending_verification / blocked / rejected) cannot add
|
|
86
|
+
* lines to the cart. Anonymous users are always permitted.
|
|
87
|
+
*
|
|
88
|
+
* Feature 026 (US1 / US3). Throws OrganizationCannotTransactError, which
|
|
89
|
+
* the route translates to HTTP 423 with a localized body.
|
|
90
|
+
*/
|
|
91
|
+
assertOrganizationCanTransact?: (organizationId: string) => Promise<void>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Cart routes — open to anonymous users too. The resolver picks the right
|
|
95
|
+
* cart based on (authenticated session, anonymous cookie, neither).
|
|
96
|
+
*
|
|
97
|
+
* Anonymous callers receive a Set-Cookie for `b2b_cart_anon` on first add so
|
|
98
|
+
* later requests target the same cart.
|
|
99
|
+
*/
|
|
100
|
+
export declare function registerCartRoutes(app: FastifyInstance, deps: CartsDeps): Promise<void>;
|
|
101
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/backend/routes.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EASL,KAAK,sBAAsB,EAE5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAEjF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAW3D,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE;QAC/B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,QAAQ,EAAE,MAAM,CAAC;KAClB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE;QACjC,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,cAAc,EAAE,MAAM,CAAC;KACxB,KAAK,OAAO,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,KAAK,CAAC;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACjF,CAAC,CAAC;IACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK;QAC7C,QAAQ,CAAC,EAAE;YAAE,iBAAiB,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,CAAC;QACxE,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,SAAS,EAAE,MAAM,aAAa,CAAC;IAC/B;;;;;OAKG;IACH,eAAe,EAAE,sBAAsB,CAAC;IACxC;;;;;;;OAOG;IACH,6BAA6B,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAqe7F"}
|