@endora-commerce/mod-delivery-methods 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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/admin/api/delivery-methods-client.d.ts +41 -0
  4. package/dist/admin/api/delivery-methods-client.d.ts.map +1 -0
  5. package/dist/admin/api/delivery-methods-client.js +20 -0
  6. package/dist/admin/api/delivery-methods-client.js.map +1 -0
  7. package/dist/admin/index.d.ts +34 -0
  8. package/dist/admin/index.d.ts.map +1 -0
  9. package/dist/admin/index.js +44 -0
  10. package/dist/admin/index.js.map +1 -0
  11. package/dist/admin/pages/DeliveryMethodsPage.d.ts +4 -0
  12. package/dist/admin/pages/DeliveryMethodsPage.d.ts.map +1 -0
  13. package/dist/admin/pages/DeliveryMethodsPage.js +167 -0
  14. package/dist/admin/pages/DeliveryMethodsPage.js.map +1 -0
  15. package/dist/admin/renderers/registry.d.ts +15 -0
  16. package/dist/admin/renderers/registry.d.ts.map +1 -0
  17. package/dist/admin/renderers/registry.js +18 -0
  18. package/dist/admin/renderers/registry.js.map +1 -0
  19. package/dist/backend/adapters/built-in-adapters.d.ts +46 -0
  20. package/dist/backend/adapters/built-in-adapters.d.ts.map +1 -0
  21. package/dist/backend/adapters/built-in-adapters.js +62 -0
  22. package/dist/backend/adapters/built-in-adapters.js.map +1 -0
  23. package/dist/backend/commands/delivery-method.commands.d.ts +61 -0
  24. package/dist/backend/commands/delivery-method.commands.d.ts.map +1 -0
  25. package/dist/backend/commands/delivery-method.commands.js +107 -0
  26. package/dist/backend/commands/delivery-method.commands.js.map +1 -0
  27. package/dist/backend/demo/reset.d.ts +12 -0
  28. package/dist/backend/demo/reset.d.ts.map +1 -0
  29. package/dist/backend/demo/reset.js +13 -0
  30. package/dist/backend/demo/reset.js.map +1 -0
  31. package/dist/backend/demo/rows.d.ts +24 -0
  32. package/dist/backend/demo/rows.d.ts.map +1 -0
  33. package/dist/backend/demo/rows.js +22 -0
  34. package/dist/backend/demo/rows.js.map +1 -0
  35. package/dist/backend/demo/seed.d.ts +14 -0
  36. package/dist/backend/demo/seed.d.ts.map +1 -0
  37. package/dist/backend/demo/seed.js +28 -0
  38. package/dist/backend/demo/seed.js.map +1 -0
  39. package/dist/backend/entities/delivery-method.entity.d.ts +30 -0
  40. package/dist/backend/entities/delivery-method.entity.d.ts.map +1 -0
  41. package/dist/backend/entities/delivery-method.entity.js +91 -0
  42. package/dist/backend/entities/delivery-method.entity.js.map +1 -0
  43. package/dist/backend/index.d.ts +88 -0
  44. package/dist/backend/index.d.ts.map +1 -0
  45. package/dist/backend/index.js +144 -0
  46. package/dist/backend/index.js.map +1 -0
  47. package/dist/backend/routes.d.ts +51 -0
  48. package/dist/backend/routes.d.ts.map +1 -0
  49. package/dist/backend/routes.js +152 -0
  50. package/dist/backend/routes.js.map +1 -0
  51. package/dist/backend/services/delivery-method-read-port.d.ts +25 -0
  52. package/dist/backend/services/delivery-method-read-port.d.ts.map +1 -0
  53. package/dist/backend/services/delivery-method-read-port.js +56 -0
  54. package/dist/backend/services/delivery-method-read-port.js.map +1 -0
  55. package/dist/backend/services/delivery-method-reconciler.d.ts +97 -0
  56. package/dist/backend/services/delivery-method-reconciler.d.ts.map +1 -0
  57. package/dist/backend/services/delivery-method-reconciler.js +157 -0
  58. package/dist/backend/services/delivery-method-reconciler.js.map +1 -0
  59. package/dist/backend/services/order-status-registry.port.d.ts +50 -0
  60. package/dist/backend/services/order-status-registry.port.d.ts.map +1 -0
  61. package/dist/backend/services/order-status-registry.port.js +45 -0
  62. package/dist/backend/services/order-status-registry.port.js.map +1 -0
  63. package/dist/backend/services/registry-singleton.d.ts +20 -0
  64. package/dist/backend/services/registry-singleton.d.ts.map +1 -0
  65. package/dist/backend/services/registry-singleton.js +21 -0
  66. package/dist/backend/services/registry-singleton.js.map +1 -0
  67. package/dist/backend/services/shipment-usage-guard.d.ts +31 -0
  68. package/dist/backend/services/shipment-usage-guard.d.ts.map +1 -0
  69. package/dist/backend/services/shipment-usage-guard.js +33 -0
  70. package/dist/backend/services/shipment-usage-guard.js.map +1 -0
  71. package/dist/backend/services/shipping-adapter-registry.d.ts +98 -0
  72. package/dist/backend/services/shipping-adapter-registry.d.ts.map +1 -0
  73. package/dist/backend/services/shipping-adapter-registry.js +92 -0
  74. package/dist/backend/services/shipping-adapter-registry.js.map +1 -0
  75. package/dist/backend/services/shipping-method-eligibility.d.ts +24 -0
  76. package/dist/backend/services/shipping-method-eligibility.d.ts.map +1 -0
  77. package/dist/backend/services/shipping-method-eligibility.js +46 -0
  78. package/dist/backend/services/shipping-method-eligibility.js.map +1 -0
  79. package/dist/install/index.d.ts +59 -0
  80. package/dist/install/index.d.ts.map +1 -0
  81. package/dist/install/index.js +59 -0
  82. package/dist/install/index.js.map +1 -0
  83. package/dist/manifest.d.ts +193 -0
  84. package/dist/manifest.d.ts.map +1 -0
  85. package/dist/manifest.js +185 -0
  86. package/dist/manifest.js.map +1 -0
  87. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.d.ts +30 -0
  88. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.d.ts.map +1 -0
  89. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.js +72 -0
  90. package/dist/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.js.map +1 -0
  91. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.d.ts +24 -0
  92. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.d.ts.map +1 -0
  93. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.js +28 -0
  94. package/dist/migrations/20260611T140416_delivery_methods_fix_in_person_pickup_adapter.js.map +1 -0
  95. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.d.ts +27 -0
  96. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.d.ts.map +1 -0
  97. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.js +44 -0
  98. package/dist/migrations/20260912T094638_delivery_methods_sales_channel_delivery_methods.js.map +1 -0
  99. package/dist/migrations/index.d.ts +29 -0
  100. package/dist/migrations/index.d.ts.map +1 -0
  101. package/dist/migrations/index.js +33 -0
  102. package/dist/migrations/index.js.map +1 -0
  103. package/dist/ports/index.d.ts +129 -0
  104. package/dist/ports/index.d.ts.map +1 -0
  105. package/dist/ports/index.js +2 -0
  106. package/dist/ports/index.js.map +1 -0
  107. package/docs/delivery_methods.md +197 -0
  108. package/i18n/en.json +5 -0
  109. package/i18n/pl.json +5 -0
  110. package/package.json +100 -0
  111. package/tailwind.css +14 -0
@@ -0,0 +1,46 @@
1
+ export class ShippingMethodEligibilityService {
2
+ registry;
3
+ constructor(registry) {
4
+ this.registry = registry;
5
+ }
6
+ async filter(methods, ctx) {
7
+ const eligible = [];
8
+ for (const m of methods) {
9
+ if (m.status !== 'active')
10
+ continue;
11
+ const adapter = this.registry.get(m.adapter);
12
+ if (!adapter)
13
+ continue; // unregistered adapter ⇒ not offered (FR-003)
14
+ const eligCtx = {
15
+ deliveryMethod: {
16
+ id: m.id,
17
+ code: m.code,
18
+ adapter: m.adapter,
19
+ name: m.name,
20
+ cost: { amount: Number(m.cost), currency: m.currency },
21
+ status: m.status,
22
+ statusOnSuccess: m.statusOnSuccess,
23
+ statusOnFailure: m.statusOnFailure,
24
+ salesChannelIds: [],
25
+ rendererKey: adapter.renderers?.storefront ?? null,
26
+ },
27
+ // Issue #103 — passed through, `null` included. See the payment twin:
28
+ // `?? ''` is not a spelling of "platform-wide", it is a value the
29
+ // settings seam guard rejects.
30
+ salesChannelId: ctx.salesChannelId,
31
+ organizationId: ctx.organizationId,
32
+ customerAccountId: ctx.customerAccountId,
33
+ surface: ctx.surface,
34
+ };
35
+ const ok = ctx.surface === 'admin'
36
+ ? await adapter.validateUseOnAdmin(eligCtx)
37
+ : ctx.surface === 'api'
38
+ ? await adapter.validateUseInApi(eligCtx)
39
+ : await adapter.validateUseOnStorefront(eligCtx);
40
+ if (ok)
41
+ eligible.push(m);
42
+ }
43
+ return eligible;
44
+ }
45
+ }
46
+ //# sourceMappingURL=shipping-method-eligibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shipping-method-eligibility.js","sourceRoot":"","sources":["../../../src/backend/services/shipping-method-eligibility.ts"],"names":[],"mappings":"AAoBA,MAAM,OAAO,gCAAgC;IACd;IAA7B,YAA6B,QAAiC;QAAjC,aAAQ,GAAR,QAAQ,CAAyB;IAAG,CAAC;IAElE,KAAK,CAAC,MAAM,CACV,OAAyB,EACzB,GAA+B;QAE/B,MAAM,QAAQ,GAAqB,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ;gBAAE,SAAS;YACpC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC7C,IAAI,CAAC,OAAO;gBAAE,SAAS,CAAC,8CAA8C;YAEtE,MAAM,OAAO,GAAG;gBACd,cAAc,EAAE;oBACd,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;oBACtD,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,eAAe,EAAE,CAAC,CAAC,eAAe;oBAClC,eAAe,EAAE,CAAC,CAAC,eAAe;oBAClC,eAAe,EAAE,EAAc;oBAC/B,WAAW,EAAE,OAAO,CAAC,SAAS,EAAE,UAAU,IAAI,IAAI;iBACnD;gBACD,sEAAsE;gBACtE,kEAAkE;gBAClE,+BAA+B;gBAC/B,cAAc,EAAE,GAAG,CAAC,cAAc;gBAClC,cAAc,EAAE,GAAG,CAAC,cAAc;gBAClC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;gBACxC,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC;YAEF,MAAM,EAAE,GACN,GAAG,CAAC,OAAO,KAAK,OAAO;gBACrB,CAAC,CAAC,MAAM,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC;gBAC3C,CAAC,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK;oBACrB,CAAC,CAAC,MAAM,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC;oBACzC,CAAC,CAAC,MAAM,OAAO,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;YACvD,IAAI,EAAE;gBAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The **install surface** this module publishes: one factory, on a subpath whose
3
+ * declared meaning is foreign consumption (feature 134, FR-064;
4
+ * `module-package-layout.md` R11).
5
+ *
6
+ * A module that ships its own carrier seeds its `delivery_methods` row from its
7
+ * `installHook` through `createDeliveryMethodSeeder()`, handing `ctx.em` to every
8
+ * call; the interface it returns is published type-only on this package's
9
+ * `./ports`. `inpost`, `dhl_parcel` and the example deployment's
10
+ * `carrier_fixture` are its three consumers today, and wave 2 gives
11
+ * `payment_methods` the twin surface for five payment gateways.
12
+ *
13
+ * ## Why this is a subpath of its own rather than a line on `./backend`
14
+ *
15
+ * Three reasons, and the checker is not one of them.
16
+ *
17
+ * **The npm edge coincides with a declared lifecycle dependency rather than
18
+ * substituting for one.** R4 in `backend/scripts/lib/module-package-manifest.ts`
19
+ * refuses a module package importing another because a package edge is one *"the
20
+ * lifecycle, the migration order and an operator switching the owner off all know
21
+ * nothing about"* — D-11 rule 3's mirror false positive. Both carriers already
22
+ * declare `dependencies: ['…', 'delivery_methods', '…']` in their manifests, so
23
+ * the lifecycle, the migration order and the operator's switch all know about this
24
+ * edge; the npm declaration says the same thing a second way, in the only
25
+ * vocabulary a published tarball has. That is what puts this seam **inside** R4's
26
+ * reason rather than beside it.
27
+ *
28
+ * **`./backend` is deliberately discriminating and must stay so.**
29
+ * `module-package-layout.md` R7: after D-168, *"every reach into `<pkg>/backend`
30
+ * really is a wiring reach"*. A factory there would make one subpath mean either
31
+ * "this consumer is wiring `delivery_methods`", a real Principle I violation, or
32
+ * "this consumer seeds its own row through the sanctioned surface" — two findings
33
+ * with opposite remedies behind one name, for as many modules as adopt the seam.
34
+ *
35
+ * **The import is evaluated at every boot, and it is measured.**
36
+ * `manifest-index.generated.ts` imports every module's manifest statically and
37
+ * eagerly, in the server, the CLI and every worker — so a consumer's `installHook`
38
+ * is *called* at install and its `import` is *loaded* at boot. Measured on the
39
+ * emitted artefact, and both measurement points are given because the split moved
40
+ * one of them: with the factory on the barrel, `dist/backend/index.js` pulled **12
41
+ * emitted files and 7 external specifiers**, `@endora-commerce/platform/http`
42
+ * among them; after the split it pulls **11 and 7**, because the reconciler left
43
+ * it, and `dist/install/index.js` pulls **3 and 4 — this file, the reconciler, the
44
+ * entity — with no HTTP layer**. So a consumer that had to name the barrel loaded
45
+ * twelve modules and the HTTP layer where it now loads three and none of it,
46
+ * per process, for as many modules as adopt the seam.
47
+ *
48
+ * ## It is a pure re-export, and that is a rule
49
+ *
50
+ * No behaviour is added here and none may be. The install hook is **not** inside a
51
+ * database transaction — measured: a hook that threw half-way left the first of
52
+ * two seeded rows behind and never wrote the second — so every behaviour placed on
53
+ * this path is a new partial-write surface. The write stays in
54
+ * `../backend/services/delivery-method-reconciler.ts`, where its tests, its
55
+ * `command-coverage-ignore` classification and its Constitution XIII reasoning
56
+ * already live.
57
+ */
58
+ export { createDeliveryMethodSeeder } from '../backend/services/delivery-method-reconciler.js';
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,EAAE,0BAA0B,EAAE,MAAM,mDAAmD,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The **install surface** this module publishes: one factory, on a subpath whose
3
+ * declared meaning is foreign consumption (feature 134, FR-064;
4
+ * `module-package-layout.md` R11).
5
+ *
6
+ * A module that ships its own carrier seeds its `delivery_methods` row from its
7
+ * `installHook` through `createDeliveryMethodSeeder()`, handing `ctx.em` to every
8
+ * call; the interface it returns is published type-only on this package's
9
+ * `./ports`. `inpost`, `dhl_parcel` and the example deployment's
10
+ * `carrier_fixture` are its three consumers today, and wave 2 gives
11
+ * `payment_methods` the twin surface for five payment gateways.
12
+ *
13
+ * ## Why this is a subpath of its own rather than a line on `./backend`
14
+ *
15
+ * Three reasons, and the checker is not one of them.
16
+ *
17
+ * **The npm edge coincides with a declared lifecycle dependency rather than
18
+ * substituting for one.** R4 in `backend/scripts/lib/module-package-manifest.ts`
19
+ * refuses a module package importing another because a package edge is one *"the
20
+ * lifecycle, the migration order and an operator switching the owner off all know
21
+ * nothing about"* — D-11 rule 3's mirror false positive. Both carriers already
22
+ * declare `dependencies: ['…', 'delivery_methods', '…']` in their manifests, so
23
+ * the lifecycle, the migration order and the operator's switch all know about this
24
+ * edge; the npm declaration says the same thing a second way, in the only
25
+ * vocabulary a published tarball has. That is what puts this seam **inside** R4's
26
+ * reason rather than beside it.
27
+ *
28
+ * **`./backend` is deliberately discriminating and must stay so.**
29
+ * `module-package-layout.md` R7: after D-168, *"every reach into `<pkg>/backend`
30
+ * really is a wiring reach"*. A factory there would make one subpath mean either
31
+ * "this consumer is wiring `delivery_methods`", a real Principle I violation, or
32
+ * "this consumer seeds its own row through the sanctioned surface" — two findings
33
+ * with opposite remedies behind one name, for as many modules as adopt the seam.
34
+ *
35
+ * **The import is evaluated at every boot, and it is measured.**
36
+ * `manifest-index.generated.ts` imports every module's manifest statically and
37
+ * eagerly, in the server, the CLI and every worker — so a consumer's `installHook`
38
+ * is *called* at install and its `import` is *loaded* at boot. Measured on the
39
+ * emitted artefact, and both measurement points are given because the split moved
40
+ * one of them: with the factory on the barrel, `dist/backend/index.js` pulled **12
41
+ * emitted files and 7 external specifiers**, `@endora-commerce/platform/http`
42
+ * among them; after the split it pulls **11 and 7**, because the reconciler left
43
+ * it, and `dist/install/index.js` pulls **3 and 4 — this file, the reconciler, the
44
+ * entity — with no HTTP layer**. So a consumer that had to name the barrel loaded
45
+ * twelve modules and the HTTP layer where it now loads three and none of it,
46
+ * per process, for as many modules as adopt the seam.
47
+ *
48
+ * ## It is a pure re-export, and that is a rule
49
+ *
50
+ * No behaviour is added here and none may be. The install hook is **not** inside a
51
+ * database transaction — measured: a hook that threw half-way left the first of
52
+ * two seeded rows behind and never wrote the second — so every behaviour placed on
53
+ * this path is a new partial-write surface. The write stays in
54
+ * `../backend/services/delivery-method-reconciler.ts`, where its tests, its
55
+ * `command-coverage-ignore` classification and its Constitution XIII reasoning
56
+ * already live.
57
+ */
58
+ export { createDeliveryMethodSeeder } from '../backend/services/delivery-method-reconciler.js';
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/install/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,EAAE,0BAA0B,EAAE,MAAM,mDAAmD,CAAC"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Delivery Methods module — manifest backfill (Module Lifecycle, feature 018);
3
+ * the shipping-method adapter framework host (feature 035).
4
+ *
5
+ * Predates the lifecycle system; the core module's schema is owned by
6
+ * platform-wide migrations (delivery_methods table + feature-035 columns in
7
+ * migration 052). The core module itself has no install/uninstall hook.
8
+ *
9
+ * Recognition condition (feature 035, FR-001): a *separate* platform module is
10
+ * recognised as a shipping-method adapter iff it registers a `ShippingAdapter`
11
+ * in the process-wide `shippingAdapterRegistry` (see
12
+ * services/registry-singleton.ts) from its **boot hook**, naming itself as the
13
+ * contributing module. Not from `installHook`: the registry is an in-memory
14
+ * table per process, install runs once in the CLI process, and the serving
15
+ * process reads what its own composition pushed.
16
+ *
17
+ * The `delivery_methods` **row** is the other half, and since feature 134's
18
+ * FR-064 it is written from the contributing module's `installHook` through this
19
+ * module's published install surface — `createDeliveryMethodSeeder()` on
20
+ * `./backend`, typed by `DeliveryMethodSeedApi` on `./ports`. It used to ship as
21
+ * that module's own migration, which was an `insert` into this module's table
22
+ * from another module's migration: three `migration-foreign-writes` ledger keys,
23
+ * and once the seeding module lives in another repository, a schema dependency
24
+ * with no version range and no compile-time signal
25
+ * (`specs/134-paid-module-extraction/contracts/foreign-write-repair.md`).
26
+ *
27
+ * No `uninstallHook` withdraws the adapter, and none should: the registry
28
+ * records the contributing module on every entry and filters its enumeration on
29
+ * that module's effective state, so an absent contributor is answered at the
30
+ * read. The row and its Shipments are preserved either way (FR-003). See
31
+ * docs/docs/modules/delivery_methods.md § *When the registry is read*.
32
+ */
33
+ export declare const manifest: {
34
+ id: string;
35
+ name: string;
36
+ version: string;
37
+ dependencies: string[];
38
+ description?: string | undefined;
39
+ acknowledgedDependencies?: {
40
+ moduleId: string;
41
+ port: string;
42
+ reason: string;
43
+ }[] | undefined;
44
+ nonBindingDependencies?: {
45
+ moduleId: string;
46
+ name: string;
47
+ kind: "contributes-to" | "degrades-without" | "refuses-without";
48
+ reason: string;
49
+ whenAbsent?: string | undefined;
50
+ }[] | undefined;
51
+ activation?: {
52
+ settingCode: string;
53
+ default: boolean;
54
+ } | {
55
+ nonDeactivatable: true;
56
+ reason: string;
57
+ } | undefined;
58
+ settings?: {
59
+ moduleCode: string;
60
+ groups: {
61
+ code: string;
62
+ name: string;
63
+ salesChannelCodes?: string[] | undefined;
64
+ isSystemProtected?: boolean | undefined;
65
+ }[];
66
+ settings: {
67
+ code: string;
68
+ name: string;
69
+ valueType: "string" | "number" | "boolean" | "json" | "string_list" | "secret" | "credential_ref";
70
+ defaultValue: unknown;
71
+ description?: string | undefined;
72
+ groupCode?: string | undefined;
73
+ previousDefaultValues?: unknown[] | undefined;
74
+ salesChannelCodes?: string[] | undefined;
75
+ enumOptions?: string[] | undefined;
76
+ configurationType?: string | undefined;
77
+ hidden?: boolean | undefined;
78
+ }[];
79
+ } | undefined;
80
+ i18n?: {
81
+ bundlesDir: string;
82
+ } | undefined;
83
+ docs?: false | {
84
+ dir: string;
85
+ } | undefined;
86
+ demo?: false | {
87
+ summary: string;
88
+ seed: (context: import("@endora-commerce/contracts").ModuleDemoContext<never>) => Promise<import("@endora-commerce/contracts").DemoSeedResult>;
89
+ reset: (context: import("@endora-commerce/contracts").ModuleDemoContext<never>) => Promise<import("@endora-commerce/contracts").DemoResetResult>;
90
+ after?: readonly string[] | undefined;
91
+ package?: string | undefined;
92
+ } | undefined;
93
+ actions?: {
94
+ id: string;
95
+ labelKey: string;
96
+ icon: "Plus" | "Sparkles" | "Settings" | "Search" | "Boxes" | "Layers" | "Menu" | "PlusCircle" | "PlusSquare" | "FilePlus" | "FolderPlus" | "Upload" | "FileUp" | "CloudUpload" | "Download" | "FileDown" | "FileText" | "BookOpen" | "Rss" | "Package" | "Tag" | "ShoppingCart" | "Receipt" | "CreditCard" | "Users" | "UserPlus" | "Inbox" | "ListChecks" | "ClipboardList" | "Image" | "Video" | "LayoutDashboard" | "PanelLeft" | "KeyRound" | "ShieldCheck" | "Edit" | "Archive" | "Box" | "Truck" | "CircleDollarSign" | "Activity" | "LineChart" | "Smartphone" | "Webhook" | "Scale" | "PlugZap" | "PercentDiamond" | "Newspaper" | "Languages" | "Eraser" | "Warehouse" | "TrendingDown" | "Bell" | "PackageOpen" | "Building2" | "Store" | "ClipboardCheck";
97
+ targetRoute: string;
98
+ keywords: string[];
99
+ weight: number;
100
+ descriptionKey?: string | undefined;
101
+ requiredPermission?: string | undefined;
102
+ }[] | undefined;
103
+ permissions?: {
104
+ code: string;
105
+ label: string;
106
+ module?: string | undefined;
107
+ description?: string | undefined;
108
+ requires?: string[] | undefined;
109
+ }[] | undefined;
110
+ transactionalEmails?: {
111
+ code: string;
112
+ name: string;
113
+ variables: {
114
+ key: string;
115
+ label: string;
116
+ sampleValue?: string | undefined;
117
+ description?: string | undefined;
118
+ }[];
119
+ description?: string | undefined;
120
+ group?: string | undefined;
121
+ }[] | undefined;
122
+ capabilities?: string[] | undefined;
123
+ exclusiveCapabilities?: {
124
+ key: string;
125
+ errorCode: string;
126
+ }[] | undefined;
127
+ errorCodes?: {
128
+ code: string;
129
+ tokens?: string[] | undefined;
130
+ }[] | undefined;
131
+ blocks?: {
132
+ name: string;
133
+ labelKey: string;
134
+ category: string;
135
+ contexts: ("invoice" | "email" | "cms" | "newsletter")[];
136
+ fields: Record<string, {
137
+ type: "number" | "object" | "array" | "uuid" | "text" | "textarea" | "select" | "radio" | "external" | "richtext";
138
+ label?: string | undefined;
139
+ required?: boolean | undefined;
140
+ options?: {
141
+ label: string;
142
+ value: string | number;
143
+ }[] | undefined;
144
+ refKind?: string | undefined;
145
+ }>;
146
+ descriptionKey?: string | undefined;
147
+ defaultProps?: Record<string, unknown> | undefined;
148
+ responsiveFields?: string[] | undefined;
149
+ previewIcon?: string | undefined;
150
+ weight?: number | undefined;
151
+ }[] | undefined;
152
+ blockCategories?: {
153
+ key: string;
154
+ titleKey: string;
155
+ contexts: ("invoice" | "email" | "cms" | "newsletter")[];
156
+ weight?: number | undefined;
157
+ visible?: boolean | undefined;
158
+ }[] | undefined;
159
+ env?: {
160
+ name: string;
161
+ describes: {
162
+ en: string;
163
+ pl: string;
164
+ };
165
+ requirement: {
166
+ kind: "required";
167
+ } | {
168
+ kind: "requiredWhen";
169
+ input: string;
170
+ equals: string;
171
+ } | {
172
+ kind: "optional";
173
+ without: {
174
+ en: string;
175
+ pl: string;
176
+ };
177
+ };
178
+ secret: boolean;
179
+ generable: boolean;
180
+ owner: {
181
+ kind: "platform";
182
+ } | {
183
+ kind: "application";
184
+ application: "admin" | "backend" | "storefront";
185
+ } | {
186
+ kind: "module";
187
+ moduleId: string;
188
+ };
189
+ consumers: ("admin" | "backend" | "storefront")[];
190
+ addressOf: "admin" | "backend" | "storefront" | null;
191
+ }[] | undefined;
192
+ };
193
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuInB,CAAC"}
@@ -0,0 +1,185 @@
1
+ import { defineModuleManifest } from '@endora-commerce/contracts';
2
+ /**
3
+ * The demo data this module owns (feature 113, T220 — contract §1.3).
4
+ *
5
+ * A typed `const` rather than an inline object literal: declared inline the
6
+ * parameter infers from the schema and is `never`, so the author loses
7
+ * `context.ctx: ModuleContext`.
8
+ *
9
+ * Both bodies are reached by a **relative `await import()`** (§1.4), in
10
+ * `cliCommands.run`'s shape and for `cliCommands`' reason: a manifest is loaded
11
+ * by every process that composes the platform and by the check scripts that
12
+ * import the generated index, so a demo body imported at the top of this file
13
+ * would be a service graph pulled into all of them. It needs no `exports`
14
+ * subpath and no `files` entry (§1.5).
15
+ */
16
+ const demo = {
17
+ summary: 'A free in-person pickup method, so the demo shop can be checked out.',
18
+ seed: async (context) => (await import('./backend/demo/seed.js')).seedDemo(context),
19
+ reset: async (context) => (await import('./backend/demo/reset.js')).resetDemo(context),
20
+ };
21
+ /**
22
+ * Delivery Methods module — manifest backfill (Module Lifecycle, feature 018);
23
+ * the shipping-method adapter framework host (feature 035).
24
+ *
25
+ * Predates the lifecycle system; the core module's schema is owned by
26
+ * platform-wide migrations (delivery_methods table + feature-035 columns in
27
+ * migration 052). The core module itself has no install/uninstall hook.
28
+ *
29
+ * Recognition condition (feature 035, FR-001): a *separate* platform module is
30
+ * recognised as a shipping-method adapter iff it registers a `ShippingAdapter`
31
+ * in the process-wide `shippingAdapterRegistry` (see
32
+ * services/registry-singleton.ts) from its **boot hook**, naming itself as the
33
+ * contributing module. Not from `installHook`: the registry is an in-memory
34
+ * table per process, install runs once in the CLI process, and the serving
35
+ * process reads what its own composition pushed.
36
+ *
37
+ * The `delivery_methods` **row** is the other half, and since feature 134's
38
+ * FR-064 it is written from the contributing module's `installHook` through this
39
+ * module's published install surface — `createDeliveryMethodSeeder()` on
40
+ * `./backend`, typed by `DeliveryMethodSeedApi` on `./ports`. It used to ship as
41
+ * that module's own migration, which was an `insert` into this module's table
42
+ * from another module's migration: three `migration-foreign-writes` ledger keys,
43
+ * and once the seeding module lives in another repository, a schema dependency
44
+ * with no version range and no compile-time signal
45
+ * (`specs/134-paid-module-extraction/contracts/foreign-write-repair.md`).
46
+ *
47
+ * No `uninstallHook` withdraws the adapter, and none should: the registry
48
+ * records the contributing module on every entry and filters its enumeration on
49
+ * that module's effective state, so an absent contributor is answered at the
50
+ * read. The row and its Shipments are preserved either way (FR-003). See
51
+ * docs/docs/modules/delivery_methods.md § *When the registry is read*.
52
+ */
53
+ export const manifest = defineModuleManifest({
54
+ id: 'delivery_methods',
55
+ name: 'Delivery Methods',
56
+ description: 'Shipping/delivery method definitions and per-channel availability.',
57
+ version: '1.0.0',
58
+ // `auth` owns the `requireAdmin` port the admin routes are gated by; the
59
+ // edge became real with the conversion (feature 072, T095).
60
+ // `organizations` since feature 072 (T138) — see the payment twin.
61
+ dependencies: ['auth', 'organizations'],
62
+ /**
63
+ * D-44 — real to the container, binding on no operator (feature 075, the
64
+ * `delivery_methods` boundary shard).
65
+ *
66
+ * `shipments` declares this module, so the ordinary declaration closes a
67
+ * manifest cycle, and acknowledging the edge would put `delivery_methods` —
68
+ * present in every deployment that ships anything — among the dependents that
69
+ * refuse the flip, making shipments permanently unswitchable. The delete
70
+ * guard has a defined behaviour instead: it probes
71
+ * `effectiveState.isPresent('shipments')` before it resolves the port and
72
+ * refuses the delete when the answer is no, so nothing catches
73
+ * `ModuleDisabledError` and the degrade is declared rather than laundered out
74
+ * of a closed gate.
75
+ *
76
+ * Refusing rather than proceeding is the whole point of the entry.
77
+ * `shipments.delivery_method_id` carries no foreign key, so this count is the
78
+ * only thing between a delete and permanently orphaned shipment history — and
79
+ * a switched-off module is exactly when no screen would show the operator
80
+ * that the history exists. Switching a module off is meant to be reversible;
81
+ * a delete taken while it was off is not. Every row, binding and setting stays
82
+ * where it was, so the delete becomes available again the moment shipments
83
+ * comes back.
84
+ */
85
+ nonBindingDependencies: [
86
+ {
87
+ moduleId: 'shipments',
88
+ name: 'shipmentUsagePort',
89
+ kind: 'degrades-without',
90
+ whenAbsent: 'Deleting a delivery method is refused, naming the shipments module. Every other ' +
91
+ 'surface — the catalog, the channel bindings, the storefront list, the writes — is ' +
92
+ 'unaffected.',
93
+ reason: 'The FR-003 delete guard counts the shipments created against a method before it ' +
94
+ 'removes the row, and those rows belong to `shipments`. It was a raw ' +
95
+ '`select count(*) from "shipments"` on this module\'s own transaction until feature ' +
96
+ '075 — a boundary crossing that named no import specifier and so compiled. The ' +
97
+ 'ordinary declaration closes a cycle (`shipments` depends on this module for the ' +
98
+ 'method row, the adapter registry and the order-status registry) and an acknowledged ' +
99
+ 'edge would refuse every attempt to switch shipments off, which is a capability ' +
100
+ 'operators are meant to have.',
101
+ },
102
+ ],
103
+ /**
104
+ * The module's own authority (2026-08-28).
105
+ *
106
+ * All three admin routes used to enforce `catalog:read` / `catalog:write`, so
107
+ * whoever could edit a product could read the delivery-method configuration,
108
+ * rewrite it — which methods a checkout offers, their surcharge, and which
109
+ * order status a shipment outcome moves an order to — and delete a method
110
+ * outright. Both codes were real, declared and enforced, so the permission
111
+ * inventory's two directions were clean over the site, and
112
+ * `check:action-route-permissions` never looked at all: this module declares
113
+ * no manifest action, so the check has nothing of its own to compare.
114
+ *
115
+ * A pair and no third code, spelled `<module id>:<read|write>` like the five
116
+ * gateway modules, `payment_methods`, `returns` and `invoices`. A prefix that
117
+ * is not its owner's id is the mistake `PERMISSION_CATALOGUE` comments on
118
+ * twice (`integrations:manage`, `audit_log:read`), both frozen because they
119
+ * are persisted in role rows; getting it right on a code that does not exist
120
+ * yet is free. The codes stay here rather than in `PERMISSION_CATALOGUE`,
121
+ * which is for codes spanning modules — this module owns these outright.
122
+ *
123
+ * No data migration: see
124
+ * `test/contract/delivery_methods/permission-authority.test.ts`.
125
+ */
126
+ permissions: [
127
+ { code: 'delivery_methods:read', label: 'View delivery methods' },
128
+ { code: 'delivery_methods:write', label: 'Configure delivery methods' },
129
+ ],
130
+ settings: {
131
+ moduleCode: 'delivery_methods',
132
+ groups: [{ code: 'delivery_methods', name: 'Delivery methods' }],
133
+ settings: [
134
+ {
135
+ // Feature 073 — the operator's activation control. Platform-wide.
136
+ code: 'delivery_methods.enabled',
137
+ name: 'Delivery methods enabled',
138
+ // The consequence sentence was missing the same way the payments one
139
+ // was: "the public list a checkout picks from" is accurate and stops
140
+ // short of what it means for the shop. With no method to pick, order
141
+ // placement answers "Delivery method is not active" and no order can be
142
+ // completed at all.
143
+ description: 'Switches the delivery-method catalog on or off: the admin screens that define methods and their per-channel availability, and the public list a checkout picks from. With no method to pick, checkout cannot be completed and the shop stops taking orders. Nothing is dropped — every method, its channel bindings and the shipments already created against it stay in the database, and the catalog returns exactly as configured when you switch it back on.',
144
+ groupCode: 'delivery_methods',
145
+ valueType: 'boolean',
146
+ defaultValue: true,
147
+ },
148
+ ],
149
+ },
150
+ // Feature 073, Amendment A1 (Constitution XVII) — deactivatable, because the
151
+ // reason it used to give does not hold. "The platform cannot take an order"
152
+ // rests on an edge that is not in the graph: `orders` declares `addresses`,
153
+ // `api_keys`, `carts`, `credit_limits`, `organizations`, `promotions`,
154
+ // `settings` and `transactional_emails`, and neither this module nor
155
+ // `payment_methods`. The dependents that do declare it — `payments`,
156
+ // `quick_order`, `shipments` — fail closed when it is off, which is the
157
+ // intended meaning of switching a delivery catalog off, not an accident.
158
+ // Feature 091 (Phase 4, batch 8) — this module ships a bundle now: its
159
+ // sidebar entry's `labelKey` is module-relative (R8) and resolves in this
160
+ // module's own namespace. Its screen's copy stays in `_i18n`'s `core`
161
+ // scope, which is batch 4's shape and not a new one.
162
+ i18n: { bundlesDir: 'i18n' },
163
+ docs: { dir: 'docs' },
164
+ // Feature 091 (Phase 4, batch 8) — the palette row `AppShell.tsx` carried by
165
+ // hand, arriving as the declaration Principle XVI names, for the reason
166
+ // recorded on `credit_limits`' entry: a `PALETTE_ITEMS` literal is a copy of
167
+ // an advertisement nothing filtered by the effective enabled-set.
168
+ // `delivery_methods:read` is what gates `GET /api/v1/admin/delivery-methods`,
169
+ // so the palette never advertises a 403.
170
+ actions: [
171
+ {
172
+ id: 'open-delivery-methods',
173
+ labelKey: 'actions.openDeliveryMethods.label',
174
+ descriptionKey: 'actions.openDeliveryMethods.description',
175
+ icon: 'Truck',
176
+ targetRoute: '/delivery-methods',
177
+ requiredPermission: 'delivery_methods:read',
178
+ keywords: ['delivery', 'shipping', 'methods', 'courier', 'metody dostawy', 'wysyłka', 'kurier'],
179
+ weight: 300,
180
+ },
181
+ ],
182
+ demo,
183
+ activation: { settingCode: 'delivery_methods.enabled', default: true },
184
+ });
185
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+ /**
3
+ * Shipping-method adapter framework + Shipment record (feature 035 — Metoda
4
+ * Dostawy).
5
+ *
6
+ * Extends the existing `delivery_methods` entry into a configurable,
7
+ * adapter-backed shipping method and introduces the `shipments` record:
8
+ *
9
+ * delivery_methods:
10
+ * + adapter — registry key of the ShippingAdapter realising the
11
+ * logic (backfilled from the existing `code`)
12
+ * + status_on_success — Order-status reference applied on a successful
13
+ * shipment generation (seed `shipped`)
14
+ * + status_on_failure — Order-status reference applied on a failed
15
+ * shipment generation (seed `in_fulfilment`)
16
+ *
17
+ * shipments (new):
18
+ * a first-class generation attempt against an Order — order_id,
19
+ * delivery_method_id, status (pending|success|failure), external_reference,
20
+ * provider_details, failure_reason, attempt_no, timestamps.
21
+ *
22
+ * `price` reuses the existing `delivery_methods.cost` column (no new column).
23
+ * Seed status mappings reuse the current hard-coded order `status` enum until
24
+ * the Orders module ships a configurable registry (see research.md R3/R10).
25
+ */
26
+ export declare class Migration20260611T140354DeliveryMethodsShippingMethodsAdapterAndShipments extends Migration {
27
+ up(): Promise<void>;
28
+ down(): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.d.ts","sourceRoot":"","sources":["../../src/migrations/20260611T140354_delivery_methods_shipping_methods_adapter_and_shipments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,yEAA0E,SAAQ,SAAS;IACvF,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAqCnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CASrC"}