@openlup/platform 0.22.0 → 0.24.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/CHANGELOG.md +440 -158
- package/README.md +141 -589
- package/dist/fulfillment/adapterConformance.js +1 -1
- package/dist/fulfillment/bindings.js +1 -1
- package/dist/fulfillment/contracts/conformance.d.ts +3 -1
- package/dist/fulfillment/contracts/dispatch.d.ts +45 -3
- package/dist/fulfillment/contracts/index.d.ts +3 -3
- package/dist/fulfillment/contracts/observation.d.ts +21 -1
- package/dist/fulfillment/contracts/readback.d.ts +21 -0
- package/dist/fulfillment/contracts/store.d.ts +3 -0
- package/dist/fulfillment/contracts/sync.d.ts +58 -2
- package/dist/fulfillment/dispatchProjection.d.ts +20 -1
- package/dist/fulfillment/dispatchProjection.js +97 -6
- package/dist/fulfillment/index.d.ts +3 -2
- package/dist/fulfillment/index.js +2 -2
- package/dist/fulfillment/migrations.d.ts +5 -0
- package/dist/fulfillment/migrations.js +1 -0
- package/dist/fulfillment/observationProjection.d.ts +24 -3
- package/dist/fulfillment/observationProjection.js +65 -12
- package/dist/fulfillment/omnipack/client.d.ts +3 -1
- package/dist/fulfillment/omnipack/client.js +31 -13
- package/dist/fulfillment/omnipack/index.d.ts +4 -1
- package/dist/fulfillment/omnipack/index.js +107 -45
- package/dist/fulfillment/omnipack/mappers.d.ts +7 -1
- package/dist/fulfillment/omnipack/mappers.js +24 -2
- package/dist/fulfillment/omnipack/observation.d.ts +11 -4
- package/dist/fulfillment/omnipack/observation.js +44 -29
- package/dist/fulfillment/omnipack/reconciliation.d.ts +15 -0
- package/dist/fulfillment/omnipack/reconciliation.js +55 -0
- package/dist/fulfillment/postgresDispatchStore.js +1 -1
- package/dist/fulfillment/postgresShipmentSpine.d.ts +8 -1
- package/dist/fulfillment/postgresShipmentSpine.js +17 -3
- package/dist/fulfillment/postgresStockSyncPort.js +6 -3
- package/dist/fulfillment/providerDispatchAcceptance.d.ts +1 -0
- package/dist/fulfillment/providerDispatchAcceptance.js +8 -2
- package/dist/fulfillment/providerDispatchWorker.d.ts +51 -0
- package/dist/fulfillment/providerDispatchWorker.js +65 -20
- package/dist/fulfillment/providerReconciliationWorker.d.ts +27 -19
- package/dist/fulfillment/providerReconciliationWorker.js +75 -19
- package/dist/fulfillment/providerStockSyncWorker.d.ts +5 -1
- package/dist/fulfillment/providerStockSyncWorker.js +229 -120
- package/dist/fulfillment/providerTrackingReferences.d.ts +3 -2
- package/dist/fulfillment/verifiedIngress.d.ts +38 -11
- package/dist/fulfillment/verifiedIngress.js +36 -8
- package/dist/invoicing/accountingCanonicalProviderLines.d.ts +5 -0
- package/dist/invoicing/accountingCanonicalProviderLines.js +104 -0
- package/dist/invoicing/accountingLineAllocation.d.ts +2 -0
- package/dist/invoicing/accountingLineAllocation.js +69 -0
- package/dist/invoicing/adapterConformance.d.ts +42 -0
- package/dist/invoicing/adapterConformance.js +296 -0
- package/dist/invoicing/artifacts.d.ts +7 -0
- package/dist/invoicing/artifacts.js +20 -0
- package/dist/invoicing/bindings.d.ts +46 -0
- package/dist/invoicing/bindings.js +69 -0
- package/dist/invoicing/capabilities.d.ts +11 -0
- package/dist/invoicing/capabilities.js +10 -0
- package/dist/invoicing/channelPolicy.d.ts +28 -0
- package/dist/invoicing/channelPolicy.js +27 -0
- package/dist/invoicing/continuity.d.ts +12 -0
- package/dist/invoicing/continuity.js +18 -0
- package/dist/invoicing/contracts/capabilities.d.ts +40 -0
- package/dist/invoicing/contracts/capabilities.js +1 -0
- package/dist/invoicing/contracts/companyLookup.d.ts +49 -0
- package/dist/invoicing/contracts/companyLookup.js +1 -0
- package/dist/invoicing/contracts/delivery.d.ts +74 -0
- package/dist/invoicing/contracts/delivery.js +1 -0
- package/dist/invoicing/contracts/facts.d.ts +110 -0
- package/dist/invoicing/contracts/facts.js +1 -0
- package/dist/invoicing/contracts/host.d.ts +245 -0
- package/dist/invoicing/contracts/host.js +1 -0
- package/dist/invoicing/contracts/index.d.ts +16 -0
- package/dist/invoicing/contracts/index.js +1 -0
- package/dist/invoicing/contracts/provider.d.ts +126 -0
- package/dist/invoicing/contracts/provider.js +1 -0
- package/dist/invoicing/contracts/settlement.d.ts +66 -0
- package/dist/invoicing/contracts/settlement.js +1 -0
- package/dist/invoicing/contracts/store.d.ts +277 -0
- package/dist/invoicing/contracts/store.js +1 -0
- package/dist/invoicing/contribution.d.ts +21 -0
- package/dist/invoicing/contribution.js +19 -0
- package/dist/invoicing/correction.d.ts +42 -0
- package/dist/invoicing/correction.js +44 -0
- package/dist/invoicing/delivery.d.ts +85 -0
- package/dist/invoicing/delivery.js +79 -0
- package/dist/invoicing/documentHistory.d.ts +50 -0
- package/dist/invoicing/documentHistory.js +213 -0
- package/dist/invoicing/documentSync.d.ts +24 -0
- package/dist/invoicing/documentSync.js +26 -0
- package/dist/invoicing/dutyCollector.d.ts +15 -0
- package/dist/invoicing/dutyCollector.js +35 -0
- package/dist/invoicing/fulfillmentTrigger.d.ts +56 -0
- package/dist/invoicing/fulfillmentTrigger.js +90 -0
- package/dist/invoicing/handoff.d.ts +37 -0
- package/dist/invoicing/handoff.js +62 -0
- package/dist/invoicing/index.d.ts +39 -0
- package/dist/invoicing/index.js +37 -0
- package/dist/invoicing/issue.d.ts +39 -0
- package/dist/invoicing/issue.js +55 -0
- package/dist/invoicing/migrations.d.ts +48 -0
- package/dist/invoicing/migrations.js +25 -0
- package/dist/invoicing/nativeUnsupported.d.ts +9 -0
- package/dist/invoicing/nativeUnsupported.js +22 -0
- package/dist/invoicing/paymentReadback.d.ts +20 -0
- package/dist/invoicing/paymentReadback.js +47 -0
- package/dist/invoicing/postgresInvoiceStore.d.ts +55 -0
- package/dist/invoicing/postgresInvoiceStore.js +344 -0
- package/dist/invoicing/readModel.d.ts +74 -0
- package/dist/invoicing/readModel.js +90 -0
- package/dist/invoicing/readback.d.ts +4 -0
- package/dist/invoicing/readback.js +30 -0
- package/dist/invoicing/reversal.d.ts +37 -0
- package/dist/invoicing/reversal.js +28 -0
- package/dist/invoicing/sellerRevision.d.ts +19 -0
- package/dist/invoicing/sellerRevision.js +14 -0
- package/dist/invoicing/settlementSync.d.ts +18 -0
- package/dist/invoicing/settlementSync.js +32 -0
- package/dist/invoicing/snapshot.d.ts +52 -0
- package/dist/invoicing/snapshot.js +141 -0
- package/dist/subscriptions/automaticRenewal.d.ts +44 -0
- package/dist/subscriptions/automaticRenewal.js +81 -0
- package/dist/subscriptions/automaticRenewalExecution.d.ts +21 -0
- package/dist/subscriptions/automaticRenewalExecution.js +44 -0
- package/dist/subscriptions/contracts/commands.d.ts +115 -0
- package/dist/subscriptions/contracts/commands.js +1 -0
- package/dist/subscriptions/contracts/dunning.d.ts +133 -0
- package/dist/subscriptions/contracts/dunning.js +1 -0
- package/dist/subscriptions/contracts/index.d.ts +6 -0
- package/dist/subscriptions/contracts/index.js +1 -0
- package/dist/subscriptions/contracts/messages.d.ts +43 -0
- package/dist/subscriptions/contracts/messages.js +1 -0
- package/dist/subscriptions/contracts/renewal.d.ts +533 -0
- package/dist/subscriptions/contracts/renewal.js +1 -0
- package/dist/subscriptions/contracts/stockWait.d.ts +73 -0
- package/dist/subscriptions/contracts/stockWait.js +1 -0
- package/dist/subscriptions/index.d.ts +39 -0
- package/dist/subscriptions/index.js +17 -0
- package/dist/subscriptions/paymentOutcomes.d.ts +8 -0
- package/dist/subscriptions/paymentOutcomes.js +27 -0
- package/dist/subscriptions/postgresRenewalStore.d.ts +20 -0
- package/dist/subscriptions/postgresRenewalStore.js +61 -0
- package/dist/subscriptions/postgresRetryStore.d.ts +78 -0
- package/dist/subscriptions/postgresRetryStore.js +142 -0
- package/dist/subscriptions/renewalCycleFailureMechanism.d.ts +34 -0
- package/dist/subscriptions/renewalCycleFailureMechanism.js +79 -0
- package/dist/subscriptions/renewalCycleMechanism.d.ts +46 -0
- package/dist/subscriptions/renewalCycleMechanism.js +157 -0
- package/dist/subscriptions/renewalCycleRefusalMechanism.d.ts +41 -0
- package/dist/subscriptions/renewalCycleRefusalMechanism.js +160 -0
- package/dist/subscriptions/renewalIdentity.d.ts +3 -0
- package/dist/subscriptions/renewalIdentity.js +4 -0
- package/package.json +23 -3
- package/release-gates.json +74 -7
- package/sql/20260809210000_accounting_document_rail.sql +889 -0
- package/sql/20260811150000_accounting_payout_rail.sql +333 -0
- package/sql/20260812130000_accounting_document_lifecycle_rail.sql +460 -0
- package/sql/20261022160000_subscription_retry_lifecycle.sql +328 -0
- package/sql/20261022165000_fulfillment_stock_evidence_replay_reopen.sql +30 -0
- package/sql/20261022190000_invoicing_durable_duties.sql +494 -0
- package/sql/20261022191000_invoicing_document_effects.sql +249 -0
- package/sql/20261022192000_invoicing_payment_decoupling.sql +144 -0
- package/sql/20261022195000_invoicing_seller_revision.sql +65 -0
- package/src/fulfillment/adapterConformance.ts +1 -1
- package/src/fulfillment/bindings.ts +1 -1
- package/src/fulfillment/contracts/conformance.ts +3 -1
- package/src/fulfillment/contracts/dispatch.ts +24 -5
- package/src/fulfillment/contracts/index.ts +3 -3
- package/src/fulfillment/contracts/observation.ts +11 -3
- package/src/fulfillment/contracts/readback.ts +13 -0
- package/src/fulfillment/contracts/store.ts +1 -0
- package/src/fulfillment/contracts/sync.ts +13 -2
- package/src/fulfillment/dispatchProjection.ts +94 -7
- package/src/fulfillment/index.ts +3 -2
- package/src/fulfillment/migrations.ts +1 -0
- package/src/fulfillment/observationProjection.ts +64 -13
- package/src/fulfillment/omnipack/client.ts +32 -13
- package/src/fulfillment/omnipack/index.ts +99 -39
- package/src/fulfillment/omnipack/mappers.ts +23 -2
- package/src/fulfillment/omnipack/observation.ts +45 -27
- package/src/fulfillment/omnipack/reconciliation.ts +56 -0
- package/src/fulfillment/postgresDispatchStore.ts +1 -1
- package/src/fulfillment/postgresShipmentSpine.ts +21 -4
- package/src/fulfillment/postgresStockSyncPort.ts +6 -3
- package/src/fulfillment/providerDispatchAcceptance.ts +9 -3
- package/src/fulfillment/providerDispatchWorker.ts +61 -20
- package/src/fulfillment/providerReconciliationWorker.ts +81 -25
- package/src/fulfillment/providerStockSyncWorker.ts +222 -126
- package/src/fulfillment/providerTrackingReferences.ts +3 -2
- package/src/fulfillment/verifiedIngress.ts +44 -11
- package/src/invoicing/accountingCanonicalProviderLines.ts +134 -0
- package/src/invoicing/accountingLineAllocation.ts +69 -0
- package/src/invoicing/adapterConformance.ts +249 -0
- package/src/invoicing/artifacts.ts +19 -0
- package/src/invoicing/bindings.ts +80 -0
- package/src/invoicing/capabilities.ts +9 -0
- package/src/invoicing/channelPolicy.ts +50 -0
- package/src/invoicing/continuity.ts +15 -0
- package/src/invoicing/contracts/capabilities.ts +15 -0
- package/src/invoicing/contracts/companyLookup.ts +13 -0
- package/src/invoicing/contracts/delivery.ts +24 -0
- package/src/invoicing/contracts/facts.ts +71 -0
- package/src/invoicing/contracts/host.ts +84 -0
- package/src/invoicing/contracts/index.ts +16 -0
- package/src/invoicing/contracts/provider.ts +78 -0
- package/src/invoicing/contracts/settlement.ts +39 -0
- package/src/invoicing/contracts/store.ts +102 -0
- package/src/invoicing/contribution.ts +28 -0
- package/src/invoicing/correction.ts +56 -0
- package/src/invoicing/delivery.ts +122 -0
- package/src/invoicing/documentHistory.ts +301 -0
- package/src/invoicing/documentSync.ts +51 -0
- package/src/invoicing/dutyCollector.ts +31 -0
- package/src/invoicing/fulfillmentTrigger.ts +144 -0
- package/src/invoicing/handoff.ts +71 -0
- package/src/invoicing/index.ts +39 -0
- package/src/invoicing/issue.ts +64 -0
- package/src/invoicing/migrations.ts +25 -0
- package/src/invoicing/nativeUnsupported.ts +24 -0
- package/src/invoicing/paymentReadback.ts +70 -0
- package/src/invoicing/postgresInvoiceStore.ts +334 -0
- package/src/invoicing/readModel.ts +80 -0
- package/src/invoicing/readback.ts +26 -0
- package/src/invoicing/reversal.ts +34 -0
- package/src/invoicing/sellerRevision.ts +20 -0
- package/src/invoicing/settlementSync.ts +37 -0
- package/src/invoicing/snapshot.ts +192 -0
- package/src/subscriptions/automaticRenewal.ts +87 -0
- package/src/subscriptions/automaticRenewalExecution.ts +39 -0
- package/src/subscriptions/contracts/commands.ts +46 -0
- package/src/subscriptions/contracts/dunning.ts +48 -0
- package/src/subscriptions/contracts/index.ts +6 -0
- package/src/subscriptions/contracts/messages.ts +18 -0
- package/src/subscriptions/contracts/renewal.ts +325 -0
- package/src/subscriptions/contracts/stockWait.ts +34 -0
- package/src/subscriptions/index.ts +24 -0
- package/src/subscriptions/paymentOutcomes.ts +23 -0
- package/src/subscriptions/postgresRenewalStore.ts +76 -0
- package/src/subscriptions/postgresRetryStore.ts +174 -0
- package/src/subscriptions/renewalCycleFailureMechanism.ts +119 -0
- package/src/subscriptions/renewalCycleMechanism.ts +225 -0
- package/src/subscriptions/renewalCycleRefusalMechanism.ts +215 -0
- package/src/subscriptions/renewalIdentity.ts +5 -0
package/README.md
CHANGED
|
@@ -1,17 +1,45 @@
|
|
|
1
1
|
# @openlup/platform
|
|
2
2
|
|
|
3
|
+
Invoicing exports explicit `createInvoiceServices`, `InvoiceServices` and inert
|
|
4
|
+
`createInvoiceContribution` through `/invoicing`, with no new composition entry.
|
|
5
|
+
`claimInvoiceSellerRevision` reads an injected selection before claim; the pinned
|
|
6
|
+
SQL wrappers persist it for eligible obligations. `InvoiceSellerRevision` is also
|
|
7
|
+
available from the type-only contracts entry. Legacy obligations keep fallback.
|
|
8
|
+
|
|
3
9
|
Development preview. This package is part of the publishable set with core and outbox; preparation does not establish a registry release or a stable API. Its repository-directory publish command refuses publication; the authorized package-release workflow owns publication.
|
|
4
10
|
|
|
5
11
|
It holds the runnable server substrate an OpenLup application composes: the Node HTTP runtime, BFF dispatch, scheduling and job leases, blob storage, data gateways, the node-postgres migration runner and bundle composition. Ports and their contracts stay in `@openlup/core/platform-runtime`.
|
|
6
12
|
|
|
7
|
-
For the prepared `0.
|
|
8
|
-
limitations](CHANGELOG.md#
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
For the prepared `0.24.0` set, read the [adjacent-release migration and known
|
|
14
|
+
limitations](CHANGELOG.md#0240) before selecting optional services.
|
|
15
|
+
Install the complete native chain through position 80, including invoicing
|
|
16
|
+
positions 77–79 and the first-claim seller revision forward; sparse SQL projections
|
|
17
|
+
are not an install chain. Keep the older native-row migration precautions in the
|
|
18
|
+
release notes when upgrading `0.22.0` data. Native delivery alignment stays off or
|
|
19
|
+
shadow until a host composes its automatic-renewal runner with G23 admission.
|
|
20
|
+
M10 subscription renewal/retry (P1 exports, forward controls, P2 stores/executor,
|
|
21
|
+
native N1 SQL) remains **EXPERIMENTAL, INCOMPLETE and DEFAULT-OFF**, not for
|
|
22
|
+
adopter activation; G23/N1 host obligations remain pending.
|
|
23
|
+
M09 invoicing remains **EXPERIMENTAL and DEFAULT-OFF**, available for explicit
|
|
24
|
+
provider/capability selection and ready host composition, including issue,
|
|
25
|
+
correction, independent duties, delivery/read-side and seller revision helpers.
|
|
26
|
+
Adopters must not activate unselected or unready invoicing; installation and
|
|
27
|
+
inert contributions register no runner, worker, route or schedule.
|
|
28
|
+
M06 managed-host proof classes remain pending in the
|
|
11
29
|
[M06 parity ledger](../../docs/platform/plans/oss-m06-stock-reservations-delivery.md#parity-pending-rows).
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
30
|
+
Size comparison uses the published `0.23.0` tarball. Preparation and offline
|
|
31
|
+
adapter evidence grant no publication or provider-account certification.
|
|
32
|
+
|
|
33
|
+
Longer module recipes live in the [platform package reference](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md).
|
|
34
|
+
|
|
35
|
+
The prepared set requires Zod `^4.6.6` for GHSA-mrhx-c7xc-m3w5.
|
|
36
|
+
Public quote requests retain their collection limits and valid-input behavior;
|
|
37
|
+
oversized collections now fail with the size error before accumulating invalid
|
|
38
|
+
element errors. Package API and installed-consumer checks remain required.
|
|
39
|
+
The observation adapter explicitly retains minute-precision timestamps
|
|
40
|
+
alongside seconds/fractions, compact offsets and local timestamps. Calendar
|
|
41
|
+
validation still rejects impossible dates; validation never rewrites the raw
|
|
42
|
+
timestamp used in the webhook's idempotency key.
|
|
15
43
|
|
|
16
44
|
## Package surface
|
|
17
45
|
|
|
@@ -37,6 +65,8 @@ or provider-account certification.
|
|
|
37
65
|
| `./fulfillment/omnipack` | Opt-in Node fulfillment example with injected I/O; default-off. |
|
|
38
66
|
| `./payments` | Experimental prepared-attempt ordering with injected persistence, execution and failure policy; contracts at `./payments/contracts`. |
|
|
39
67
|
| `./fulfillment`, `./fulfillment/contracts` | [Experimental fulfillment services, contracts and status canon](../../docs/platform/ARCHITECTURE_AND_EXTENSIONS.md#fulfillment-contracts). |
|
|
68
|
+
| `./subscriptions`, `./subscriptions/contracts` | Default-off, incomplete; [experimental subscription contracts and renewal port](../../docs/platform/ARCHITECTURE_AND_EXTENSIONS.md#subscription-contracts). |
|
|
69
|
+
| `./invoicing`, `./invoicing/contracts` | Default-off invoicing contracts and independent duty collection; no provider activation. |
|
|
40
70
|
| `./inventory` | Experimental schemas/ports, handlers, native stores, projection, injected forecast and SQL descriptor; `./inventory/contracts` DTOs. |
|
|
41
71
|
| `./catalog` | Experimental neutral catalog schemas, drafts, reads, media source packs and publication ports |
|
|
42
72
|
| `./catalog/contracts` | Dependency-free catalog DTOs, media resolver, authority and canonicalization helpers |
|
|
@@ -455,458 +485,23 @@ in both resolution modes with all three optional peers absent.
|
|
|
455
485
|
|
|
456
486
|
## Identity import candidate
|
|
457
487
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
`identityOidcReadiness` from `@openlup/platform/identity`, which also exports
|
|
461
|
-
`OIDC_FAILURE_CODES` and `OidcFailureCode` for hosts. The browser-shared
|
|
462
|
-
`@openlup/platform/identity/contracts` entry excludes OIDC refusals.
|
|
463
|
-
Inject the host's selected JWT library through `IdentityJwtLibraryLoader`.
|
|
464
|
-
Discovery and rotating keys load only on verification or readiness. The opt-in
|
|
465
|
-
direct composition uses normal reconcile with an explicit email-trust policy,
|
|
466
|
-
authenticated actor reads and live operator membership. Managed storage requires
|
|
467
|
-
native federation sessions and refuses raw upstream-token composition. Run
|
|
468
|
-
`node tests/postgres/runOidcIdentityConformance.mjs` from the repository root with
|
|
469
|
-
its cached pinned issuer and local prerequisites; the [OIDC recipe](../../docs/platform/IDENTITY.md#real-issuer-oidc-recipe)
|
|
470
|
-
owns timing, refusal, session and certification boundaries. There is no schema or
|
|
471
|
-
default login flow change; existing static session verification and default
|
|
472
|
-
reference/browser flows retain their runtime behaviour.
|
|
473
|
-
|
|
474
|
-
The existing `IdentityJwtLibrary.jwtVerify` contract widens with optional
|
|
475
|
-
`currentDate?: Date` and `clockTolerance?: number` verify options and now returns
|
|
476
|
-
`{ payload: IdentityJwtClaims }`, whose claims interface includes a string index
|
|
477
|
-
signature. **Migration:** hosts implementing or typing their own
|
|
478
|
-
`IdentityJwtLibrary` or `IdentityJwtLibraryLoader` must accept the optional verify
|
|
479
|
-
options and return claims as `IdentityJwtClaims`.
|
|
480
|
-
|
|
481
|
-
The direct operator API adds `createPostgresOperatorIdentityStore`,
|
|
482
|
-
`createOperatorSessionService`, `createOperatorIdentityVerifier`,
|
|
483
|
-
`createOperatorAdminAuth` and `createOperatorAuthHandlers` to `./identity`.
|
|
484
|
-
`./identity/contracts` exposes strict operator challenge/session schemas and
|
|
485
|
-
`OperatorBrowserAuthPort` without a server or provider import. Challenge delivery
|
|
486
|
-
and session signing use the existing structural ports. Operator handlers send
|
|
487
|
-
the padded generic acceptance before awaiting mailbox delivery, keeping delivery
|
|
488
|
-
latency out of the response. Custom HTTP composition uses the session service's
|
|
489
|
-
optional acceptance callback for the same ordering. Restoration reads preserve
|
|
490
|
-
in-flight browser redemption; explicit sign-out still cancels it. Active operator
|
|
491
|
-
login needs no pending invitation and preserves membership and invitation history. The new store's public
|
|
492
|
-
signature exposes no driver types and loads its optional driver only on use.
|
|
493
|
-
|
|
494
|
-
Apply the complete direct catalogue through position 68 before enabling human
|
|
495
|
-
login; `sql/20261018180000_identity_operator_challenges.sql` is its exact projection.
|
|
496
|
-
Configure a distinct operator audience and an adopter deployment route policy:
|
|
497
|
-
the public policy refuses all mounted operator routes, including `me`, with
|
|
498
|
-
`adopter_policy_required` before input or authentication-binding construction. The reference dispatcher accepts a
|
|
499
|
-
session-binding factory through `createReferenceBffDispatch`; use it to compose
|
|
500
|
-
separate operator delivery. Caller-supplied operator handlers retain the same
|
|
501
|
-
policy boundary. The browser hook consumes guarded auth-port notifications rather
|
|
502
|
-
than signing out from a stale post-redemption check. Use the
|
|
503
|
-
explicit bootstrap/prune commands in the [identity guide](../../docs/platform/IDENTITY.md#direct-human-login).
|
|
504
|
-
The bounded reference browser builds do not mount the admin shell; application
|
|
505
|
-
composition must mount the provided pages and hook. First redemption activates the existing invitation and consumes the challenge in
|
|
506
|
-
one transaction. Live membership, not a JWT role, authorizes each request. The
|
|
507
|
-
cold consumer includes both identity entries and the new adapter's missing-peer
|
|
508
|
-
refusal; real concurrency and upgrade proof needs the complete PostgreSQL chain.
|
|
509
|
-
|
|
510
|
-
Creating a client/contact records commerce contact data, not an authentication
|
|
511
|
-
identity. Creating an auth user provisions a principal. Neither a typed address
|
|
512
|
-
nor a soft-account link proves mailbox ownership; reconcile may create a contact
|
|
513
|
-
for an existing authenticated principal without creating that principal.
|
|
514
|
-
|
|
515
|
-
Customer soft-account provisioning now creates unconfirmed auth users
|
|
516
|
-
(`email_confirm:false`). The soft-account linker retains create-first lookup,
|
|
517
|
-
normalized duplicate recovery and conditional linking. Checkout and paid-order
|
|
518
|
-
retry are adopter composition that must call the linker. Failed links retain
|
|
519
|
-
the provisioned identity for retry. Customer magic links keep
|
|
520
|
-
`shouldCreateUser:false`: captured mailbox proof confirms that existing user;
|
|
521
|
-
unknown addresses cannot sign themselves up through this path.
|
|
522
|
-
|
|
523
|
-
The managed link store requires an injected `emailTrustPolicy`, assessed before
|
|
524
|
-
creation or linking an existing identity by email. Unsafe or unavailable settings
|
|
525
|
-
return a non-fatal soft-account refusal (`EMAIL_TRUST_ENVELOPE_REFUSED` or
|
|
526
|
-
`EMAIL_TRUST_SETTINGS_UNAVAILABLE`) without creating an identity or link. Matching
|
|
527
|
-
existing links retain their replay behaviour. The reference adapter binds managed
|
|
528
|
-
settings assessment regardless of the selected bundle.
|
|
529
|
-
|
|
530
|
-
**Migration:** soft-account provisioning requires a trusted envelope: automatic
|
|
531
|
-
email confirmation disabled and every enabled non-email provider explicitly
|
|
532
|
-
declared email-verifying. Automatic signup can otherwise confirm an unconfirmed
|
|
533
|
-
user and issue a session to someone who merely knows the contact's address.
|
|
534
|
-
Pass the policy to `createSupabaseClientAuthLinkStore(client, emailTrustPolicy)`;
|
|
535
|
-
custom `ClientAuthLinkStore` implementations must expose `emailTrustPolicy`.
|
|
536
|
-
An adopter may explicitly bind `createVerifierResultOnlyEmailTrustPolicy()` when
|
|
537
|
-
its own trust boundary supplies the guarantee. Ensure the selected Auth installation can deliver and verify the
|
|
538
|
-
first-login link for an existing unconfirmed user. Run the documented joint local conformance
|
|
539
|
-
command after building core/platform. Existing identities, contact links,
|
|
540
|
-
subscription references and migration history are not rewritten.
|
|
541
|
-
|
|
542
|
-
Managed verification now requires the confirmation timestamp. Email-derived
|
|
543
|
-
reconcile requires an injected `emailTrustPolicy`. Managed hosts share
|
|
544
|
-
`createManagedEmailTrustPolicy` with `identityEmailTrustReadiness`; it reports
|
|
545
|
-
module `identity` using core's existing codes. Hosts retaining verifier-only
|
|
546
|
-
admission explicitly bind `createVerifierResultOnlyEmailTrustPolicy()`.
|
|
547
|
-
See the [identity policy and migration](../../docs/platform/IDENTITY.md#responsibility-and-composition)
|
|
548
|
-
for the empty provider allowlist, cache/deadline, 403/503 failures and the opt-in
|
|
549
|
-
`node tests/postgres/runIdentityEnvelopeConformance.mjs --phase email-trust` and
|
|
550
|
-
`node tests/postgres/runIdentityEnvelopeConformance.mjs --phase joint` prerequisites
|
|
551
|
-
and conformance scope. Both phases replay the committed managed chain, including
|
|
552
|
-
the identity capabilities forward, and prove association under the shipped managed
|
|
553
|
-
reference grants.
|
|
554
|
-
Construction and imports perform no settings read or SDK initialization.
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
The `./identity` server entry imports the existing identity engine, authorization,
|
|
558
|
-
profile readers, session adapters and BFF factories into one capability. Its
|
|
559
|
-
`./identity/contracts` entry is declared browser-safe and currently exposes the
|
|
560
|
-
customer auth port, value types and provider parser. Runtime-schema extraction
|
|
561
|
-
is pending the contracts-boundary choice described in the
|
|
562
|
-
[identity owner page](../../docs/platform/IDENTITY.md). Both entries remain an
|
|
563
|
-
unpublished development-preview import candidate.
|
|
564
|
-
|
|
565
|
-
Application composition supplies SDK clients/loaders, feature admission, redirect
|
|
566
|
-
policy, rate limiting, messages, sender and deployment URLs. Factories use the
|
|
567
|
-
foundation BFF envelope and accept the application's observed request-ID reader.
|
|
568
|
-
The module depends only on the declared foundation entries, without changing the
|
|
569
|
-
artifact's rail kind. Its schema contribution requires a host-selected inventory;
|
|
570
|
-
its seven SQL files are verbatim projections at canonical positions 11, 12, 29,
|
|
571
|
-
60, 67, 68 and 69, not an independent migration chain. The owner page maps the characterization
|
|
572
|
-
witnesses and records the remaining evidence.
|
|
573
|
-
|
|
574
|
-
Identity authorizes stored operator roles only when they are `admin` or
|
|
575
|
-
`distributor`; null and unknown values return `FORBIDDEN` (HTTP 403). The reference
|
|
576
|
-
admin-profile reader reports those rows as non-admin, and admin magic links do
|
|
577
|
-
not send for them while retaining the generic accepted response, padding and
|
|
578
|
-
quota. Adopters needing legacy role mapping must do it in their own adapter
|
|
579
|
-
before passing the role to the package; there is no package fallback option.
|
|
580
|
-
|
|
581
|
-
Both managed contact stores match normalized addresses case-insensitively,
|
|
582
|
-
including mixed-case stored contacts. Literal matching uses an anchored, escaped
|
|
583
|
-
`imatch` database prefilter plus an exact `email.trim().toLowerCase()` comparison
|
|
584
|
-
with the normalized input. Unicode regex folding alone cannot establish identity.
|
|
585
|
-
Both lookups select email and fetch at most ten candidates. Soft linking selects
|
|
586
|
-
the oldest accepted contact; reconciliation requires a single accepted contact
|
|
587
|
-
and throws the existing multiple-row error if several remain. A match beyond the
|
|
588
|
-
candidate bound is not selected. Injected structural query clients must implement
|
|
589
|
-
`filter(column, "imatch", value)` and the bounded array query. The direct customer
|
|
590
|
-
challenge already compares `lower(email)` to normalized input; no migration is
|
|
591
|
-
needed.
|
|
592
|
-
|
|
593
|
-
Magic-link factories default to the shared strict origin resolver. Pass
|
|
594
|
-
`redirectOrigins: ["https://example.com", "https://secondary.example.com:8443"]`;
|
|
595
|
-
the first configured origin builds the callback and every entry must be an exact
|
|
596
|
-
HTTP(S) origin, without credentials, a path, query or fragment (a root trailing
|
|
597
|
-
slash is accepted). Request headers never authorize an origin. Missing or invalid
|
|
598
|
-
configuration returns BFF `UPSTREAM_UNAVAILABLE` (503), with details reason
|
|
599
|
-
`magic_link_origin_not_configured`, before provider access. Customer `returnTo`
|
|
600
|
-
is normalized to a same-origin relative path; unsafe targets are omitted for the
|
|
601
|
-
callback's default landing page. An adopter needing its existing policy can keep
|
|
602
|
-
passing `resolveOrigin`; that explicit injection overrides the default. See the
|
|
603
|
-
[identity redirect contract](../../docs/platform/IDENTITY.md#magic-link-redirect-policy)
|
|
604
|
-
for reference configuration and migration.
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
### Operator invitations
|
|
608
|
-
|
|
609
|
-
`identity/contracts` exposes distinct direct pending-invitation and managed
|
|
610
|
-
active-membership results. Matching runtime schemas remain in the server entry.
|
|
611
|
-
The admin-action port returns `OperatorInviteResult`, a union of those results.
|
|
612
|
-
|
|
613
|
-
`createDirectOperatorInvitationStore` provides the new pending, active, expired and
|
|
614
|
-
revoked lifecycle in its trusted PostgreSQL transaction lane, including ordered
|
|
615
|
-
membership locks and atomic membership/audit writes. Direct callers inject the
|
|
616
|
-
store and a parsed TTL. `createDirectOperatorIdentityDirectory` commits principal
|
|
617
|
-
creation/reuse separately. Apply the complete direct catalogue through position
|
|
618
|
-
67; the byte-identical package projection is for inspection and composition, not
|
|
619
|
-
a standalone fresh chain. Direct human acceptance is a trusted command,
|
|
620
|
-
unmounted from machine authentication.
|
|
621
|
-
|
|
622
|
-
Managed hosts use `createInviteAdminUserGateway().activateMembership` in
|
|
623
|
-
`runInviteAdminUserUseCase`. Insertion immediately creates active `admin_users`
|
|
624
|
-
membership with invitation provenance; it omits `is_machine_actor` and relies on
|
|
625
|
-
the database default false. The result carries principal ID, role, active state
|
|
626
|
-
and `MEMBERSHIP_CREATED` or `ALREADY_ACTIVE`, without pending timestamps or an
|
|
627
|
-
invitation ID. Identical repeats and concurrent insert losers return the existing
|
|
628
|
-
membership without a second notification. Role differences conflict; revoked
|
|
629
|
-
members refuse with `MANAGED_REINVITE_UNSUPPORTED`. Failures retain identities
|
|
630
|
-
for retry, including after notification failure. No Auth metadata store,
|
|
631
|
-
first-entry acceptance, expiry or compensation is used. Magic-link eligibility
|
|
632
|
-
requires active membership and a known role. Authorization, removal and admin
|
|
633
|
-
`me` retain their actor bindings without a service key for lifecycle state.
|
|
634
|
-
|
|
635
|
-
**Migration:** direct hosts can adopt the new pending lifecycle by applying
|
|
636
|
-
`20261018120000_identity_operator_invitations` after the existing direct catalogue
|
|
637
|
-
and composing the store, trusted human acceptance and parsed TTL. Existing
|
|
638
|
-
memberships are preserved. Managed immediate activation is retained; managed
|
|
639
|
-
consumers must now parse the structured active result and its
|
|
640
|
-
`MEMBERSHIP_CREATED`/`ALREADY_ACTIVE` codes instead of message-only success.
|
|
641
|
-
Duplicates return existing membership rather than `ALREADY_ADDED`, and
|
|
642
|
-
notification failure returns 503 `INVITATION_NOTIFICATION_FAILED` while keeping
|
|
643
|
-
membership active. Managed pending/expiry remains a compatibility gap requiring
|
|
644
|
-
a separate transactional store and reviewed forward. No managed SQL, RPC or SDK
|
|
645
|
-
dependency is added. See the
|
|
646
|
-
[identity lifecycle owner](../../docs/platform/IDENTITY.md#operator-invitation-lifecycle).
|
|
647
|
-
|
|
648
|
-
The managed chain's identity capabilities forward
|
|
649
|
-
`20261018160000_identity_service_role_capabilities.sql` grants `service_role`
|
|
650
|
-
SELECT(email) and INSERT(id, email, role, membership_state, membership_provenance,
|
|
651
|
-
membership_accepted_at) on `admin_users`.
|
|
652
|
-
The opt-in managed conformance replays the complete committed chain with ambient
|
|
653
|
-
default ACLs removed and adds no grant. It proves immediate activation,
|
|
654
|
-
repeat/concurrent recovery and revoked-member refusal under the shipped grants.
|
|
655
|
-
It does not establish managed/direct lifecycle parity.
|
|
656
|
-
|
|
657
|
-
With a fresh local managed stack running, export its API URL, service key and
|
|
658
|
-
PostgreSQL owner (`supabase_admin`) connection URL as `OPENLUP_MANAGED_CONFORMANCE_URL`,
|
|
659
|
-
`OPENLUP_MANAGED_CONFORMANCE_SERVICE_KEY` and
|
|
660
|
-
`OPENLUP_MANAGED_CONFORMANCE_DATABASE_URL`, then run from the repository root:
|
|
661
|
-
|
|
662
|
-
```sh
|
|
663
|
-
npm --workspace @openlup/platform run build
|
|
664
|
-
node --import tsx tests/postgres/operatorInvitationManaged.conformance.ts
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
The module refuses non-loopback endpoints, an already-installed public schema,
|
|
668
|
-
and existing synthetic fixture identities. It retains synthetic identities;
|
|
669
|
-
discard the disposable stack after the run. Its database owner connection must
|
|
670
|
-
be able to replay the committed prerequisites, baseline and ordered forwards.
|
|
488
|
+
`./identity` provides server identity services; `./identity/contracts` supplies browser-shareable contracts.
|
|
489
|
+
See the [identity recipe](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#identity-import-candidate) for composition, migrations and operator invitations.
|
|
671
490
|
|
|
672
491
|
## Personal data
|
|
673
492
|
|
|
674
|
-
The experimental identity entry
|
|
675
|
-
|
|
676
|
-
`exportPersonalData`, `erasePersonalData`, `createPrivacyExportHandler` and
|
|
677
|
-
`createPrivacyEraseHandler`. Browser requests, versioned contributor documents and
|
|
678
|
-
receipts come from `@openlup/platform/identity/contracts`. Register every required
|
|
679
|
-
contributor explicitly, with its owned fields, assessment, erase/retain operation
|
|
680
|
-
and remote/retention obligations. Missing required owners refuse erasure; export
|
|
681
|
-
reports missing coverage. This capability erases identity-owned data only.
|
|
682
|
-
|
|
683
|
-
Direct hosts compose `createPostgresPrivacyUnitOfWork` and
|
|
684
|
-
`createPostgresPrivacyStore` with the identity contributor and their domain vetoes
|
|
685
|
-
using the same executor. The reference subscriptions contributor holds a relation
|
|
686
|
-
lock through commit, refusing active and paused subscriptions without changing
|
|
687
|
-
them. `IdentityPrivacyPolicy.retainedContactFields` names explicit retention
|
|
688
|
-
owners for populated opaque columns; unknown ownership refuses. The reference
|
|
689
|
-
retains lifecycle/acquisition fields, and refuses nonempty metadata or external
|
|
690
|
-
references until an owner declares their disposition.
|
|
691
|
-
|
|
692
|
-
Migration: apply the complete direct catalogue including
|
|
693
|
-
`20261018190000_identity_privacy_erasures` before using privacy or the updated
|
|
694
|
-
customer challenge store. The forward appends one receipt table at position 69
|
|
695
|
-
without grants or stored functions. Direct erasure pseudonymizes identity-owned
|
|
696
|
-
fields, deletes challenges and outstanding invitations, uses guarded membership
|
|
697
|
-
revocation, clears only the selected contact's direct principal link, and commits
|
|
698
|
-
an idempotent audit receipt atomically. Contact IDs and managed auth links never
|
|
699
|
-
change. Failed writes roll back. Retained audit references are pseudonymous, not
|
|
700
|
-
an assertion of anonymization. Already-issued tokens may remain valid until expiry.
|
|
701
|
-
Customer challenge issuance and redemption reject a receipt for either the
|
|
702
|
-
contact or principal under the same transaction-held challenge relation lock as
|
|
703
|
-
erasure, including late challenges inserted after cleanup. Hosts must use the
|
|
704
|
-
package adapters; calling the retained raw challenge SQL functions directly
|
|
705
|
-
bypasses this erasure receipt fence.
|
|
706
|
-
|
|
707
|
-
Managed hosts compose `createManagedPrivacyStore` with their structural service
|
|
708
|
-
client for export. Coverage explicitly excludes inaccessible country and
|
|
709
|
-
identity history/receipt fields. Managed erasure refuses with
|
|
710
|
-
`MANAGED_PRIVACY_ERASURE_UNAVAILABLE`: a managed adopter must provide its own
|
|
711
|
-
erasure path. The committed grants and structural client cannot provide the
|
|
712
|
-
required mutations and atomic receipt. This change adds no managed forward or
|
|
713
|
-
erasure grants. Provider identity is never deleted; any future composed provider
|
|
714
|
-
erasure must disable it after committed local success. The managed refusal here
|
|
715
|
-
occurs before reaching any provider mutation.
|
|
716
|
-
|
|
717
|
-
The reference mounts authenticated human-admin export/erase POSTs and an Admin
|
|
718
|
-
Settings readback panel. Direct and managed mounts require the adopter deployment
|
|
719
|
-
policy under admin mutation risk; the public default returns
|
|
720
|
-
`adopter_policy_required` before body/query reads, and direct mounts also refuse
|
|
721
|
-
before authentication or privacy binding construction. The shipped dispatcher mounts
|
|
722
|
-
both routes for managed bundles even when its caller supplies no routes. After admission,
|
|
723
|
-
exports and receipts stay in memory with no-store
|
|
724
|
-
responses. The maintenance `prune-challenges` command prunes separate bounded
|
|
725
|
-
operator/customer batches. See [identity privacy](../../docs/platform/IDENTITY.md#identity-personal-data)
|
|
726
|
-
for refusals, token limits and retained obligations.
|
|
727
|
-
|
|
728
|
-
The complete direct conformance is included in
|
|
729
|
-
`npm test -- tests/postgres/operatorIdentityUpgrade.test.ts` from the repository
|
|
730
|
-
root after normal setup. A maintainer host resource broker is optional.
|
|
731
|
-
For managed conformance, supply the same three `OPENLUP_MANAGED_CONFORMANCE_*`
|
|
732
|
-
local disposable-stack settings described for operator invitations, with
|
|
733
|
-
`OPENLUP_MANAGED_CONFORMANCE_DATABASE_URL` set to the database owner
|
|
734
|
-
(`supabase_admin`) connection, then run
|
|
735
|
-
`node --experimental-strip-types tests/postgres/identityPrivacyManaged.conformance.ts`.
|
|
736
|
-
Use a fresh public schema and reset the disposable stack between proofs; the
|
|
737
|
-
managed privacy proof replays the committed chain without fixture erasure grants.
|
|
738
|
-
Replay through node-postgres omits only the psql-only pg_dump `\restrict` and
|
|
739
|
-
`\unrestrict` guard lines; all migration SQL remains unchanged.
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
Reference startup can compose identity through `createReferenceIdentity` and
|
|
743
|
-
`startPublicReferenceServer({ identity })`, with explicit route functions,
|
|
744
|
-
selected adapters, trusted schema/migration observation and the bundle-specific
|
|
745
|
-
inventory. It consumes email-trust readiness before listening, and rejects
|
|
746
|
-
unknown or unsatisfied candidates. Direct reconcile reads the existing actor
|
|
747
|
-
link; direct invite/remove select the pending-invitation stores. The default
|
|
748
|
-
static reference and browser page sets remain unchanged. See the
|
|
749
|
-
[composition contract](../../docs/platform/IDENTITY.md#responsibility-and-composition).
|
|
750
|
-
|
|
751
|
-
Both identity entries already belong to the public export map and build output;
|
|
752
|
-
artifact availability does not imply registry publication or release activation.
|
|
753
|
-
The cold installed-artifact consumer imports both entries without optional peers,
|
|
754
|
-
compiles contracts without driver types, and invokes every driver-owning direct
|
|
755
|
-
identity adapter for its missing-peer refusal. Managed factories consume
|
|
756
|
-
structural clients. Server declarations compile after peer selection. Full
|
|
757
|
-
installed-artifact and database proof require the existing supervisor-run package
|
|
758
|
-
consumer command and an owned disposable database.
|
|
759
|
-
|
|
760
|
-
The managed identity service-role capabilities forward in the committed chain
|
|
761
|
-
supplies client link writes and operator membership insert/email-read
|
|
762
|
-
permissions; the local conformance runners add no fixture grant. No migration is
|
|
763
|
-
added by reference composition.
|
|
764
|
-
|
|
493
|
+
The experimental identity entry provides contributor-based personal-data export and erasure.
|
|
494
|
+
See the [personal-data recipe](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#personal-data) for composition, refusals and retained obligations.
|
|
765
495
|
|
|
766
496
|
## Disposable identity composition
|
|
767
497
|
|
|
768
|
-
The
|
|
769
|
-
|
|
770
|
-
or publishing a registry version. It reuses the customer/operator pages and
|
|
771
|
-
captured-delivery port, with a private local mailbox and administrator privacy
|
|
772
|
-
panel. Its explicit runtime must supply actual routes and readiness admission;
|
|
773
|
-
the shell refuses a missing composition. See the
|
|
774
|
-
[identity reference guide](../../docs/platform/IDENTITY.md#disposable-identity-reference)
|
|
775
|
-
for both-bundle commands, the committed managed grants and installation limits.
|
|
498
|
+
The opt-in reference identity shell consumes the existing identity exports with explicit routes and readiness admission.
|
|
499
|
+
See [disposable identity composition](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#disposable-identity-composition) for its boundary and reference guide.
|
|
776
500
|
|
|
777
501
|
## Communications import
|
|
778
502
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
M04 P1 relocates the existing public implementation without changing its reference
|
|
783
|
-
outputs. The reference shims bind the existing renderer, egress resolver, origin
|
|
784
|
-
defaults, delivery-shaping policy and receipt transaction lane. The package does
|
|
785
|
-
not select a deployment, mount a route or schedule another executor.
|
|
786
|
-
`createCommunicationsContribution` requires the host's version and schema
|
|
787
|
-
inventory; supplied handlers, schedules, routes and ports describe only that
|
|
788
|
-
host's selection.
|
|
789
|
-
|
|
790
|
-
`COMMUNICATIONS_MIGRATIONS` projects three existing canonical units byte for byte:
|
|
791
|
-
comms outbox (position 2), transactional receipts (9) and communications control
|
|
792
|
-
plane (20). This sparse list is not a standalone migration chain. Apply the full
|
|
793
|
-
selected canonical prefix through its existing runner; importing the module does
|
|
794
|
-
not apply SQL or advertise missing managed/direct capabilities.
|
|
795
|
-
|
|
796
|
-
Browser previews retain their reference renderer, content defaults and template
|
|
797
|
-
policy. The Auth hook receives that same renderer through its reference shim.
|
|
798
|
-
The standard Auth webhook and the maintained HTTP mail provider verifiers keep their separate signature
|
|
799
|
-
formats and clocks; the generic helper added to `./http` replaces neither.
|
|
800
|
-
E2 is applied: the payment webhook module delegates these five generic helpers.
|
|
801
|
-
`readRawBody` is the same package function object with its original declared
|
|
802
|
-
`(req: VercelRequest) => Promise<string>` signature; the other four exports are
|
|
803
|
-
plain re-exports. The payment provider verification and its replay tolerance stay local.
|
|
804
|
-
The maintained mail transport, credentials, callback verification/mapping,
|
|
805
|
-
poll read/mapping, timeline and send-ledger adapters remain in reference source.
|
|
806
|
-
B1 changes only the four raw-injection guard sites in the reference delivery
|
|
807
|
-
adapters and the approved invoice test fixture; the concrete client and all
|
|
808
|
-
other vendor-directory files retain the comparison-base bytes. The neutral
|
|
809
|
-
`./communications` entry exposes transport/result contracts and capture without
|
|
810
|
-
concrete mail wiring. The platform ships opt-in vendor adapter subpaths;
|
|
811
|
-
default wiring includes none, and adopters choose or replace them.
|
|
812
|
-
The type-only `CommunicationProvider<Provider>` and `EmailMessageReadModel<Provider>`
|
|
813
|
-
accept host vocabulary; reference types retain their original literal.
|
|
814
|
-
|
|
815
|
-
`createGuardedEmailTransport({ providerKind, policy, send })` is the network
|
|
816
|
-
adapter constructor. At each send it awaits a fresh host policy, validates the
|
|
817
|
-
whole decision and enters the sender only for a coherent `production`,
|
|
818
|
-
`sandbox_direct` or `sandbox_sink` decision. The sender receives the effective
|
|
819
|
-
recipient and a frozen context with intended recipient, host-selected credential,
|
|
820
|
-
mode, reason and environment tag. It must consume that context when selecting
|
|
821
|
-
credentials and emitting provider metadata. The neutral entry reads no environment
|
|
822
|
-
and contains no provider client. Opt-in adapters consume this same guard and
|
|
823
|
-
host-selected context. Missing/throwing policy, unknown modes, mismatched
|
|
824
|
-
recipients/tags, blank credentials or unsupported fields fail with status zero,
|
|
825
|
-
no identifier and bounded error codes. Reasons are lower-case token codes up to
|
|
826
|
-
80 characters. One unadorned `local@domain.example` recipient mailbox is required;
|
|
827
|
-
whitespace, lists, display names and local-only domains are refused on this new
|
|
828
|
-
alternate-transport policy boundary.
|
|
829
|
-
|
|
830
|
-
`blocked` returns failure; explicit `drop` returns terminal suppression with no
|
|
831
|
-
send, no identifier and an ineligible sent timestamp. Arbitrary injected objects
|
|
832
|
-
are refused by `guardEmailTransport`; a provider name or copied capture shape
|
|
833
|
-
cannot establish admission. Package-created capture retains its ordered envelopes
|
|
834
|
-
and synthetic identifiers with no network effect. Capture acceptance remains
|
|
835
|
-
local acceptance, never evidence of external delivery.
|
|
836
|
-
|
|
837
|
-
`admitPolicyEnforcedEmailTransport` is the trusted host bridge for a transport
|
|
838
|
-
that already enforces egress internally, as the maintained reference client does.
|
|
839
|
-
The package registry owns its identity; this bridge performs no second routing
|
|
840
|
-
or credential decision. It is a composition trust boundary, not a sandbox for
|
|
841
|
-
host code: callers must not admit an unguarded network sender. New adapters should
|
|
842
|
-
use the validating constructor above. The reference default retains its original
|
|
843
|
-
sink/drop policy, key selection, optional payload fields, headers, signal and
|
|
844
|
-
result/error semantics. `createAuthEmailTransport` preserves the Auth envelope
|
|
845
|
-
mapping and admission; raw Auth closures are refused before their send method.
|
|
846
|
-
Admin/control and required-audit ordering stay at their existing callers.
|
|
847
|
-
No egress result authorizes a subscription-state or delivery-cycle mutation.
|
|
848
|
-
|
|
849
|
-
`processEmailObservation` accepts already authenticated, decoded and environment-admitted
|
|
850
|
-
input. It looks up a local send, constructs evidence only when found, applies one
|
|
851
|
-
observation and records best-effort telemetry. Lookup and apply failures propagate.
|
|
852
|
-
`runDeliveryReconciliation` polls candidates sequentially, rotates every non-404
|
|
853
|
-
read, and delegates consecutive failed-404 abandonment at threshold three to the
|
|
854
|
-
store. Rotation failure is counted without dropping delivery truth; apply failure
|
|
855
|
-
continues the batch. Candidate-query, read and not-found-store throws propagate.
|
|
856
|
-
The host classifies protocol snapshots after rotation and passes recipient/evidence
|
|
857
|
-
through unchanged. The existing reference domain entry points use both engines;
|
|
858
|
-
routes and schedules remain the same.
|
|
859
|
-
|
|
860
|
-
Neither engine writes suppression or subscription state. Both callback and poll
|
|
861
|
-
composition retain `communication_update_email_delivery_from_provider` as the
|
|
862
|
-
single durable convergence/suppression writer. These ports add no in-memory
|
|
863
|
-
replay authority, database store or second executor. Legacy transport identifier
|
|
864
|
-
fields remain compatibility residue; new ports use `messageId`.
|
|
865
|
-
|
|
866
|
-
`createCommunicationPurposeRegistry` composes immutable exact identifiers with a
|
|
867
|
-
mandatory `marketing` or `non-marketing` classification. Its built-ins cannot be
|
|
868
|
-
redeclared. Existing policy, token and newsletter schema calls keep their finite
|
|
869
|
-
defaults. Passing a registry to policy evaluation, token verification or
|
|
870
|
-
`createNewsletterIntegrationSchemas` recognizes its identifiers without granting
|
|
871
|
-
permission. Custom marketing purposes still require a grant and respect
|
|
872
|
-
suppression; built-in tester pause and permission rules stay in force.
|
|
873
|
-
|
|
874
|
-
`createRegisteredPublicPreferenceTokenPort` requires an explicit host persistence
|
|
875
|
-
function and passes the exact purpose and frozen classification to it. It creates
|
|
876
|
-
no sync event. Stock managed permission and newsletter-sync tables retain their
|
|
877
|
-
finite CHECKs; registering a purpose does not expand those stores. Additional
|
|
878
|
-
persistence and schema requirements belong to the adopter. No new purpose, table,
|
|
879
|
-
migration, preference UI, URL or default fan-out is installed.
|
|
880
|
-
|
|
881
|
-
`processNewsletterWebhookEvent` supplies the existing event → permission →
|
|
882
|
-
settlement sequence behind neutral ports. Reference HTTP admission and signature
|
|
883
|
-
mapping stay local. Explicit registered purposes survive permission writes;
|
|
884
|
-
purpose-less feedback still targets exactly the two existing marketing purposes.
|
|
885
|
-
Verified opt-in, suppression and replay rules are unchanged. Registered dispatch
|
|
886
|
-
checks the batch's purposes before provider effects and retains claim tokens,
|
|
887
|
-
echo and capability skips, retry behavior and counters. Sync-settled and accepted
|
|
888
|
-
receipts are distinct from delivered evidence. Existing job admission, binding,
|
|
889
|
-
leases, finish-run linkage and operator readback retain their host composition.
|
|
890
|
-
No shared sender pipeline is added: required audit and best-effort send paths
|
|
891
|
-
keep their distinct ordering and failure semantics.
|
|
892
|
-
|
|
893
|
-
`MarketingAutomationProviderPort` and `MarketingAutomationStorePort` describe
|
|
894
|
-
explicit scope, claim/generation fences, admission/deadlines, idempotency,
|
|
895
|
-
observations/history and ambiguity/backoff. The synthetic substitute-provider
|
|
896
|
-
conformance suite is an executable contract, not an installed worker or a remote
|
|
897
|
-
provider certification. Evidence carries opaque references; remote feedback does
|
|
898
|
-
not grant local consent. No trigger catalogue, schedule or provider activation
|
|
899
|
-
is supplied.
|
|
900
|
-
|
|
901
|
-
The required selection retains the moved-code witnesses and neutral package
|
|
902
|
-
characterization tests. The package W1 hook reader witnesses the Auth composition;
|
|
903
|
-
provider-specific reference test paths remain in the complete suite. The
|
|
904
|
-
[M04 ledger](../../docs/platform/plans/oss-m04-communications-triggers.md#verification-ledger)
|
|
905
|
-
records counted cases, separate boundary iterations and local timing provenance.
|
|
906
|
-
The clean-commit artifact gate enforces all merged caps, including the owner-read, measured limit on the complete contracts entry. Artifact admission still needs a
|
|
907
|
-
clean supervisor commit.
|
|
908
|
-
See the [M04 plan](../../docs/platform/plans/oss-m04-communications-triggers.md)
|
|
909
|
-
for scope, later waves and verification limits.
|
|
503
|
+
`./communications` provides host-composed communications services; `./communications/contracts` supplies pure content and browser contracts.
|
|
504
|
+
See the [communications recipe](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#communications-import) for migration, email rendering and native operations.
|
|
910
505
|
|
|
911
506
|
## Package artifact limits
|
|
912
507
|
|
|
@@ -919,145 +514,6 @@ for measured sizes, current caps, the S1 baseline refresh and refusal remedies.
|
|
|
919
514
|
Artifact checks require a clean package directory; `--manifest-only` supplies no
|
|
920
515
|
artifact evidence.
|
|
921
516
|
|
|
922
|
-
### Pure email content and browser rendering
|
|
923
|
-
|
|
924
|
-
`./communications/contracts` now exports `renderEmail`, the nine existing block
|
|
925
|
-
constructors, `guideCardBlock` and per-template content factories.
|
|
926
|
-
Each `create*ContentFactory` binds host-selected copy plus only the pure helpers
|
|
927
|
-
it uses: order-reference formatting, payment-cause wording or marketing footer.
|
|
928
|
-
Localized review routes remain in the reference helper.
|
|
929
|
-
In P3 no copy pack, brand, locale choice, environment reader, provider client or
|
|
930
|
-
sending policy moved into this entry. B2 adds the explicit neutral defaults below. The existing email DTOs remain its canonical types.
|
|
931
|
-
Reference `petName` compatibility inputs are translated to neutral `contextName`
|
|
932
|
-
by their existing facades. Complete subjects, preheaders, ordered blocks and
|
|
933
|
-
HTML/text remain byte-identical, including omitted and explicit optional fields.
|
|
934
|
-
|
|
935
|
-
Browser previews continue through those facades to contracts values only. Auth
|
|
936
|
-
uses its existing server hook factory with the same host renderer injection;
|
|
937
|
-
its inactive public content binding still refuses with 503. Standard Auth,
|
|
938
|
-
mail callback, integration-event and generic HTTP verification remain separate
|
|
939
|
-
policies with their existing raw-byte and replay behavior. No crypto refactor,
|
|
940
|
-
new entry, dependency or graph edge is part of P3.
|
|
941
|
-
|
|
942
|
-
The contracts conformance test compiles the complete entry with no Node types
|
|
943
|
-
and checks its value inventory and import closure. The cold consumer repeats the
|
|
944
|
-
exact inventory and renders with fetch forbidden and optional peers absent,
|
|
945
|
-
retaining all other consumer checks. Browser size measures every runtime export
|
|
946
|
-
of the built entry through `browserEntryBytes`; it never measures a tree-shaken
|
|
947
|
-
consumer subset. See the M04 ledger for the measured size, owner-read cap and
|
|
948
|
-
working-tree versus signed-candidate evidence limits.
|
|
949
|
-
|
|
950
|
-
P3's complete built contracts entry measures **5,992 B minified+gzip**;
|
|
951
|
-
the owner-read cap is **11,776 B**, rounded to the nearest 512 B at about
|
|
952
|
-
twice that measurement. Only this browser limit changes. Existing pack classes,
|
|
953
|
-
other browser limits and clean-candidate artifact checks remain binding.
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
M04 B2 adds four default factories in this same pure contracts entry:
|
|
957
|
-
`createInvoiceDocumentContentFactory`, `createRoleNotificationContentFactory`,
|
|
958
|
-
`createInquiryContentFactory` and `createOptOutContentFactory`. Each accepts an
|
|
959
|
-
optional complete bilingual copy replacement; each content call takes an explicit
|
|
960
|
-
`pl`/`en` locale. Invoice takes resolved order/document references, kind and account
|
|
961
|
-
URL; role takes role, operator URL and optional pending expiry. Inquiry builds
|
|
962
|
-
receipt/notice blocks from caller details, signoff and URL without sending or
|
|
963
|
-
promising a response time. Opt-out returns display strings for seven outcomes;
|
|
964
|
-
it verifies no token and writes no consent. Hosts own brand, locale selection,
|
|
965
|
-
URLs, policy and delivery.
|
|
966
|
-
|
|
967
|
-
The reference invoice adapter defaults to its byte-identical Polish output; explicit
|
|
968
|
-
construction locale EN maps to `/account?sekcja=orders`, while the production
|
|
969
|
-
composition still omits locale. All existing role outputs remain identical.
|
|
970
|
-
The reference opt-out page now selects Polish/EN throughout, escapes display values,
|
|
971
|
-
and uses neutral selected-communications/service-message wording. Its methods,
|
|
972
|
-
verification, purpose allowlist, durable RPC, headers and statuses are unchanged.
|
|
973
|
-
Generic inquiry is only a pure binding; the existing private-label sender stays
|
|
974
|
-
unchanged. Invoice/role gain Polish canon previews; no sender/registry activation.
|
|
975
|
-
See the [complete B2 expectation ledger](../../docs/platform/plans/oss-m04-communications-triggers.md#b2-changed-expectations-and-preservation)
|
|
976
|
-
and [default conformance tests](test/communications/contentDefaults.test.ts).
|
|
977
|
-
The measured B2 contracts entry is 8,210 B minified+gzip under the unchanged
|
|
978
|
-
11,776 B cap; this is a local built-entry measurement, not release admission.
|
|
979
|
-
|
|
980
|
-
### Native communications operations (development preview)
|
|
981
|
-
|
|
982
|
-
The server entry `@openlup/platform/communications` additionally exports
|
|
983
|
-
`createPostgresDeliveryReconciliationPort`, `createPostgresCommunicationSyncStore`,
|
|
984
|
-
`createPostgresNotificationRecipientsPort` and `createPostgresConsentEvaluator`.
|
|
985
|
-
Install the complete canonical manifest through position 70 before selecting
|
|
986
|
-
these factories. `COMMUNICATIONS_MIGRATIONS` now projects positions 2, 9, 20 and
|
|
987
|
-
70; it remains a sparse inventory, not an installer. Missing schema/configuration
|
|
988
|
-
is an error, never an empty queue or an allow decision.
|
|
989
|
-
|
|
990
|
-
Each factory owns a capability-local, role-free transaction lane and lazy `pg`
|
|
991
|
-
pool, with `close()` for host cleanup. Only a trusted host may hold these owner
|
|
992
|
-
credentials. Effective PUBLIC/browser table, column and inherited privileges
|
|
993
|
-
cause refusal; the CREATE-only forward intentionally changes no old ACL or role.
|
|
994
|
-
Do not expose a factory or its database lane to browser callers. The directory
|
|
995
|
-
requires a verified active human operator, live communications authorization and
|
|
996
|
-
absence of machine authority in the same transaction as each operation.
|
|
997
|
-
|
|
998
|
-
A host registers `evidence: "network_accepted"` only after actual network
|
|
999
|
-
acceptance, with a unique source key and binding. Capture is never registered as
|
|
1000
|
-
a network target. Polls and admitted callbacks call the same `applyObservation`
|
|
1001
|
-
writer; observation-key replay must preserve the immutable fact. Readback keeps
|
|
1002
|
-
acceptance, observed state, attempt/404 counts and abandonment separate. Only
|
|
1003
|
-
three consecutive 404s abandon a candidate; abandonment is not failed/delivered.
|
|
1004
|
-
Bounce/complaint writes the authoritative fingerprint's suppression atomically.
|
|
1005
|
-
No subscription or renewal state is changed.
|
|
1006
|
-
|
|
1007
|
-
For newsletter sync, inject `rail: db => createPostgresOutboxStore(db)` from
|
|
1008
|
-
`@openlup/outbox/postgres` in host composition. `db` is the current transaction,
|
|
1009
|
-
so claim commits before I/O and rail ack and sidecar settlement commit together.
|
|
1010
|
-
`registerWork` creates one existing-outbox identity for a source and target
|
|
1011
|
-
binding. Successive preferences for one contact/target share the rail aggregate,
|
|
1012
|
-
so newer work cannot overtake older unprocessed work. Configure a distinct
|
|
1013
|
-
binding per target/provider, and exclude
|
|
1014
|
-
`nativeSyncEventType(binding)` from generic dispatch registries. Invoke only
|
|
1015
|
-
`runCommunicationSyncDispatch` with an explicit neutral membership provider.
|
|
1016
|
-
The sidecar cannot claim work and has no lease or drainer. A membership settlement
|
|
1017
|
-
records sync progress, never email delivery; remote exactly-once effects are not
|
|
1018
|
-
promised across a process crash. There is no automatic backfill or activation.
|
|
1019
|
-
|
|
1020
|
-
Native consent evaluates registered P4 policy against the authoritative native
|
|
1021
|
-
permission and persists the decision before returning its id. Admin notices need
|
|
1022
|
-
an active source-bound notification recipient. Optional `testerPaused` reads
|
|
1023
|
-
host-owned authoritative pause state inside that transaction; omitted means no
|
|
1024
|
-
pause policy. The capability explicitly declares `managedFrequencyCaps: false`,
|
|
1025
|
-
`legacyContactTouching: false`, `sendTimeFence: false`: managed 16-hour / 2-day /
|
|
1026
|
-
4-week caps and legacy contact-touching are excluded. Evaluation does not fence a
|
|
1027
|
-
later send against changed consent. Custom-purpose persistence remains host-owned.
|
|
1028
|
-
|
|
1029
|
-
The [callable reference binding](../../server/runtime/communications/communicationsLifecycleBinding.ts)
|
|
1030
|
-
selects only `PLATFORM_BUNDLE=node-postgres` with `DATABASE_URL`; it closes pools
|
|
1031
|
-
on success/failure and supplies no network/provider default. Existing managed
|
|
1032
|
-
HTTP cron/UI routes retain their existing composition. See the
|
|
1033
|
-
[B3 expectation inventory](../../docs/platform/plans/oss-m04-communications-triggers.md#b3-native-stores)
|
|
1034
|
-
and [real-PG witnesses](../../tests/postgres/communicationsNative.test.ts).
|
|
1035
|
-
|
|
1036
|
-
C-compose extends the native delivery store with binding-scoped `findByMessageId`
|
|
1037
|
-
and bounded `listEvidence({limit})` (1–100). Existing observation/replay and polling
|
|
1038
|
-
methods retain their behavior. `registerPreference` on the native sync store
|
|
1039
|
-
commits an authoritative denied/suppressed permission and default-purpose sync
|
|
1040
|
-
work together; tester permission adds no marketing work. The trusted
|
|
1041
|
-
`registerNativeSyncWorkInTransaction` helper contains the same registration SQL
|
|
1042
|
-
used by `registerWork`; standalone input validation still precedes database entry.
|
|
1043
|
-
This helper is a trusted host transaction seam: its caller-owned executor must
|
|
1044
|
-
already hold the lane's safe effective privileges; the function does not check
|
|
1045
|
-
them. Standard native sync factory transactions check
|
|
1046
|
-
`public.communication_native_sync_state`, `public.outbox_events` and
|
|
1047
|
-
`public.communication_recipient_consents`. The caller owns the transaction and
|
|
1048
|
-
must commit or roll back permission, sidecar and existing-rail effects atomically.
|
|
1049
|
-
Use a safely admitted lane; the helper grants no claim token or provider authority.
|
|
1050
|
-
|
|
1051
|
-
Reference composition remains outside the package: actual installed factories,
|
|
1052
|
-
Core readiness, explicit provider ports and host-supplied schedules. Native
|
|
1053
|
-
readback and signed-token bridges do not promise managed frequency caps, legacy
|
|
1054
|
-
tester-source parity, a send-time fence or a full native network sender. The
|
|
1055
|
-
opt-in browser profile adds no npm entry or UI package export.
|
|
1056
|
-
|
|
1057
|
-
Source contributors record notable changes in package changelog fragments;
|
|
1058
|
-
release preparation assembles the shipped CHANGELOG. Follow the
|
|
1059
|
-
[public contribution guide](https://github.com/openlup/openlup/blob/main/CONTRIBUTING.md#development-preview-checks).
|
|
1060
|
-
|
|
1061
517
|
## Payments prepared attempts
|
|
1062
518
|
|
|
1063
519
|
`@openlup/platform/payments` exports `executePreparedAttemptMechanism`: validate before durable preparation, refuse prepared replay, dispatch once unless the host proves no charge, and retry one immutable local finalization. The host owns keys, fingerprints, nominal error trust and persistence. An unknown execution never authorizes redispatch. The reference facade retains its existing binding.
|
|
@@ -1241,3 +697,99 @@ readiness and simulator composition. Its prepared-attempt facade re-exports the
|
|
|
1241
697
|
same error class so `instanceof` preserves the no-charge trust boundary.
|
|
1242
698
|
The M07 factories' neutral envelopes and capability limits remain unchanged;
|
|
1243
699
|
reference-support availability establishes no provider activation or stable API.
|
|
700
|
+
|
|
701
|
+
## Fulfillment stock evidence replay
|
|
702
|
+
|
|
703
|
+
The fulfillment migration projection additionally includes the native
|
|
704
|
+
`20261022165000_fulfillment_stock_evidence_replay_reopen.sql` forward at canonical
|
|
705
|
+
position 76 in this catalogue. Install the complete chain before stock adoption.
|
|
706
|
+
Matching-fingerprint alert replay refreshes severity/quantities, reopens status and
|
|
707
|
+
clears `resolved_at`, preserving identity, first-seen time and historical resolver
|
|
708
|
+
metadata. Mismatches, including legacy 0.22.0 whole-input fingerprints, still
|
|
709
|
+
raise `23505`; no rewrite is supplied. See the [migration owner](../../docs/platform/DATA_AND_MIGRATIONS.md#module-catalogues-and-installed-histories)
|
|
710
|
+
for upgrade and operational-dependency proof.
|
|
711
|
+
|
|
712
|
+
## Subscription contracts and renewal port
|
|
713
|
+
|
|
714
|
+
The experimental `./subscriptions` entry exposes hosted renewal mechanisms and
|
|
715
|
+
an explicit native capability descriptor; `./subscriptions/contracts` is
|
|
716
|
+
browser-safe and type-only. The [subscription architecture and recipe](../../docs/platform/ARCHITECTURE_AND_EXTENSIONS.md#subscription-contracts)
|
|
717
|
+
owns the concrete ports, continuity rules, capability refusals and witnesses.
|
|
718
|
+
These entries do not install a store or activate a runner.
|
|
719
|
+
|
|
720
|
+
Native renewal and N1 retry stores accept injected SQL executors and explicit
|
|
721
|
+
snapshot/identity policy. The generic native executor consumes the subscription
|
|
722
|
+
ports; host composition supplies G23, M07, transaction and correlation policy.
|
|
723
|
+
The initial binding preserves case-before-outcome ordering with atomic bookkeeping.
|
|
724
|
+
N1's same-obligation recovery repairs the native decline stall (F16); it does not
|
|
725
|
+
supply M07 prepared-store parity or activate a runner.
|
|
726
|
+
|
|
727
|
+
## Invoicing contracts
|
|
728
|
+
|
|
729
|
+
Experimental `@openlup/platform/invoicing` exposes `readInvoiceCapabilities`;
|
|
730
|
+
`invoicing/contracts` contains types only. Host selection is explicit and default-off.
|
|
731
|
+
Frozen facts, correction recovery, exact absence, owed duties and host-only fiscal,
|
|
732
|
+
artifact, delivery, payout and owned-history seams are described in the
|
|
733
|
+
[invoicing reference](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#invoicing-contracts).
|
|
734
|
+
The contract entry supplies no executor or activation.
|
|
735
|
+
`createNativeUnsupportedInvoicePorts` supplies inert typed refusals for every
|
|
736
|
+
host, store and provider seam. `runInvoiceAdapterConformance` checks adapter-owned
|
|
737
|
+
offline fixtures; its sanitized evidence does not establish live fiscal readiness.
|
|
738
|
+
|
|
739
|
+
Issue helpers in `invoicing` preserve claim/preflight/projection/fresh-money/
|
|
740
|
+
create/fenced-finalize order. Hosts bind compatibility payloads, seller/date/tax
|
|
741
|
+
policy, captions, event descriptors and key scopes. Canonical and legacy line
|
|
742
|
+
checks share the unchanged donor allocation; handoff helpers register no job or
|
|
743
|
+
executor. Eight issue/line/payment/handoff cases join the existing package smoke
|
|
744
|
+
selection. Continuity cutover and activation remain separate.
|
|
745
|
+
|
|
746
|
+
Correction and reversal workers preserve durable identity, recovery and fenced
|
|
747
|
+
outcomes through host callbacks. The reference host requires a conforming
|
|
748
|
+
correction bridge; the legacy vendor method stays unselected. Reversal handlers pass
|
|
749
|
+
through the RPC action (`voided`, `correction_requested`, `corrected`, `no_invoice`). The required package
|
|
750
|
+
selection includes correction/reversal witnesses in `test/invoicing/contracts.test.ts`.
|
|
751
|
+
See the [invoicing design](../../docs/platform/plans/oss-m09-invoicing.md#p3-correction-and-reversal-boundary)
|
|
752
|
+
for managed migration and reconciliation limits.
|
|
753
|
+
|
|
754
|
+
See the [M09 forward owner](../../docs/platform/DATA_AND_MIGRATIONS.md#m09-invoicing-forward-design-and-control-approval) for the registered managed-correction limit and follow-up.
|
|
755
|
+
|
|
756
|
+
`createPostgresInvoiceStore` uses a caller-owned structural executor for native
|
|
757
|
+
owed duties, split fact leases, claims and fenced issue/correction results.
|
|
758
|
+
Missing host facts refuse before writes; clearance remains host work. Delivery
|
|
759
|
+
requires an explicit host envelope projection and M04 transport. `INVOICING_MIGRATIONS` separates native child-document and managed
|
|
760
|
+
base-row correction storage. Install the complete native catalogue, not its
|
|
761
|
+
seven sparse byte-identical SQL assets. The local-only Postgres adapter consumes
|
|
762
|
+
this store without claiming fiscal parity or registering a worker. The
|
|
763
|
+
[invoicing architecture owner](../../docs/platform/ARCHITECTURE_AND_EXTENSIONS.md#invoicing-contracts)
|
|
764
|
+
describes reversal recovery, capture faults and cutover fencing.
|
|
765
|
+
`collectInvoiceDuties` and `createIndependentInvoiceDutyBinding` collect retained
|
|
766
|
+
paid/handoff duties through separately committed store phases. Hosts invoke them
|
|
767
|
+
outside payment and fulfillment work; missing facts remain owed. The pinned
|
|
768
|
+
payment-decoupling SQL is a sparse catalogue projection, requiring the full P4
|
|
769
|
+
native chain. See the architecture owner for continuity and activation limits.
|
|
770
|
+
|
|
771
|
+
`runNativeInvoiceIssueJob` supplies the native create/readback binding over
|
|
772
|
+
explicit local/fresh money and provider ports. Fresh non-ready results settle
|
|
773
|
+
before returning; stale results write no failure. No scheduler or default
|
|
774
|
+
composition is registered. Operator DDL/ACL limits of the unchanged M07 readback
|
|
775
|
+
remain registered in the architecture owner.
|
|
776
|
+
|
|
777
|
+
For bounded duty discovery before facts exist, including cursor continuation past
|
|
778
|
+
unavailable facts, follow the [invoicing architecture owner](../../docs/platform/ARCHITECTURE_AND_EXTENSIONS.md#invoicing-contracts).
|
|
779
|
+
|
|
780
|
+
The invoicing read side adds `runInvoiceDeliveryJob`, `assertInvoicePdf`,
|
|
781
|
+
`invoicePdfFilename`, `syncAcceptedInvoiceDocuments`,
|
|
782
|
+
`syncInvoicePayoutSettlements`, `resolveInvoiceDocumentHistory` and
|
|
783
|
+
`createInvoiceReadModel`. Hosts supply authorization, storage, M04 transport,
|
|
784
|
+
terminal/backoff callbacks or the native store, and safe native history projection. See the
|
|
785
|
+
[read-helper recipe](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#invoicing-read-helpers).
|
|
786
|
+
|
|
787
|
+
`createInvoiceServices` and `createInvoiceContribution` compose the existing
|
|
788
|
+
helpers through `/invoicing`, with explicit selection, default-off and readiness
|
|
789
|
+
before execution. Native collection, issue, delivery, document/payout sync and
|
|
790
|
+
history use their module implementations; host facades may bind factories where
|
|
791
|
+
transport or query projection is host-owned. No executor is installed.
|
|
792
|
+
`claimInvoiceSellerRevision` selects a seller before leasing. The optional native
|
|
793
|
+
store seller binding and managed wrappers persist its first-ever claim revision;
|
|
794
|
+
legacy fallback and forward-only migration limits are owned by the
|
|
795
|
+
[M09 migration section](../../docs/platform/DATA_AND_MIGRATIONS.md#m09-invoicing-forward-design-and-control-approval).
|