@openlup/platform 0.28.0 → 0.29.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 +219 -18
- package/README.md +143 -4
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/index.js +1 -0
- package/dist/composition/marketingContribution.d.ts +21 -0
- package/dist/composition/marketingContribution.js +29 -0
- package/dist/marketing/acquisitionCaseSchemas.d.ts +103 -0
- package/dist/marketing/acquisitionCaseSchemas.js +53 -0
- package/dist/marketing/acquisitionEvidenceSchemas.d.ts +105 -0
- package/dist/marketing/acquisitionEvidenceSchemas.js +55 -0
- package/dist/marketing/analytics/dataLayer.d.ts +18 -0
- package/dist/marketing/analytics/dataLayer.js +111 -0
- package/dist/marketing/analytics/noop.d.ts +9 -0
- package/dist/marketing/analytics/noop.js +8 -0
- package/dist/marketing/analytics/purchaseFacts.d.ts +4 -0
- package/dist/marketing/analytics/purchaseFacts.js +69 -0
- package/dist/marketing/analytics/routePolicy.d.ts +10 -0
- package/dist/marketing/analytics/routePolicy.js +59 -0
- package/dist/marketing/consentEvidence.d.ts +8 -0
- package/dist/marketing/consentEvidence.js +32 -0
- package/dist/marketing/contactLegal.d.ts +14 -0
- package/dist/marketing/contactLegal.js +19 -0
- package/dist/marketing/contracts/acquisition.d.ts +88 -0
- package/dist/marketing/contracts/acquisition.js +1 -0
- package/dist/marketing/contracts/acquisitionPorts.d.ts +49 -0
- package/dist/marketing/contracts/acquisitionPorts.js +1 -0
- package/dist/marketing/contracts/analytics.d.ts +144 -0
- package/dist/marketing/contracts/analytics.js +1 -0
- package/dist/marketing/contracts/contactLegal.d.ts +53 -0
- package/dist/marketing/contracts/contactLegal.js +1 -0
- package/dist/marketing/contracts/index.d.ts +6 -0
- package/dist/marketing/contracts/index.js +1 -0
- package/dist/marketing/contracts/prelaunch.d.ts +39 -0
- package/dist/marketing/contracts/prelaunch.js +1 -0
- package/dist/marketing/index.d.ts +16 -0
- package/dist/marketing/index.js +14 -0
- package/dist/marketing/prelaunchAcquisitionSchemas.d.ts +116 -0
- package/dist/marketing/prelaunchAcquisitionSchemas.js +51 -0
- package/dist/marketing/seo/jsonLd.d.ts +157 -0
- package/dist/marketing/seo/jsonLd.js +127 -0
- package/dist/marketing/seo/metadata.d.ts +41 -0
- package/dist/marketing/seo/metadata.js +36 -0
- package/dist/marketing/seo/serializeJsonLd.d.ts +1 -0
- package/dist/marketing/seo/serializeJsonLd.js +6 -0
- package/dist/marketing/seo/urls.d.ts +14 -0
- package/dist/marketing/seo/urls.js +23 -0
- package/dist/marketing/server/acquisitionCaseDirect.d.ts +4 -0
- package/dist/marketing/server/acquisitionCaseDirect.js +88 -0
- package/dist/marketing/server/acquisitionCaseHandlers.d.ts +28 -0
- package/dist/marketing/server/acquisitionCaseHandlers.js +40 -0
- package/dist/marketing/server/acquisitionCasePorts.d.ts +42 -0
- package/dist/marketing/server/acquisitionCasePorts.js +1 -0
- package/dist/marketing/server/acquisitionEvidenceDirect.d.ts +5 -0
- package/dist/marketing/server/acquisitionEvidenceDirect.js +100 -0
- package/dist/marketing/server/analyticsContext.d.ts +3 -0
- package/dist/marketing/server/analyticsContext.js +65 -0
- package/dist/marketing/server/analyticsContextPorts.d.ts +31 -0
- package/dist/marketing/server/analyticsContextPorts.js +1 -0
- package/dist/marketing/server/bindings.d.ts +14 -0
- package/dist/marketing/server/bindings.js +18 -0
- package/dist/marketing/server/directPorts.d.ts +26 -0
- package/dist/marketing/server/directPorts.js +1 -0
- package/dist/marketing/server/index.d.ts +14 -0
- package/dist/marketing/server/index.js +11 -0
- package/dist/marketing/server/postgres/acquisitionCaseRoutines.d.ts +10 -0
- package/dist/marketing/server/postgres/acquisitionCaseRoutines.js +204 -0
- package/dist/marketing/server/postgres/acquisitionEvidenceRoutines.d.ts +10 -0
- package/dist/marketing/server/postgres/acquisitionEvidenceRoutines.js +107 -0
- package/dist/marketing/server/postgres/index.d.ts +3 -0
- package/dist/marketing/server/postgres/index.js +3 -0
- package/dist/marketing/server/prelaunchAcquisitionDirect.d.ts +4 -0
- package/dist/marketing/server/prelaunchAcquisitionDirect.js +122 -0
- package/dist/marketing/server/privacyContributor.d.ts +66 -0
- package/dist/marketing/server/privacyContributor.js +87 -0
- package/dist/marketing/server/research/adminSurveyResponsesHandler.d.ts +9 -0
- package/dist/marketing/server/research/adminSurveyResponsesHandler.js +53 -0
- package/dist/marketing/server/research/managedSurveyResponseSubmit.d.ts +39 -0
- package/dist/marketing/server/research/managedSurveyResponseSubmit.js +102 -0
- package/dist/marketing/server/research/surveyResponseSubmitHandler.d.ts +8 -0
- package/dist/marketing/server/research/surveyResponseSubmitHandler.js +41 -0
- package/dist/marketing/validation.d.ts +2 -0
- package/dist/marketing/validation.js +3 -0
- package/package.json +22 -2
- package/release-gates.json +72 -4
- package/src/composition/index.ts +1 -0
- package/src/composition/marketingContribution.ts +37 -0
- package/src/marketing/acquisitionCaseSchemas.ts +75 -0
- package/src/marketing/acquisitionEvidenceSchemas.ts +72 -0
- package/src/marketing/analytics/dataLayer.ts +100 -0
- package/src/marketing/analytics/noop.ts +14 -0
- package/src/marketing/analytics/purchaseFacts.ts +63 -0
- package/src/marketing/analytics/routePolicy.ts +55 -0
- package/src/marketing/consentEvidence.ts +36 -0
- package/src/marketing/contactLegal.ts +22 -0
- package/src/marketing/contracts/acquisition.ts +50 -0
- package/src/marketing/contracts/acquisitionPorts.ts +48 -0
- package/src/marketing/contracts/analytics.ts +88 -0
- package/src/marketing/contracts/contactLegal.ts +41 -0
- package/src/marketing/contracts/index.ts +17 -0
- package/src/marketing/contracts/prelaunch.ts +15 -0
- package/src/marketing/index.ts +16 -0
- package/src/marketing/prelaunchAcquisitionSchemas.ts +64 -0
- package/src/marketing/seo/jsonLd.ts +153 -0
- package/src/marketing/seo/metadata.ts +62 -0
- package/src/marketing/seo/serializeJsonLd.ts +6 -0
- package/src/marketing/seo/urls.ts +34 -0
- package/src/marketing/server/acquisitionCaseDirect.ts +67 -0
- package/src/marketing/server/acquisitionCaseHandlers.ts +57 -0
- package/src/marketing/server/acquisitionCasePorts.ts +42 -0
- package/src/marketing/server/acquisitionEvidenceDirect.ts +76 -0
- package/src/marketing/server/analyticsContext.ts +55 -0
- package/src/marketing/server/analyticsContextPorts.ts +28 -0
- package/src/marketing/server/bindings.ts +27 -0
- package/src/marketing/server/directPorts.ts +27 -0
- package/src/marketing/server/index.ts +14 -0
- package/src/marketing/server/postgres/acquisitionCaseRoutines.ts +218 -0
- package/src/marketing/server/postgres/acquisitionEvidenceRoutines.ts +103 -0
- package/src/marketing/server/postgres/index.ts +3 -0
- package/src/marketing/server/prelaunchAcquisitionDirect.ts +121 -0
- package/src/marketing/server/privacyContributor.ts +123 -0
- package/src/marketing/server/research/adminSurveyResponsesHandler.ts +78 -0
- package/src/marketing/server/research/managedSurveyResponseSubmit.ts +158 -0
- package/src/marketing/server/research/surveyResponseSubmitHandler.ts +57 -0
- package/src/marketing/validation.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,225 @@ in the source repository.
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [0.29.0]
|
|
14
|
+
|
|
15
|
+
- Publishable on the npm `latest` dist-tag as `0.29.0`, from tag
|
|
16
|
+
`openlup-platform-v0.29.0`.
|
|
17
|
+
|
|
18
|
+
Adds experimental browser-safe marketing runtime contracts and a type-only
|
|
19
|
+
contracts entry through unchanged schema movement and reference import rebinding.
|
|
20
|
+
Core research remains the compatibility owner. Parsing, defaults, issue details
|
|
21
|
+
and order, and existing inferred input/output types retain their behavior.
|
|
22
|
+
|
|
23
|
+
Migration: No observable divergence is introduced for existing reference consumers; shims retain their exported names and schema object identities.
|
|
24
|
+
Migration: New public subpath `@openlup/platform/marketing` exposes browser-safe runtime contracts without a server entry.
|
|
25
|
+
Migration: New public subpath `@openlup/platform/marketing/contracts` exposes types only, with no Zod or runtime-module imports.
|
|
26
|
+
Migration: New public export `ACQUISITION_CASE_CONTRACT_VERSION` is available from `@openlup/platform/marketing`.
|
|
27
|
+
Migration: New public export `ACQUISITION_CASE_VIEW` is available from `@openlup/platform/marketing`.
|
|
28
|
+
Migration: New public export `ACQUISITION_CASE_SOURCE` is available from `@openlup/platform/marketing`.
|
|
29
|
+
Migration: New public export `acquisitionOpaqueReferenceSchema` is available from `@openlup/platform/marketing`.
|
|
30
|
+
Migration: New public export `acquisitionAddressReferenceSchema` is available from `@openlup/platform/marketing`.
|
|
31
|
+
Migration: New public export `acquisitionCaseStateSchema` is available from `@openlup/platform/marketing`.
|
|
32
|
+
Migration: New public export `acquisitionCaseProjectionSchema` is available from `@openlup/platform/marketing`.
|
|
33
|
+
Migration: New public export `acquisitionCaseListRequestSchema` is available from `@openlup/platform/marketing`.
|
|
34
|
+
Migration: New public export `acquisitionCaseListResponseSchema` is available from `@openlup/platform/marketing`.
|
|
35
|
+
Migration: New public export `acquisitionCaseActiveCountResponseSchema` is available from `@openlup/platform/marketing`.
|
|
36
|
+
Migration: New public export `acquisitionIdempotencyKeySchema` is available from `@openlup/platform/marketing`.
|
|
37
|
+
Migration: New public export `ACQUISITION_SURVEY_VERSION` is available from `@openlup/platform/marketing`.
|
|
38
|
+
Migration: New public export `ACQUISITION_NEWSLETTER_VERSION` is available from `@openlup/platform/marketing`.
|
|
39
|
+
Migration: New public export `acquisitionSurveySubmitSchema` is available from `@openlup/platform/marketing`.
|
|
40
|
+
Migration: New public export `acquisitionSurveyEvidenceSchema` is available from `@openlup/platform/marketing`.
|
|
41
|
+
Migration: New public export `acquisitionSurveySubmitResponseSchema` is available from `@openlup/platform/marketing`.
|
|
42
|
+
Migration: New public export `acquisitionSurveyListQuerySchema` is available from `@openlup/platform/marketing`.
|
|
43
|
+
Migration: New public export `acquisitionSurveyListResponseSchema` is available from `@openlup/platform/marketing`.
|
|
44
|
+
Migration: New public export `acquisitionNewsletterConsentEventSchema` is available from `@openlup/platform/marketing`.
|
|
45
|
+
Migration: New public export `acquisitionNewsletterConsentResponseSchema` is available from `@openlup/platform/marketing`.
|
|
46
|
+
Migration: New public export `marketingResearchJsonSchema` is available from `@openlup/platform/marketing` with its core object identity.
|
|
47
|
+
Migration: New public export `researchSurveyTypeSchema` is available from `@openlup/platform/marketing` with its core object identity.
|
|
48
|
+
Migration: New public export `adminSurveyResponsesRequestSchema` is available from `@openlup/platform/marketing` with its core object identity.
|
|
49
|
+
Migration: New public export `adminSurveyResponseRowSchema` is available from `@openlup/platform/marketing` with its core object identity.
|
|
50
|
+
Migration: New public export `adminSurveyResponsesResponseSchema` is available from `@openlup/platform/marketing` with its core object identity.
|
|
51
|
+
Migration: New public export `researchSurveySubmitRequestSchema` is available from `@openlup/platform/marketing` with its core object identity.
|
|
52
|
+
Migration: New public export `researchSurveySubmitResponseSchema` is available from `@openlup/platform/marketing` with its core object identity.
|
|
53
|
+
Migration: New public type `AcquisitionOpaqueReference` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
54
|
+
Migration: New public type `AcquisitionAddressReference` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
55
|
+
Migration: New public type `AcquisitionCaseState` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
56
|
+
Migration: New public type `AcquisitionCaseProjection` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
57
|
+
Migration: New public type `AcquisitionCaseListRequest` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
58
|
+
Migration: New public type `AcquisitionCaseListResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
59
|
+
Migration: New public type `AcquisitionCaseActiveCountResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
60
|
+
Migration: New public type `AcquisitionIdempotencyKey` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
61
|
+
Migration: New public type `AcquisitionSurveySubmit` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
62
|
+
Migration: New public type `AcquisitionSurveyEvidence` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
63
|
+
Migration: New public type `AcquisitionSurveySubmitResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
64
|
+
Migration: New public type `AcquisitionSurveyListQuery` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
65
|
+
Migration: New public type `AcquisitionSurveyListResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
66
|
+
Migration: New public type `AcquisitionNewsletterConsentEvent` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
67
|
+
Migration: New public type `AcquisitionNewsletterConsentResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
68
|
+
Migration: New public type `MarketingResearchJson` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
69
|
+
Migration: New public type `ResearchSurveyType` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
70
|
+
Migration: New public type `AdminSurveyResponsesRequest` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
71
|
+
Migration: New public type `AdminSurveyResponseRow` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
72
|
+
Migration: New public type `AdminSurveyResponsesResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
73
|
+
Migration: New public type `ResearchSurveySubmitRequest` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
74
|
+
Migration: New public type `ResearchSurveySubmitResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
75
|
+
Migration: New public type `MarketingResearchSurveyResponsesReadPort` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
76
|
+
Migration: New public type `MarketingResearchSurveyRequestHeaders` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
77
|
+
Migration: New public type `MarketingResearchSurveySubmitPort` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
78
|
+
Migration: `en|pl` locale restriction is known debt tied to the persisted CHECK; locale widening needs a future migration and is outside M13 scope.
|
|
79
|
+
Migration: Retired acquisition case submit/transition request and response contracts and the app-owned client-version binding are intentionally not published.
|
|
80
|
+
Migration: New public export `PRELAUNCH_ACQUISITION_VIEW` is available from `@openlup/platform/marketing`.
|
|
81
|
+
Migration: New public export `PRELAUNCH_ACQUISITION_CONTRACT_VERSION` is available from `@openlup/platform/marketing`.
|
|
82
|
+
Migration: New public export `prelaunchAcquisitionListRequestSchema` is available from `@openlup/platform/marketing`.
|
|
83
|
+
Migration: New public export `prelaunchAcquisitionDetailRequestSchema` is available from `@openlup/platform/marketing`.
|
|
84
|
+
Migration: New public export `prelaunchAcquisitionLeadSchema` is available from `@openlup/platform/marketing`.
|
|
85
|
+
Migration: New public export `prelaunchAcquisitionListResponseSchema` is available from `@openlup/platform/marketing`.
|
|
86
|
+
Migration: New public export `prelaunchAcquisitionDetailResponseSchema` is available from `@openlup/platform/marketing`.
|
|
87
|
+
Migration: New public type `AcquisitionCaseFailureKind` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
88
|
+
Migration: New public type `AcquisitionCaseResult` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
89
|
+
Migration: New public type `AcquisitionCaseListQuery` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
90
|
+
Migration: New public type `AcquisitionCaseGetQuery` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
91
|
+
Migration: New public type `AcquisitionCasePort` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
92
|
+
Migration: New public type `AcquisitionEvidenceFailure` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
93
|
+
Migration: New public type `AcquisitionEvidenceResult` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
94
|
+
Migration: New public type `AcquisitionEvidencePort` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
95
|
+
Migration: New public type `PrelaunchAcquisitionListRequest` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
96
|
+
Migration: New public type `PrelaunchAcquisitionDetailRequest` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
97
|
+
Migration: New public type `PrelaunchAcquisitionLead` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
98
|
+
Migration: New public type `PrelaunchAcquisitionListResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
99
|
+
Migration: New public type `PrelaunchAcquisitionDetailResponse` is available from `@openlup/platform/marketing` and `@openlup/platform/marketing/contracts`.
|
|
100
|
+
Migration: The rich prelaunch DTO and retired acquisition case submit/transition port methods and commands are intentionally not published.
|
|
101
|
+
Migration: The marketing runtime entry configures the shared Zod instance in jitless mode on load, the same as the pricing, catalog and communications entries; the type-only marketing/contracts entry has no runtime initialization.
|
|
102
|
+
|
|
103
|
+
Adds experimental Node-only marketing server factories through unchanged
|
|
104
|
+
acquisition, research and PostgreSQL algorithm movement. Host composition retains
|
|
105
|
+
routing, environment, authorization, observed wrappers and notification copy.
|
|
106
|
+
Browser marketing entries retain their isolated schema/type-only boundaries.
|
|
107
|
+
|
|
108
|
+
Migration: New public subpath `@openlup/platform/marketing/server` contains acquisition case handlers, direct acquisition history and prelaunch reads, survey evidence and consent commands, research handlers and managed survey orchestration.
|
|
109
|
+
Migration: PostgreSQL port factories are published separately under `@openlup/platform/marketing/server/postgres` so the server entry does not load the existing optional `pg` peer. Select `/postgres` with that peer installed. Reference bindings load the adapter lazily after their bundle and connection guards. SQL text, signatures, role selection, pool creation and transaction handling retain their behavior.
|
|
110
|
+
Migration: `createAdminClientsTestersDirectHandler` maps to the neutral package symbol `createAcquisitionCaseListDirectHandler`; `createTesterProgramActiveCountDirectHandler` maps to `createAcquisitionCaseActiveCountDirectHandler`. The reference retains both original factory names and route registrations.
|
|
111
|
+
Migration: `handleAcquisitionSurveySubmit`, `handleAcquisitionSurveyList` and `handleAcquisitionNewsletterConsent` compose `createAcquisitionSurveySubmitDirectHandler`, `createAcquisitionSurveyListDirectHandler` and `createAcquisitionNewsletterConsentDirectHandler`, respectively. Successful evidence values remain forwarded without response-schema validation.
|
|
112
|
+
Migration: Direct factories receive the host BFF responder, authorization callback and binding resolver. Acquisition list/count additionally receive the direct-bundle predicate at its original guard position. Prelaunch/evidence bundle and request-view dispatch remain with host callers; no additional guard is introduced.
|
|
113
|
+
Migration: Research submit/admin handler dependencies receive the BFF responder and use platform HTTP types. Research schemas and ports retain the `@openlup/core/marketing/research` compatibility owner. Delivery types retain their communications/contracts owner.
|
|
114
|
+
Migration: Managed survey submission receives `renderNotificationHtml(type, responseData, id)` and `notificationSubject(type, now)`. HTML renders before the subject clock read, after policy filtering. The host retains subject/HTML copy and escaping; rendered values reach delivery unchanged.
|
|
115
|
+
Migration: Server-only structural submit/transition request and command types retain the historical adapter signatures without adding schemas or changing either browser entry. Retired route factories, terminal refusals, admin auth binding, observed wrappers and raw signed consent ingress remain application-owned.
|
|
116
|
+
Migration: Reference acquisition handler and PostgreSQL adapter paths retain thin package re-exports; runtime bindings retain lazy adapter imports. Reference research handler files bind the responder, and managed submission binds notification copy while retaining live host configuration reads. Prelaunch rich read models and admin leads remain application-owned.
|
|
117
|
+
Migration: Neutral characterization lives under `packages/platform/test/marketing/server/`, including the complete survey/consent direct-handler witness. Six superseded reference test files are removed: acquisition case handlers, both PostgreSQL adapters, prelaunch direct handlers, research submit handler and research admin responses handler. Each asserts only package-owned behavior.
|
|
118
|
+
Migration: Reference direct acquisition tests retain retirement and real admin-auth assertions. Reference prelaunch route tests and evidence direct tests retain host composition coverage. Managed submission retains only reference-side copy/escaping coverage; package tests assert the synthetic renderer seam and ordering.
|
|
119
|
+
Migration: Real PostgreSQL parity lives at `tests/postgres/acquisitionEvidenceParity.test.ts`, imports package factories from `/marketing/server/postgres`, applies the hash-checked manifest prefix and connects all ports using a login granted only runtime-role membership. Missing Docker throws instead of skipping. The fixture owner is used only for setup, state inspection and the donor's append-only trigger proof; separate runtime-role mutation assertions retain privilege-denial coverage in the same case. The witness retains 11 cases. Test rows use deterministic synthetic identifiers and timestamps, and emails use `example.invalid`.
|
|
120
|
+
Migration: The installed consumer exercises a historical count and a conflict refusal with injected bindings without optional peers. The `/postgres` entry receives missing-peer import refusal and selected-peer factory/refusal checks through the existing adapter proof. One package-boundary bundle case prevents the server entry from reaching PostgreSQL adapters or `pg`, bringing the additive seam cases to seven within the eight-case limit. Exact export, API and package-smoke inventories include both server entries; artifact caps, dependencies, migrations and grants are unchanged.
|
|
121
|
+
|
|
122
|
+
The browser-safe marketing surface provides inert analytics defaults, independently attempted local sinks, injected route policy, paid purchase projection and historical consent-time selection. The reference application binds its existing policy and wire names while preserving its purchase transcript. Local admission booleans establish synchronous acceptance only, never delivery.
|
|
123
|
+
|
|
124
|
+
Migration: `AnalyticsStepName<StepName = string>` and `AnalyticsEventMap<StepName = string>` accept host step literals instead of a product-specific union. `AnalyticsCheckoutItem`, `AnalyticsPurchaseItem`, `AnalyticsCheckoutMode`, `AnalyticsPaymentWaitOutcome` and `AnalyticsEventName` retain the neutral event vocabulary. Types are also available type-only through `./marketing/contracts`.
|
|
125
|
+
Migration: `createNoopAnalytics` reuses the existing core `AnalyticsPort`. `initializeDeploymentAnalytics`, `trackDeploymentEvent`, `syncAdvertisingConsent` and `trackAdvertisingPurchase` are inert defaults.
|
|
126
|
+
Migration: The donor-only transport ownership field and provider-specific purchase envelope, transport result and transport types are excluded private transport concerns; hosts extend their own event map outside the package.
|
|
127
|
+
Migration: `createAnalyticsDataLayer` replaces module-global mutable state with per-instance state. `AnalyticsDataLayerOptions` injects consent storage/event names, event prefix, container reader, deployment callback and browser access. Defaults are inert. `AnalyticsBrowserWindow`, `AnalyticsCookieConsent`, `AnalyticsSinkAttemptMask` and `AnalyticsSinkAdmission` describe those seams. Host bindings retain historical literals. Consent command arguments, ordering, parse rules, push-time advertising grants and independent synchronous admission are preserved; no pre-consent replay is added.
|
|
128
|
+
Migration: Hosts must supply `AnalyticsDataLayerOptions.consentSignalNames` to enable optional event admission and consent commands: one `analytics` wire name and ordered `advertising` wire names. Omission pushes no consent commands and returns false from `pushAnalyticsEvent`, even with browser access, a container and stored consent; deployment sink attempts are unaffected. Supplied settings retain the analytics key first, then advertising keys in host order, with unchanged consent values.
|
|
129
|
+
Migration: `createAnalyticsRoutePolicy` takes required `AnalyticsRoutePolicyInput` public paths, redirect sources and sensitive sets; there is no ambient route manifest or default sensitive-path policy. `normalizeAnalyticsPathname` preserves normalization. The returned optional-route eligibility method uses a neutral name; hosts alias their historical name.
|
|
130
|
+
Migration: `projectPaidPurchase`, structural `PurchaseOrder` and `PurchaseSuppressionReason` preserve paid allocation, grouping, residual shipping, cap and ordered refusal logic. Currency is a plain string with no ambient currency initialization. The reference guards unsupported kinds before projection through a null input, preserving its renewal refusal and order/payment precedence; the package admits renewal as subscription, matching the donor.
|
|
131
|
+
Migration: `selectMarketingHistoricalConsentTime`, `MarketingHistoricalConsentCommand`, `MarketingHistoricalConsentState` and `MarketingHistoricalConsentResult` expose only chronology facts and the exact compared state literals. Command authorization, persistence and workers stay with the host.
|
|
132
|
+
Migration: `createAnalyticsContextHandler` is exported only by `./marketing/server`, with server-only `AnalyticsContextHandlerDeps`, `AnalyticsContextPersistencePort`, `AnalyticsContextStoreResolver` and `AnalyticsContextCapabilityCrypto`. Platform `HttpRequest`/`HttpResponse` and a required host `BffResponder` replace application HTTP/envelope imports; the host keeps its route path and observability wrapper.
|
|
133
|
+
Migration: The context handler requires an `isEnabled` reader instead of reading an ambient flag. The host retains the flag name and exact enabled-value comparison; the package has no enabling default. Method, flag, origin and strict request-schema refusal order and error codes/messages are preserved. The schema uses the package's jitless validation wrapper.
|
|
134
|
+
Migration: `AnalyticsContextHandlerDeps.clientIdField` is a required host binding for the historical client-id wire field name. Each handler builds its strict schema once with that key, retaining the numeric-dot-numeric pattern, 64-character limit, optional field, `explicitGrant` default false and granted-requires-client-id refusal. Internal and persistence fields remain `clientId`; hosts retain their serving wire names.
|
|
135
|
+
Migration: The host supplies `capabilityCrypto.mintToken` and `hashToken` instead of built-in cryptography, and `cookieName` as the historical compatibility input. Minting must provide opaque 32-byte lowercase hexadecimal tokens and hashing must preserve the host's cryptographic digest. Cookie parsing still selects the first matching name, accepts only 64 lowercase hexadecimal characters and hashes the token; mint timing, cookie attributes and explicit no-store placement are unchanged.
|
|
136
|
+
Migration: `resolveStore` replaces the application gateway lookup; null still refuses with `UPSTREAM_UNAVAILABLE`. `AnalyticsContextPersistencePort.syncContext` receives token hash, granted and client id, and `enrollSubscriptions` receives the verified subject and context hash. These throwing operations replace the application RPC-call wrapper; the host keeps RPC names, argument translation, error-to-throw handling and gateway service authority. Only literal true is active. No default persistence or portable SQL exists, and no reference route is added; a host must supply persistence before mounting the handler.
|
|
137
|
+
Migration: Required `readAccessToken` and `resolveTrustedSubject` bindings replace application authentication imports. The host verifies the bearer under its service authority; invalid bearer grants still refuse before writes, withdrawal needs no identity, and enrollment uses only the verified subject. Explicit regrant replacement, revoked predecessor retention and `{ active }` responses are unchanged. An active result is a local context fact, never delivery; telemetry context failure never gates commerce.
|
|
138
|
+
|
|
139
|
+
Extend the experimental browser-safe `@openlup/platform/marketing` entry with
|
|
140
|
+
JSON-LD serialization and graphs, route URLs and hreflang, an ordered head
|
|
141
|
+
descriptor and contact/legal plain-data projections. Contact/legal/privacy
|
|
142
|
+
content contracts are type-only exports from `@openlup/platform/marketing/contracts`
|
|
143
|
+
and the runtime entry. Applications supply all identity, origin, locale, image,
|
|
144
|
+
document and processor facts. Responsibility-specific source files re-export
|
|
145
|
+
through the existing marketing barrel without adding a subpath, renderer,
|
|
146
|
+
dependency, network call or application policy. Fresh synthetic conformance and
|
|
147
|
+
browser-bundle tests, API declaration snapshots and the installed consumer
|
|
148
|
+
witness both entries.
|
|
149
|
+
|
|
150
|
+
Donor divergences: entity facts, lifecycle-selected organization type, contact
|
|
151
|
+
type/languages, image URLs/dimensions, route registry, default locale and social
|
|
152
|
+
metadata become explicit inputs. Product brand prefixing, fixed category,
|
|
153
|
+
audience, fallback weight and image-slug lookup are removed; category, images,
|
|
154
|
+
SKU, GTIN and net content are caller supplied or omitted. The fixed locale union
|
|
155
|
+
becomes strings, and FAQ fields use neutral question/answer names. The private
|
|
156
|
+
image variant helper, language detection and unregistered-route alternate escape
|
|
157
|
+
hatch remain application concerns. The head's canonical input uses the injected
|
|
158
|
+
route contract instead of the donor's loose absolute-URL passthrough.
|
|
159
|
+
The head requires application-supplied image width, image height and Twitter
|
|
160
|
+
handle, and emits `og:image:width`, `og:image:height` and `twitter:site`
|
|
161
|
+
unconditionally in donor order. `og:locale:alternate` remains conditional on
|
|
162
|
+
a supplied alternate locale.
|
|
163
|
+
|
|
164
|
+
Contact shaping uses supplied support email, shared organization facts, address
|
|
165
|
+
text and ordered registration label/value pairs in place of private identity
|
|
166
|
+
constants and country-specific identifiers. The optional `registrationAuthority`
|
|
167
|
+
line is absent only when its input is undefined; supplied blank company lines
|
|
168
|
+
are retained. Legal shaping takes supplied title, intro and ordered title/body
|
|
169
|
+
sections in place of fixed translation keys and section inventories. The
|
|
170
|
+
last-updated text is optional; supplied blank text is retained. Page markup,
|
|
171
|
+
translations, navigation and other contact copy remain application-owned.
|
|
172
|
+
Privacy processor disclosures are new structural types, with no projection.
|
|
173
|
+
|
|
174
|
+
The reference `SeoHead` adapter renders the descriptor through the existing
|
|
175
|
+
`react-helmet-async` dependency with `defer={false}`, removes unmanaged shell
|
|
176
|
+
canonical/alternate links after client commit only in the host-supplied `csr`
|
|
177
|
+
render mode (as in the donor), and emits the serialized JSON-LD
|
|
178
|
+
unchanged. These donor host behaviours stay outside the package. The adapter
|
|
179
|
+
has no serving-route mount; mounting is a later integration. Its tests witness
|
|
180
|
+
hidden-document commits, hostile script data and shell canonical replacement.
|
|
181
|
+
|
|
182
|
+
Migration: none. Both entries are extended additively; no SQL or application route changes.
|
|
183
|
+
|
|
184
|
+
The experimental `createMarketingContribution` helper in
|
|
185
|
+
`@openlup/platform/composition` describes selected marketing callables as an inert
|
|
186
|
+
`marketing` capability providing `./marketing`, `./marketing/contracts` and
|
|
187
|
+
`./marketing/server`, depending on identity's `./identity/contracts` runtime
|
|
188
|
+
obligation schema.
|
|
189
|
+
Handlers are projected to descriptors without `handle`; ports, routes and
|
|
190
|
+
triggers retain supplied callable identity. Duplicate registration identities
|
|
191
|
+
refuse, and null ports remain required without creating callable bindings.
|
|
192
|
+
|
|
193
|
+
Divergences from the donor: no donor composition exists; this helper supplies
|
|
194
|
+
descriptors only; no worker, route or schedule is installed.
|
|
195
|
+
|
|
196
|
+
Migration: Import `createMarketingContribution` from `@openlup/platform/composition` and supply already-bound operations, handler registrations, routes, schedules and host schema requirements explicitly.
|
|
197
|
+
Migration: Bind each required operation under `@openlup/platform/marketing:<name>`; a null operation remains a Core readiness obligation and reports `OPENLUP_E_PORT_MISSING` until bound.
|
|
198
|
+
Migration: The helper invokes no operation during construction. Host admission and installation of workers, routes and schedules remain application-owned.
|
|
199
|
+
|
|
200
|
+
The existing `./marketing/server` entry additionally exports the marketing privacy
|
|
201
|
+
contributor and default-off binding. Both complete owner ports and explicit
|
|
202
|
+
enablement select one contributor, shared by the callables supplied to composition.
|
|
203
|
+
Unbound or partial ownership reports unavailable coverage and unresolved
|
|
204
|
+
obligations; identity refuses erasure before owner effects. Identity owns the
|
|
205
|
+
subscriptions veto, receipt replay and rollback. The fence runs only during
|
|
206
|
+
`eraseOrRetain`, after all assessments; fence failure throws without owner text.
|
|
207
|
+
Accepted provider requests retain an accepted-not-observed reason and never
|
|
208
|
+
claim deletion or complete remote export coverage.
|
|
209
|
+
|
|
210
|
+
Donor divergences: worker, operator and store stay app-owned. Only O18 outcomes
|
|
211
|
+
and fence semantics are contributed; provider calls, claims, retries, schedules,
|
|
212
|
+
SQL and late-import orphan handling remain with their owners. The reference
|
|
213
|
+
privacy graph leaves marketing unselected, and marketing privacy coverage there
|
|
214
|
+
remains an open gap. Raw managed questionnaires and other processors are outside
|
|
215
|
+
this contributor's coverage.
|
|
216
|
+
|
|
217
|
+
Migration: Import `createMarketingPrivacyBindings` and its owner port types from `@openlup/platform/marketing/server`; bind both complete transactional owners and set `enabled: true` explicitly to select a contributor.
|
|
218
|
+
Migration: Register the returned contributor with identity and pass the returned `exportPersonalData`, `assessErasure` and `eraseOrRetain` callables as the marketing record to `createMarketingContribution`; disabled or partial bindings expose null callables.
|
|
219
|
+
Migration: Compose identity's `./identity/contracts` module dependency and preserve its assessment-before-mutation, subscriptions veto, receipt replay and unit-of-work rollback contract.
|
|
220
|
+
Migration: Keep remote profile coverage unavailable; accepted requests and outstanding imports or targets do not establish observed deletion. The reference requires a separately authorized owner binding before marketing privacy coverage can be claimed.
|
|
221
|
+
|
|
222
|
+
Declaration repair: Privacy owner ports and `MarketingPrivacyContributor` use
|
|
223
|
+
local structural types and identity's `./identity/contracts` types, preserving
|
|
224
|
+
compatibility with identity's contributor without referencing its main entry.
|
|
225
|
+
`./marketing/server` remains free of the optional `pg` peer in strict installed
|
|
226
|
+
declaration compilation; only `./marketing/server/postgres` selects that peer.
|
|
227
|
+
The runtime obligation schema still comes from `./identity/contracts`.
|
|
228
|
+
Identity's public surface, privacy execution and the 16-case K5 budget are unchanged.
|
|
229
|
+
|
|
230
|
+
- Packed root-documentation budget: the docs-gzip cap in release-gates.json rises from 57,344 B to 73,728 B, approved by the owner on 2026-10-26, because the assembled 0.29.0 notes measured 63,226 B; no other cap changes.
|
|
231
|
+
|
|
13
232
|
## [0.28.0]
|
|
14
233
|
|
|
15
234
|
- Publishable on the npm `latest` dist-tag as `0.28.0`, from tag
|
|
@@ -314,21 +533,3 @@ Migration: Subscription finalize validates retained acquisition terms under the
|
|
|
314
533
|
Migration: The acquisition terms reader refuses absent effective terms; the no-policy finalize compatibility branch remains available.
|
|
315
534
|
Migration: New-purchase stock reads use ATP with renewal exemption fixed false, bounded SKU arrays and conservative stale reporting. The service-only reader uses owner privileges with `SECURITY DEFINER` and `search_path = pg_catalog, pg_temp`.
|
|
316
535
|
Migration: Starter graduation admits 14, 21 or 28 days, while provisional creation uses the retained starter interval and subscription timezone default. Rolling back below the forward with a 21-day marker is unsupported; roll forward.
|
|
317
|
-
|
|
318
|
-
## [0.26.0]
|
|
319
|
-
|
|
320
|
-
- Publishable on the npm `latest` dist-tag as `0.26.0`, from tag
|
|
321
|
-
`openlup-platform-v0.26.0`.
|
|
322
|
-
|
|
323
|
-
Managed dunning attempt replay.
|
|
324
|
-
|
|
325
|
-
Carry the exact applied failure attempt through renewal propagation. Managed
|
|
326
|
-
same/stale observations replay the canonical result; newer attributed failures
|
|
327
|
-
advance and revoke prior recovery authority, including used tokens.
|
|
328
|
-
|
|
329
|
-
Migration: `CycleChargeFailurePropagationPort.openDunningCase` now requires nullable `failedPaymentAttemptId`; update host implementations and callers to pass the applied transition's identity.
|
|
330
|
-
Migration: `applyFailedResult` may return `paymentAttemptId?: string | null`; return the durable applied attempt so propagation can forward it, including on replay.
|
|
331
|
-
Migration: managed hosts must pass exact applied-transition attribution to the new overloads. Fresh missing attribution refuses with SQLSTATE `55000`; do not substitute the current or prepared attempt. Already-applied donor schema/backfill requires the explicit host mapping in DATA_AND_MIGRATIONS.
|
|
332
|
-
|
|
333
|
-
Native attempt-replay parity remains REGISTERED with M10; these managed forwards
|
|
334
|
-
do not implement native parity or authorize host activation.
|
package/README.md
CHANGED
|
@@ -10,8 +10,12 @@ Development preview. This package is part of the publishable set with core and o
|
|
|
10
10
|
|
|
11
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`.
|
|
12
12
|
|
|
13
|
-
For the prepared `0.
|
|
14
|
-
limitations](CHANGELOG.md#
|
|
13
|
+
For the prepared `0.29.0` set, read the [adjacent-release migration and known
|
|
14
|
+
limitations](CHANGELOG.md#0290) before selecting optional services. Experimental
|
|
15
|
+
M13 marketing uses browser-safe `./marketing`, type-only browser-safe
|
|
16
|
+
`./marketing/contracts`, and Node-only `./marketing/server` and
|
|
17
|
+
`./marketing/server/postgres`. Marketing contributions and bindings remain
|
|
18
|
+
inert and default-off. Experimental
|
|
15
19
|
account/support APIs use `./account-support` and the type-only
|
|
16
20
|
`./account-support/contracts`; reference bindings remain inert and default-off.
|
|
17
21
|
Apply the M12 support-authority forwards after complete same-rail predecessors
|
|
@@ -50,7 +54,7 @@ Adopters must not activate unselected or unready invoicing; installation and
|
|
|
50
54
|
inert contributions register no runner, worker, route or schedule.
|
|
51
55
|
M06 managed-host proof classes remain pending in the
|
|
52
56
|
[M06 parity ledger](../../docs/platform/plans/oss-m06-stock-reservations-delivery.md#parity-pending-rows).
|
|
53
|
-
Size comparison uses the published `0.
|
|
57
|
+
Size comparison uses the published `0.28.0` tarball. Preparation and offline
|
|
54
58
|
adapter evidence grant no publication or provider-account certification.
|
|
55
59
|
|
|
56
60
|
Longer module recipes live in the [platform package reference](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md).
|
|
@@ -93,6 +97,12 @@ timestamp used in the webhook's idempotency key.
|
|
|
93
97
|
| `./inventory` | Experimental schemas/ports, handlers, native stores, projection, injected forecast and SQL descriptor; `./inventory/contracts` DTOs. |
|
|
94
98
|
| `./catalog` | Experimental neutral catalog schemas, drafts, reads, media source packs and publication ports |
|
|
95
99
|
| `./catalog/contracts` | Dependency-free catalog DTOs, media resolver, authority and canonicalization helpers |
|
|
100
|
+
| `./marketing/server` | Node-only acquisition handlers, direct read/evidence factories and research orchestration without `pg`; host responder, authorization, binding and notification copy |
|
|
101
|
+
| `./marketing/server/postgres` | Acquisition case and research evidence PostgreSQL port factories; requires the existing optional `pg` peer |
|
|
102
|
+
| `./marketing/server` (analytics context) | Injected analytics context handler with host persistence, capability and identity bindings |
|
|
103
|
+
| `./marketing`, `./marketing/contracts` | Browser-safe acquisition history, portable prelaunch, survey evidence and newsletter consent schemas; type-only DTOs and acquisition/research ports |
|
|
104
|
+
| `./marketing`, `./marketing/contracts` (analytics) | Browser-safe acquisition and research schemas, injected analytics, paid purchase and consent-time facts; type-only DTOs and ports |
|
|
105
|
+
| `./marketing`, `./marketing/contracts` (SEO and content slots) | Browser-safe JSON-LD serialization and graph builders, URL/hreflang helpers, ordered head data and contact/legal projections; type-only organization, contact, legal-document and privacy-processor content slots |
|
|
96
106
|
| `./commerce`, `./commerce/contracts` | Browser-safe neutral commerce schema cores, generic ports and pure contract helpers |
|
|
97
107
|
| `./commerce/server` | Node-only OMS, returns, native reviews/media and hosted-feedback handlers/adapters and order-detail composition, email consumers, dispatch registry, paid-fulfillment binding and checkout compensation, checkout handlers, runtime and shared paid-order saga |
|
|
98
108
|
| `./pricing` | Experimental price authority, quote computation/handlers, offer projection/cache, readiness and policy tokens |
|
|
@@ -103,6 +113,135 @@ timestamp used in the webhook's idempotency key.
|
|
|
103
113
|
| `./shipping` | Experimental delivery ports, injected-schema handlers, summary/evidence; native flat-rate port + Core schema readiness |
|
|
104
114
|
| `./shipping/contracts` | Type-only delivery, pickup-point, summary and evidence DTOs |
|
|
105
115
|
|
|
116
|
+
## Marketing contracts
|
|
117
|
+
|
|
118
|
+
`./marketing` provides acquisition address references, historical case projections,
|
|
119
|
+
list/count reads, portable prelaunch list/detail schemas, idempotency keys, survey submission/evidence/list schemas and
|
|
120
|
+
newsletter consent events/responses. Reference compatibility shims forward the
|
|
121
|
+
same schema objects and load the reference validation wrapper before package
|
|
122
|
+
schemas. The marketing runtime entry configures the shared Zod instance in
|
|
123
|
+
jitless mode before constructing schemas, preserving CSP-safe initialization
|
|
124
|
+
for direct imports as well as reference facades, like the pricing, catalog and
|
|
125
|
+
communications entries. The type-only `./marketing/contracts` entry has no
|
|
126
|
+
runtime initialization. The rich prelaunch DTO and case submit/transition schemas remain application-owned
|
|
127
|
+
and are excluded from the browser entries. The shared
|
|
128
|
+
`acquisitionOpaqueReferenceSchema` lets those retained contracts reuse the exact
|
|
129
|
+
reference syntax. No entry registers a route automatically.
|
|
130
|
+
|
|
131
|
+
`./marketing/contracts` exports only types. Explicit acquisition DTO shapes are
|
|
132
|
+
checked against the runtime schema inference by an executed TypeScript equality
|
|
133
|
+
witness. Reachable case ports expose list, get, active count and close; the app
|
|
134
|
+
uses the server-only compatibility port for its retired methods. Evidence ports retain survey submission,
|
|
135
|
+
survey listing and consent application. Port types are also forwarded through
|
|
136
|
+
the runtime entry, following the commerce boundary. Both entries forward research schemas or types from the compatibility
|
|
137
|
+
owner, `@openlup/core/marketing/research`; runtime schemas retain object identity.
|
|
138
|
+
Case locale remains `en|pl`, matching the persisted constraint. Widening it requires
|
|
139
|
+
a separate migration. Historical wire values remain unchanged.
|
|
140
|
+
|
|
141
|
+
The source and built entries have browser graph proofs. The root test runner
|
|
142
|
+
selects `test/marketing/`; the installed consumer checks both public entries,
|
|
143
|
+
compiles typed usage and refuses deep imports. Kiosk and research reference
|
|
144
|
+
contracts/ports continue to consume the core export. The app owns its admin
|
|
145
|
+
response client and host composition.
|
|
146
|
+
|
|
147
|
+
`./marketing/server` owns acquisition case handlers, list/count and prelaunch
|
|
148
|
+
list/detail factories, survey evidence submit/list and consent application,
|
|
149
|
+
research submit/admin handlers and managed survey orchestration without loading
|
|
150
|
+
`pg`. Select `./marketing/server/postgres` for the two PostgreSQL port factories
|
|
151
|
+
after installing the existing optional `pg` peer. Hosts inject the BFF responder,
|
|
152
|
+
authorization and binding resolvers. Direct case reads receive the host bundle
|
|
153
|
+
predicate at their original guard; prelaunch and evidence dispatch stays in the
|
|
154
|
+
host. Notification HTML and subject are injected separately, preserving
|
|
155
|
+
HTML rendering before the subject clock read. The reference owns retired
|
|
156
|
+
route refusals, raw signed consent ingress and notification copy. PostgreSQL
|
|
157
|
+
SQL, role selection and transaction/pool handling remain unchanged. The
|
|
158
|
+
server-only compatibility command types do not expose retired admission schemas.
|
|
159
|
+
|
|
160
|
+
Analytics facts share these browser-safe entries. `createNoopAnalytics` implements
|
|
161
|
+
Core's existing analytics port; deployment and advertising defaults remain inert.
|
|
162
|
+
`AnalyticsEventMap<StepName>` retains the host's literal step vocabulary, with
|
|
163
|
+
`string` as the neutral default. Private transport ownership fields and envelopes
|
|
164
|
+
remain host extensions. Types are forwarded type-only by `./marketing/contracts`.
|
|
165
|
+
|
|
166
|
+
`createAnalyticsDataLayer` owns loader readiness per instance and accepts the host's
|
|
167
|
+
browser/storage access, consent key and change event, `consentSignalNames`, event
|
|
168
|
+
prefix, container reader and deployment callback. `consentSignalNames` supplies
|
|
169
|
+
one `analytics` wire name and the ordered `advertising` wire names. Without it,
|
|
170
|
+
no consent command is pushed and optional event admission returns false, even
|
|
171
|
+
with browser access, a container and stored consent; deployment attempts remain
|
|
172
|
+
independent. Consent commands seed default before update and
|
|
173
|
+
use array-like arguments; advertising grants read marketing consent at push time.
|
|
174
|
+
Revocation denies every signal. Sinks are attempted independently with failure
|
|
175
|
+
isolation and no replay of observations made before consent. Admission booleans
|
|
176
|
+
mean synchronous local acceptance only, never delivery or business acknowledgement.
|
|
177
|
+
|
|
178
|
+
`createAnalyticsRoutePolicy` requires public paths, redirect sources and all
|
|
179
|
+
sensitive-path sets. Its optional-route predicate preserves broad eligibility;
|
|
180
|
+
deployment URL sanitization admits exact public paths and safe campaign values.
|
|
181
|
+
`projectPaidPurchase` consumes only structural paid-recap facts, preserving
|
|
182
|
+
allocation/grouping, the item cap and ordered suppression reasons without an
|
|
183
|
+
ambient currency policy. `selectMarketingHistoricalConsentTime` selects exact
|
|
184
|
+
native chronology only after host authorization, without changing the local
|
|
185
|
+
grant. The reference retains its narrower checkout-kind admission and all wire
|
|
186
|
+
names. [Purchase equivalence](../../src/checkout/machine/purchasePayloadEquivalence.test.ts)
|
|
187
|
+
and the package analytics witnesses pin these boundaries.
|
|
188
|
+
|
|
189
|
+
`createAnalyticsContextHandler` in `./marketing/server` accepts a required BFF
|
|
190
|
+
responder, enable reader, persistence resolver, access-token reader, trusted-subject
|
|
191
|
+
resolver, capability mint/hash functions, historical cookie name and `clientIdField`.
|
|
192
|
+
The host supplies the client-id wire field name through `clientIdField`; the strict
|
|
193
|
+
request also keeps `granted` and `explicitGrant`. Grants require a client
|
|
194
|
+
id and existing revoked contexts require an explicit new grant for replacement.
|
|
195
|
+
Only token hashes reach persistence. Enrollment uses only the server-verified
|
|
196
|
+
subject, and invalid bearer grants refuse before writes. Cookie attributes and
|
|
197
|
+
method/flag/origin/schema refusal order are preserved. The host owns flag and
|
|
198
|
+
RPC names, gateway authority, route mounting and observability. Persistence
|
|
199
|
+
operations must reject on failure; null persistence refuses as unavailable.
|
|
200
|
+
There is no default persistence, portable SQL or reference route for this handler.
|
|
201
|
+
An `active` result is a local context fact, never delivery, and telemetry context
|
|
202
|
+
failure never gates commerce. The [context witness](test/marketing/analyticsContext.test.ts)
|
|
203
|
+
exercises the factory through synthetic host bindings.
|
|
204
|
+
|
|
205
|
+
`./marketing` also provides browser-safe JSON-LD serialization and graph builders,
|
|
206
|
+
route URL/hreflang helpers, an ordered head descriptor and plain contact/legal
|
|
207
|
+
projections. Applications supply identity, origin, routes, locales, images and
|
|
208
|
+
content; the descriptor is plain data for a host head manager. The type-only
|
|
209
|
+
`./marketing/contracts` entry exports shared organization facts and contact,
|
|
210
|
+
legal-document and privacy-processor shapes, also forwarded as types by the
|
|
211
|
+
runtime entry. The package supplies no document wording, processor inventory or
|
|
212
|
+
content policy. The [marketing recipe](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#marketing-seo-and-content-slots)
|
|
213
|
+
owns the mechanics and installed-artifact proof.
|
|
214
|
+
|
|
215
|
+
## Marketing composition
|
|
216
|
+
|
|
217
|
+
`./composition` exports `createMarketingContribution`, an inert descriptor for
|
|
218
|
+
the `marketing` capability's `./marketing`, `./marketing/contracts` and
|
|
219
|
+
`./marketing/server` entries, with a runtime dependency on `identity/contracts`
|
|
220
|
+
for obligation validation.
|
|
221
|
+
Supply already-bound operations and host schema requirements. Ports, routes and
|
|
222
|
+
triggers share the supplied functions; null ports remain required for Core
|
|
223
|
+
readiness, and handlers retain only registration descriptors. Duplicate handler,
|
|
224
|
+
schedule or route identities refuse. Construction invokes no callable and
|
|
225
|
+
installs no worker, route or schedule. See the
|
|
226
|
+
[composition contract](../../docs/platform/ARCHITECTURE_AND_EXTENSIONS.md#contributions-seams-and-readiness)
|
|
227
|
+
for the host admission boundary.
|
|
228
|
+
|
|
229
|
+
`./marketing/server` also exports `createMarketingPrivacyContributor` and
|
|
230
|
+
`createMarketingPrivacyBindings`. Explicit enablement and both complete owner
|
|
231
|
+
ports select one contributor; its `exportPersonalData`, `assessErasure` and
|
|
232
|
+
`eraseOrRetain` callables can be passed directly to `createMarketingContribution`.
|
|
233
|
+
Missing ownership makes coverage unavailable and erasure unresolved. Identity
|
|
234
|
+
owns assessment ordering, subscription vetoes, receipt replay and transaction
|
|
235
|
+
rollback; the marketing fence runs only during `eraseOrRetain`. Provider request
|
|
236
|
+
acceptance never proves deletion. The reference leaves marketing unselected,
|
|
237
|
+
so its marketing privacy coverage remains an open gap. See the
|
|
238
|
+
[privacy composition recipe](../../docs/platform/PLATFORM_PACKAGE_REFERENCE.md#marketing-server-composition).
|
|
239
|
+
|
|
240
|
+
The contributor and binding declarations use identity contract types and local
|
|
241
|
+
structural interfaces compatible with identity's `PersonalDataContributor`.
|
|
242
|
+
They do not reference identity's main entry; `./marketing/server` compiles without
|
|
243
|
+
`pg` or `@types/pg`. Select `./marketing/server/postgres` explicitly for those ports.
|
|
244
|
+
|
|
106
245
|
## Commerce contracts
|
|
107
246
|
|
|
108
247
|
`./composition` exports the inert `createCommerceContribution` for the installed
|
|
@@ -256,7 +395,7 @@ SQL (class (b) retention): native uses 14 days and the contributed managed profi
|
|
|
256
395
|
uses 21 days. There is no TypeScript delay parameter or SQL change.
|
|
257
396
|
The reference browser contract facades initialize their shared Zod instance in
|
|
258
397
|
jitless mode before loading package schemas, preserving CSP-safe construction.
|
|
259
|
-
The package contracts add no global Zod configuration side effect. Browser
|
|
398
|
+
The commerce package contracts add no global Zod configuration side effect. Browser
|
|
260
399
|
conformance bundles the complete commerce entry and both reference facades
|
|
261
400
|
without externals; the raw-upload source is a failing browser control, while
|
|
262
401
|
the complete server entry bundles for Node.
|
|
@@ -8,3 +8,4 @@ export { createFulfillmentContribution } from "./fulfillmentContribution.js";
|
|
|
8
8
|
export { createSubscriptionContribution } from "./subscriptionContribution.js";
|
|
9
9
|
export { createCommerceContribution } from "./commerceContribution.js";
|
|
10
10
|
export { createAccountSupportContribution } from "./accountSupportContribution.js";
|
|
11
|
+
export { createMarketingContribution } from "./marketingContribution.js";
|
|
@@ -9,3 +9,4 @@ export { createFulfillmentContribution } from "./fulfillmentContribution.js";
|
|
|
9
9
|
export { createSubscriptionContribution } from "./subscriptionContribution.js";
|
|
10
10
|
export { createCommerceContribution } from "./commerceContribution.js";
|
|
11
11
|
export { createAccountSupportContribution } from "./accountSupportContribution.js";
|
|
12
|
+
export { createMarketingContribution } from "./marketingContribution.js";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Contribution, RequiredSchema } from "@openlup/core/readiness";
|
|
2
|
+
/** Describe existing selected marketing callables; never install another executor. */
|
|
3
|
+
export declare function createMarketingContribution(input: {
|
|
4
|
+
version: string;
|
|
5
|
+
requiredSchema: RequiredSchema;
|
|
6
|
+
marketing: Readonly<Record<string, ((...args: never[]) => unknown) | null>>;
|
|
7
|
+
handlers: Contribution["handlers"];
|
|
8
|
+
schedules: Contribution["schedules"];
|
|
9
|
+
routes: Contribution["routes"];
|
|
10
|
+
}): {
|
|
11
|
+
contributions: Contribution[];
|
|
12
|
+
ports: {
|
|
13
|
+
[k: string]: ((...args: never[]) => unknown) | null;
|
|
14
|
+
};
|
|
15
|
+
routes: {
|
|
16
|
+
[k: string]: (...args: never[]) => unknown;
|
|
17
|
+
};
|
|
18
|
+
triggers: {
|
|
19
|
+
[k: string]: (...args: never[]) => unknown;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Describe existing selected marketing callables; never install another executor. */
|
|
2
|
+
export function createMarketingContribution(input) {
|
|
3
|
+
for (const [kind, names] of [
|
|
4
|
+
["handler", input.handlers.map(handler => handler.eventType)],
|
|
5
|
+
["schedule", input.schedules.map(schedule => schedule.id)],
|
|
6
|
+
["route", input.routes.map(route => route.id)],
|
|
7
|
+
]) {
|
|
8
|
+
if (new Set(names).size !== names.length)
|
|
9
|
+
throw new Error(`marketing_duplicate_${kind}`);
|
|
10
|
+
}
|
|
11
|
+
const contribution = {
|
|
12
|
+
manifest: {
|
|
13
|
+
name: "@openlup/platform", version: input.version, kind: "rail",
|
|
14
|
+
module: { id: "marketing", kind: "capability", provides: ["./marketing", "./marketing/contracts", "./marketing/server"],
|
|
15
|
+
// The server entry validates obligations with identity's runtime contract schema.
|
|
16
|
+
dependsOn: [{ module: "identity", entries: ["./identity/contracts"] }] },
|
|
17
|
+
emits: [], handles: input.handlers.map(handler => handler.eventType),
|
|
18
|
+
schedules: input.schedules.map(({ id, cadenceSeconds }) => ({ id, cadenceSeconds })), env: [],
|
|
19
|
+
requiredPorts: Object.keys(input.marketing), routes: input.routes.map(route => route.id), requiredSchema: input.requiredSchema,
|
|
20
|
+
},
|
|
21
|
+
handlers: input.handlers.map(({ eventType, timeoutMs }) => Object.freeze({ eventType, timeoutMs })), schedules: input.schedules, routes: input.routes,
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
contributions: [contribution],
|
|
25
|
+
ports: Object.fromEntries(Object.entries(input.marketing).filter(([, fn]) => typeof fn === "function").map(([name, fn]) => [`@openlup/platform/marketing:${name}`, fn])),
|
|
26
|
+
routes: Object.fromEntries(input.routes.map(route => [`@openlup/platform/marketing:${route.id}`, route.handle])),
|
|
27
|
+
triggers: Object.fromEntries(input.schedules.map(schedule => [`@openlup/platform/marketing:${schedule.id}`, schedule.run])),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from "./validation.js";
|
|
2
|
+
export declare const ACQUISITION_CASE_CONTRACT_VERSION: "tester_application_v1";
|
|
3
|
+
export declare const ACQUISITION_CASE_VIEW: "acquisition_case_v1";
|
|
4
|
+
export declare const ACQUISITION_CASE_SOURCE: "tester_application";
|
|
5
|
+
export declare const acquisitionOpaqueReferenceSchema: z.ZodString;
|
|
6
|
+
export declare const acquisitionAddressReferenceSchema: z.ZodObject<{
|
|
7
|
+
source: z.ZodString;
|
|
8
|
+
reference: z.ZodString;
|
|
9
|
+
revision: z.ZodString;
|
|
10
|
+
provenance: z.ZodString;
|
|
11
|
+
}, z.core.$strict>;
|
|
12
|
+
export declare const acquisitionCaseStateSchema: z.ZodEnum<{
|
|
13
|
+
rejected: "rejected";
|
|
14
|
+
active: "active";
|
|
15
|
+
submitted: "submitted";
|
|
16
|
+
withdrawn: "withdrawn";
|
|
17
|
+
approved: "approved";
|
|
18
|
+
}>;
|
|
19
|
+
export declare const acquisitionCaseProjectionSchema: z.ZodObject<{
|
|
20
|
+
contractVersion: z.ZodLiteral<"tester_application_v1">;
|
|
21
|
+
caseRef: z.ZodString;
|
|
22
|
+
contactRef: z.ZodString;
|
|
23
|
+
sourceKind: z.ZodLiteral<"tester_application">;
|
|
24
|
+
consent: z.ZodObject<{
|
|
25
|
+
consentVersion: z.ZodString;
|
|
26
|
+
policyVersion: z.ZodString;
|
|
27
|
+
recordedAt: z.ZodString;
|
|
28
|
+
locale: z.ZodEnum<{
|
|
29
|
+
en: "en";
|
|
30
|
+
pl: "pl";
|
|
31
|
+
}>;
|
|
32
|
+
sourcePath: z.ZodLiteral<"/tester-application">;
|
|
33
|
+
}, z.core.$strict>;
|
|
34
|
+
addressReference: z.ZodNullable<z.ZodObject<{
|
|
35
|
+
source: z.ZodString;
|
|
36
|
+
reference: z.ZodString;
|
|
37
|
+
revision: z.ZodString;
|
|
38
|
+
provenance: z.ZodString;
|
|
39
|
+
}, z.core.$strict>>;
|
|
40
|
+
state: z.ZodEnum<{
|
|
41
|
+
rejected: "rejected";
|
|
42
|
+
active: "active";
|
|
43
|
+
submitted: "submitted";
|
|
44
|
+
withdrawn: "withdrawn";
|
|
45
|
+
approved: "approved";
|
|
46
|
+
}>;
|
|
47
|
+
version: z.ZodNumber;
|
|
48
|
+
createdAt: z.ZodString;
|
|
49
|
+
updatedAt: z.ZodString;
|
|
50
|
+
}, z.core.$strict>;
|
|
51
|
+
export declare const acquisitionCaseListRequestSchema: z.ZodObject<{
|
|
52
|
+
view: z.ZodLiteral<"acquisition_case_v1">;
|
|
53
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
54
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
55
|
+
}, z.core.$strict>;
|
|
56
|
+
export declare const acquisitionCaseListResponseSchema: z.ZodObject<{
|
|
57
|
+
contractVersion: z.ZodLiteral<"tester_application_v1">;
|
|
58
|
+
cases: z.ZodArray<z.ZodObject<{
|
|
59
|
+
contractVersion: z.ZodLiteral<"tester_application_v1">;
|
|
60
|
+
caseRef: z.ZodString;
|
|
61
|
+
contactRef: z.ZodString;
|
|
62
|
+
sourceKind: z.ZodLiteral<"tester_application">;
|
|
63
|
+
consent: z.ZodObject<{
|
|
64
|
+
consentVersion: z.ZodString;
|
|
65
|
+
policyVersion: z.ZodString;
|
|
66
|
+
recordedAt: z.ZodString;
|
|
67
|
+
locale: z.ZodEnum<{
|
|
68
|
+
en: "en";
|
|
69
|
+
pl: "pl";
|
|
70
|
+
}>;
|
|
71
|
+
sourcePath: z.ZodLiteral<"/tester-application">;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
addressReference: z.ZodNullable<z.ZodObject<{
|
|
74
|
+
source: z.ZodString;
|
|
75
|
+
reference: z.ZodString;
|
|
76
|
+
revision: z.ZodString;
|
|
77
|
+
provenance: z.ZodString;
|
|
78
|
+
}, z.core.$strict>>;
|
|
79
|
+
state: z.ZodEnum<{
|
|
80
|
+
rejected: "rejected";
|
|
81
|
+
active: "active";
|
|
82
|
+
submitted: "submitted";
|
|
83
|
+
withdrawn: "withdrawn";
|
|
84
|
+
approved: "approved";
|
|
85
|
+
}>;
|
|
86
|
+
version: z.ZodNumber;
|
|
87
|
+
createdAt: z.ZodString;
|
|
88
|
+
updatedAt: z.ZodString;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
91
|
+
}, z.core.$strict>;
|
|
92
|
+
export declare const acquisitionCaseActiveCountResponseSchema: z.ZodObject<{
|
|
93
|
+
activeTesterCount: z.ZodNumber;
|
|
94
|
+
}, z.core.$strict>;
|
|
95
|
+
export declare const acquisitionIdempotencyKeySchema: z.ZodString;
|
|
96
|
+
export type AcquisitionOpaqueReference = z.infer<typeof acquisitionOpaqueReferenceSchema>;
|
|
97
|
+
export type AcquisitionAddressReference = z.infer<typeof acquisitionAddressReferenceSchema>;
|
|
98
|
+
export type AcquisitionCaseState = z.infer<typeof acquisitionCaseStateSchema>;
|
|
99
|
+
export type AcquisitionCaseProjection = z.infer<typeof acquisitionCaseProjectionSchema>;
|
|
100
|
+
export type AcquisitionCaseListRequest = z.infer<typeof acquisitionCaseListRequestSchema>;
|
|
101
|
+
export type AcquisitionCaseListResponse = z.infer<typeof acquisitionCaseListResponseSchema>;
|
|
102
|
+
export type AcquisitionCaseActiveCountResponse = z.infer<typeof acquisitionCaseActiveCountResponseSchema>;
|
|
103
|
+
export type AcquisitionIdempotencyKey = z.infer<typeof acquisitionIdempotencyKeySchema>;
|