@fabricorg/platform-host 3.0.0 → 5.0.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 +41 -0
- package/README.md +5 -4
- package/dist/index.cjs +52 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +53 -29
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @fabricorg/platform-host
|
|
2
2
|
|
|
3
|
+
## 5.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- c504d0a: Enforce every field of `ActionExecutionContract` or hand it to an explicit owner.
|
|
8
|
+
|
|
9
|
+
- `connectivity`: an action declaring `online-required` is refused when submitted with
|
|
10
|
+
`executionReason: "offline_replay"`. What a client offers offline is a composition decision; what
|
|
11
|
+
the Host accepts is not.
|
|
12
|
+
- `consistency`: an action declaring `provisional-until-reconciled` marks the events it emits and the
|
|
13
|
+
submission result, so bus consumers and reconciliation flows can tell a settled fact from a pending
|
|
14
|
+
one without a lookup.
|
|
15
|
+
- `sensitivity`: an action declaring `restricted` refuses a submission carrying provenance audit
|
|
16
|
+
attributes instead of durably recording them.
|
|
17
|
+
- `completion`: `immediate` combined with `kind: "saga"` is rejected at registry build.
|
|
18
|
+
|
|
19
|
+
`consistency` is persisted by the PostgreSQL store (additive nullable column, applied by
|
|
20
|
+
`ensureSchema()`) and carried through `toEnterpriseEventEnvelope()` to the bus, so a provisional fact
|
|
21
|
+
stays marked as provisional after replay and after publication. Every result path is decorated, so an
|
|
22
|
+
idempotent replay reports the same consistency as the original submission.
|
|
23
|
+
|
|
24
|
+
Applications that previously submitted offline replays of online-required actions, or audit
|
|
25
|
+
attributes on restricted actions, now receive an explicit error where both were silent.
|
|
26
|
+
|
|
27
|
+
At release, raise the `@fabricorg/platform` peer floor to the version carrying
|
|
28
|
+
`AssetEventEnvelope.consistency`.
|
|
29
|
+
|
|
30
|
+
## 4.0.0
|
|
31
|
+
|
|
32
|
+
### Major Changes
|
|
33
|
+
|
|
34
|
+
- Make the capability runtime vertical-neutral and instance-scoped. Move experience and display
|
|
35
|
+
semantics into a namespaced companion package, require explicit host registries, replace privacy
|
|
36
|
+
field defaults with caller-owned policy, add PostgreSQL projection adapters, and generate executable
|
|
37
|
+
ProjectionHost read and PlatformHost mutation seams.
|
|
38
|
+
|
|
39
|
+
### Patch Changes
|
|
40
|
+
|
|
41
|
+
- Updated dependencies
|
|
42
|
+
- @fabricorg/platform@1.0.0
|
|
43
|
+
|
|
3
44
|
## 3.0.0
|
|
4
45
|
|
|
5
46
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
The canonical host for the `@fabricorg/platform` mutation pipeline.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
pnpm add @fabricorg/platform@^0.
|
|
6
|
+
pnpm add @fabricorg/platform@^1.0.0 @fabricorg/platform-host@^4.0.0
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
## AI agent integration boundary
|
|
@@ -15,7 +15,7 @@ registration, and submit stable idempotent commands. The gateway derives tenant
|
|
|
15
15
|
calls `submitAction()`; an agent must never call handlers, adapters, workflow internals, or database
|
|
16
16
|
writes directly.
|
|
17
17
|
|
|
18
|
-
See the [Platform Host
|
|
18
|
+
See the [Platform Host 4.x agent integration
|
|
19
19
|
guide](https://platform.fabric.pro/docs/platform/reference/platform-host) for application wiring,
|
|
20
20
|
execution-time authorization, the PostgreSQL transaction binder, recovery semantics, and the external
|
|
21
21
|
gateway contract.
|
|
@@ -32,8 +32,8 @@ Actor → ActionInvocation → Schema → Agent HITL → PolicyEvaluation → St
|
|
|
32
32
|
worker entry point. With no dispatcher the host executes inline, which is intended for tests and local
|
|
33
33
|
development only.
|
|
34
34
|
|
|
35
|
-
Applications
|
|
36
|
-
|
|
35
|
+
Applications construct a `createModuleRegistry()` per runtime and pass it as `registry`; a narrow
|
|
36
|
+
`resolveAction` function remains available for adapters. No process-wide platform registry exists. A custom `extractEvents` implementation can pair with
|
|
37
37
|
`eventResultFields` so its event carrier is removed from the durable invocation result. Domain events
|
|
38
38
|
without an explicit `eventSchemaVersion` inherit the action version, while host lifecycle events stay
|
|
39
39
|
at version 1. Emitted domain events must appear in the action's `emitsEvents` declaration. The
|
|
@@ -81,6 +81,7 @@ by default; `outbox.includeProvenance` is the explicit classification-aware over
|
|
|
81
81
|
```ts
|
|
82
82
|
const host = createGovernedActionHost({
|
|
83
83
|
store,
|
|
84
|
+
registry,
|
|
84
85
|
authorization: {
|
|
85
86
|
checkEntitlement,
|
|
86
87
|
authorize: authorizeSubmission,
|
package/dist/index.cjs
CHANGED
|
@@ -31,10 +31,10 @@ function digestParameters(parameters) {
|
|
|
31
31
|
return crypto.createHash("sha256").update(canonicalJson(parameters)).digest("hex");
|
|
32
32
|
}
|
|
33
33
|
var ATTRIBUTE_NAME = /^[a-z][a-z0-9-]*(?:\.[A-Za-z][A-Za-z0-9_-]*)+$/;
|
|
34
|
-
var
|
|
34
|
+
var INVOCATION_SOURCE = /^(?:ui|sdui|api|agent|worker|system|[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)+)$/;
|
|
35
35
|
function normalizeProvenance(input, options) {
|
|
36
36
|
if (!input) return void 0;
|
|
37
|
-
if (!
|
|
37
|
+
if (!INVOCATION_SOURCE.test(input.source)) throw new Error(`Invalid invocation provenance source: ${input.source}`);
|
|
38
38
|
const maxAttributes = options?.maxAttributes ?? 16;
|
|
39
39
|
const maxValueLength = options?.maxValueLength ?? 256;
|
|
40
40
|
const allowlist = new Set(options?.auditAttributeAllowlist ?? []);
|
|
@@ -83,7 +83,10 @@ function createGovernedActionHost(options) {
|
|
|
83
83
|
for (const adapter of options.adapters ?? []) adapters.register(adapter);
|
|
84
84
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
85
85
|
const extractEvents = options.extractEvents ?? DEFAULT_EXTRACT_EVENTS;
|
|
86
|
-
const
|
|
86
|
+
const configuredActionResolver = options.resolveAction ?? options.registry?.resolveAction;
|
|
87
|
+
if (!configuredActionResolver) throw new Error("Platform Host requires an explicit module registry or resolveAction function.");
|
|
88
|
+
const actionResolver = configuredActionResolver;
|
|
89
|
+
const stateMachineResolver = options.registry?.resolveStateMachine ?? (() => void 0);
|
|
87
90
|
const eventResultFields = options.eventResultFields ?? ["_events"];
|
|
88
91
|
async function submitAction(input) {
|
|
89
92
|
if (input.executionReason && !["initial", "offline_replay"].includes(input.executionReason)) {
|
|
@@ -91,6 +94,12 @@ function createGovernedActionHost(options) {
|
|
|
91
94
|
}
|
|
92
95
|
const action = actionResolver(input.actionId);
|
|
93
96
|
if (!action) throw new Error(`Unknown action: ${input.actionId}`);
|
|
97
|
+
if (action.execution?.connectivity === "online-required" && input.executionReason === "offline_replay") {
|
|
98
|
+
throw new Error(`Action ${input.actionId} is online-required and cannot be submitted as an offline replay.`);
|
|
99
|
+
}
|
|
100
|
+
if (action.execution?.sensitivity === "restricted" && Object.keys(input.provenance?.auditAttributes ?? {}).length > 0) {
|
|
101
|
+
throw new Error(`Action ${input.actionId} declares restricted sensitivity; provenance audit attributes must not be durably recorded.`);
|
|
102
|
+
}
|
|
94
103
|
const authorizationInput = toAuthorizationInput(action, input);
|
|
95
104
|
if (!await options.authorization.checkEntitlement(authorizationInput)) {
|
|
96
105
|
throw new Error(`Module "${action.namespace}" is not enabled for tenant ${input.tenantId}`);
|
|
@@ -163,7 +172,7 @@ function createGovernedActionHost(options) {
|
|
|
163
172
|
}
|
|
164
173
|
const durableWorkflowId = `action-invocation-${durableInvocation.id}`;
|
|
165
174
|
if (durableInvocation.id !== actionInvocationId) {
|
|
166
|
-
return {
|
|
175
|
+
return withConsistency({
|
|
167
176
|
actionInvocationId: durableInvocation.id,
|
|
168
177
|
status: durableInvocation.status,
|
|
169
178
|
workflowId: durableWorkflowId,
|
|
@@ -172,7 +181,7 @@ function createGovernedActionHost(options) {
|
|
|
172
181
|
...durableInvocation.hitlRoute ? { hitlRoute: durableInvocation.hitlRoute } : {},
|
|
173
182
|
...durableInvocation.hitlRiskTier ? { hitlRiskTier: durableInvocation.hitlRiskTier } : {},
|
|
174
183
|
...durableInvocation.authorizationReconciliation ? { reconciliation: durableInvocation.authorizationReconciliation } : {}
|
|
175
|
-
};
|
|
184
|
+
}, input.actionId);
|
|
176
185
|
}
|
|
177
186
|
if (options.dispatcher) {
|
|
178
187
|
try {
|
|
@@ -182,14 +191,14 @@ function createGovernedActionHost(options) {
|
|
|
182
191
|
spaceId: input.spaceId,
|
|
183
192
|
workflowId: durableWorkflowId
|
|
184
193
|
});
|
|
185
|
-
return {
|
|
194
|
+
return withConsistency({
|
|
186
195
|
actionInvocationId: durableInvocation.id,
|
|
187
196
|
status: durableInvocation.status,
|
|
188
197
|
workflowId: dispatched.workflowId,
|
|
189
198
|
...dispatched.runId ? { runId: dispatched.runId } : {},
|
|
190
199
|
...durableInvocation.hitlRoute ? { hitlRoute: durableInvocation.hitlRoute } : {},
|
|
191
200
|
...durableInvocation.hitlRiskTier ? { hitlRiskTier: durableInvocation.hitlRiskTier } : {}
|
|
192
|
-
};
|
|
201
|
+
}, input.actionId);
|
|
193
202
|
} catch (error) {
|
|
194
203
|
const message = errorMessage(error);
|
|
195
204
|
await options.store.updateActionInvocation(
|
|
@@ -206,7 +215,7 @@ function createGovernedActionHost(options) {
|
|
|
206
215
|
input.tenantId,
|
|
207
216
|
input.spaceId
|
|
208
217
|
);
|
|
209
|
-
return { ...executed, workflowId: durableWorkflowId };
|
|
218
|
+
return { ...withConsistency(executed, input.actionId), workflowId: durableWorkflowId };
|
|
210
219
|
}
|
|
211
220
|
async function executeInvocation(actionInvocationId, tenantId, spaceId, executionOptions = {}, executionReasonOverride) {
|
|
212
221
|
const loadedInvocation = await options.store.getActionInvocation(
|
|
@@ -220,7 +229,7 @@ function createGovernedActionHost(options) {
|
|
|
220
229
|
const resumingRunningInvocation = loadedInvocation.status === "running";
|
|
221
230
|
let invocation = loadedInvocation;
|
|
222
231
|
if (isTerminal(invocation.status) || invocation.status === "waiting_for_approval") {
|
|
223
|
-
return actionResult(invocation);
|
|
232
|
+
return withConsistency(actionResult(invocation), invocation.actionId);
|
|
224
233
|
}
|
|
225
234
|
if (invocation.status === "running" && invocation.leaseOwner && executionOptions.leaseOwner !== invocation.leaseOwner) {
|
|
226
235
|
return {
|
|
@@ -337,7 +346,7 @@ function createGovernedActionHost(options) {
|
|
|
337
346
|
message: `Action ${action.actionId} requires durable capture-time authorization evidence`
|
|
338
347
|
};
|
|
339
348
|
await options.store.updateActionInvocation(actionInvocationId, tenantId, spaceId, { status: "reconciliation_required", error: reconciliation.message, authorizationReconciliation: reconciliation });
|
|
340
|
-
return { actionInvocationId, status: "reconciliation_required", error: reconciliation.message, reconciliation };
|
|
349
|
+
return withConsistency({ actionInvocationId, status: "reconciliation_required", error: reconciliation.message, reconciliation }, action.actionId);
|
|
341
350
|
}
|
|
342
351
|
const bindingExpired = authorityMoment !== "capture" && invocation.authorizationBinding?.expiresAt !== void 0 && Date.parse(invocation.authorizationBinding.expiresAt) <= now().getTime();
|
|
343
352
|
if (bindingExpired) {
|
|
@@ -350,7 +359,7 @@ function createGovernedActionHost(options) {
|
|
|
350
359
|
message: `Authorization binding for action ${action.actionId} expired before execution`
|
|
351
360
|
};
|
|
352
361
|
await options.store.updateActionInvocation(actionInvocationId, tenantId, spaceId, { status: "reconciliation_required", error: reconciliation.message, authorizationReconciliation: reconciliation });
|
|
353
|
-
return { actionInvocationId, status: "reconciliation_required", error: reconciliation.message, reconciliation };
|
|
362
|
+
return withConsistency({ actionInvocationId, status: "reconciliation_required", error: reconciliation.message, reconciliation }, action.actionId);
|
|
354
363
|
}
|
|
355
364
|
const executionAuthorized = authorityMoment === "capture" ? invocation.authorizationBinding !== void 0 : options.authorization.authorizeExecution ? await options.authorization.authorizeExecution({
|
|
356
365
|
...authorizationInput,
|
|
@@ -372,7 +381,7 @@ function createGovernedActionHost(options) {
|
|
|
372
381
|
message: `Actor ${invocation.actorId} is not authorized to execute action ${action.actionId}`
|
|
373
382
|
};
|
|
374
383
|
await options.store.updateActionInvocation(actionInvocationId, tenantId, spaceId, { status: "reconciliation_required", error: reconciliation.message, authorizationReconciliation: reconciliation });
|
|
375
|
-
return { actionInvocationId, status: "reconciliation_required", error: reconciliation.message, reconciliation };
|
|
384
|
+
return withConsistency({ actionInvocationId, status: "reconciliation_required", error: reconciliation.message, reconciliation }, action.actionId);
|
|
376
385
|
}
|
|
377
386
|
const definitions = options.resolvePolicies ? await options.resolvePolicies({
|
|
378
387
|
...authorizationInput,
|
|
@@ -388,6 +397,7 @@ function createGovernedActionHost(options) {
|
|
|
388
397
|
parameters: parsed.data,
|
|
389
398
|
db: options.store.db,
|
|
390
399
|
services: options.services,
|
|
400
|
+
resolveCodePolicy: options.registry?.resolvePolicy,
|
|
391
401
|
mode: "execute",
|
|
392
402
|
now: now()
|
|
393
403
|
});
|
|
@@ -440,10 +450,11 @@ function createGovernedActionHost(options) {
|
|
|
440
450
|
spaceId,
|
|
441
451
|
binding.entityType,
|
|
442
452
|
entityId
|
|
443
|
-
) ?? initialState(binding.entityType) : initialState(binding.entityType);
|
|
453
|
+
) ?? initialState(stateMachineResolver(binding.entityType)) : initialState(stateMachineResolver(binding.entityType));
|
|
444
454
|
const targetState = typeof binding.targetState === "function" ? binding.targetState(parsed.data) : binding.targetState;
|
|
445
455
|
if (targetState !== "") {
|
|
446
|
-
const transition = platform.
|
|
456
|
+
const transition = platform.validateStateMachineTransition(
|
|
457
|
+
stateMachineResolver(binding.entityType),
|
|
447
458
|
binding.entityType,
|
|
448
459
|
currentState,
|
|
449
460
|
targetState,
|
|
@@ -712,7 +723,7 @@ function createGovernedActionHost(options) {
|
|
|
712
723
|
spaceId
|
|
713
724
|
);
|
|
714
725
|
if (!invocation) throw new Error(`ActionInvocation not found: ${actionInvocationId}`);
|
|
715
|
-
if (isTerminal(invocation.status)) return actionResult(invocation);
|
|
726
|
+
if (isTerminal(invocation.status)) return withConsistency(actionResult(invocation), invocation.actionId);
|
|
716
727
|
if (invocation.status !== "waiting_for_approval") {
|
|
717
728
|
return {
|
|
718
729
|
...actionResult(invocation),
|
|
@@ -762,9 +773,9 @@ function createGovernedActionHost(options) {
|
|
|
762
773
|
const transitioned = transition.invocation ?? await options.store.getActionInvocation(actionInvocationId, tenantId, spaceId);
|
|
763
774
|
if (!transition.applied || !transitioned) {
|
|
764
775
|
if (!transitioned) throw new Error(`ActionInvocation not found: ${actionInvocationId}`);
|
|
765
|
-
return actionResult(transitioned);
|
|
776
|
+
return withConsistency(actionResult(transitioned), transitioned.actionId);
|
|
766
777
|
}
|
|
767
|
-
if (!decision.approved) return actionResult(transitioned);
|
|
778
|
+
if (!decision.approved) return withConsistency(actionResult(transitioned), transitioned.actionId);
|
|
768
779
|
return executeInvocation(
|
|
769
780
|
actionInvocationId,
|
|
770
781
|
tenantId,
|
|
@@ -805,6 +816,13 @@ function createGovernedActionHost(options) {
|
|
|
805
816
|
spaceId
|
|
806
817
|
});
|
|
807
818
|
}
|
|
819
|
+
function declaredConsistency(actionId) {
|
|
820
|
+
return actionResolver(actionId)?.execution?.consistency;
|
|
821
|
+
}
|
|
822
|
+
function withConsistency(result, actionId) {
|
|
823
|
+
const consistency = declaredConsistency(actionId);
|
|
824
|
+
return consistency ? { ...result, consistency } : result;
|
|
825
|
+
}
|
|
808
826
|
async function appendEvent(invocation, event, deduplicationKey, defaultEventSchemaVersion = 1, transaction) {
|
|
809
827
|
const timestamp = now();
|
|
810
828
|
const envelope = {
|
|
@@ -827,7 +845,8 @@ function createGovernedActionHost(options) {
|
|
|
827
845
|
recordedAt: timestamp,
|
|
828
846
|
correlationId: invocation.correlationId,
|
|
829
847
|
...invocation.causationId ? { causationId: invocation.causationId } : {},
|
|
830
|
-
...invocation.provenance ? { provenance: { source: invocation.provenance.source, ...invocation.provenance.auditAttributes ? { auditAttributes: invocation.provenance.auditAttributes } : {} } } : {}
|
|
848
|
+
...invocation.provenance ? { provenance: { source: invocation.provenance.source, ...invocation.provenance.auditAttributes ? { auditAttributes: invocation.provenance.auditAttributes } : {} } } : {},
|
|
849
|
+
...declaredConsistency(invocation.actionId) === "provisional-until-reconciled" ? { consistency: "provisional-until-reconciled" } : {}
|
|
831
850
|
};
|
|
832
851
|
if (options.outbox) {
|
|
833
852
|
const hostLifecycleEvent = (/* @__PURE__ */ new Set(["AdapterInvocationStarted", "AdapterInvocationSucceeded", "AdapterInvocationFailed", "ComplianceBlocked"])).has(envelope.eventType);
|
|
@@ -929,8 +948,7 @@ function declaredPolicies(policyIds) {
|
|
|
929
948
|
codeEvaluatorPolicyId: policyId
|
|
930
949
|
}));
|
|
931
950
|
}
|
|
932
|
-
function initialState(
|
|
933
|
-
const machine = platform.resolveStateMachine(entityType);
|
|
951
|
+
function initialState(machine) {
|
|
934
952
|
return Object.values(machine?.states ?? {}).find((state) => state.stateClass === "initial")?.id ?? "none";
|
|
935
953
|
}
|
|
936
954
|
function isTerminal(status) {
|
|
@@ -996,6 +1014,8 @@ function toEnterpriseEventEnvelope(event, metadata) {
|
|
|
996
1014
|
payloadClassification: metadata.payloadClassification,
|
|
997
1015
|
...metadata.traceContext ? { traceContext: { ...metadata.traceContext } } : {},
|
|
998
1016
|
...metadata.includeProvenance && event.provenance ? { provenance: event.provenance } : {},
|
|
1017
|
+
// A provisional fact must stay marked as provisional once it leaves the platform.
|
|
1018
|
+
...event.consistency ? { consistency: event.consistency } : {},
|
|
999
1019
|
payload: event.payload
|
|
1000
1020
|
};
|
|
1001
1021
|
}
|
|
@@ -1427,10 +1447,11 @@ var PostgresPlatformHostStore = class _PostgresPlatformHostStore {
|
|
|
1427
1447
|
actor_id text NOT NULL, actor_type text NOT NULL, action_invocation_id text,
|
|
1428
1448
|
payload jsonb NOT NULL, sequence bigint NOT NULL,
|
|
1429
1449
|
occurred_at timestamptz NOT NULL, recorded_at timestamptz NOT NULL,
|
|
1430
|
-
correlation_id text NOT NULL, causation_id text, provenance jsonb,
|
|
1450
|
+
correlation_id text NOT NULL, causation_id text, provenance jsonb, consistency text,
|
|
1431
1451
|
UNIQUE (tenant_id, space_id, sequence)
|
|
1432
1452
|
);
|
|
1433
1453
|
ALTER TABLE fabric_platform.asset_events ADD COLUMN IF NOT EXISTS provenance jsonb;
|
|
1454
|
+
ALTER TABLE fabric_platform.asset_events ADD COLUMN IF NOT EXISTS consistency text;
|
|
1434
1455
|
CREATE INDEX IF NOT EXISTS asset_events_subject_idx
|
|
1435
1456
|
ON fabric_platform.asset_events
|
|
1436
1457
|
(tenant_id, space_id, subject_type, subject_id, sequence);
|
|
@@ -1714,8 +1735,8 @@ var PostgresPlatformHostStore = class _PostgresPlatformHostStore {
|
|
|
1714
1735
|
`INSERT INTO fabric_platform.asset_events
|
|
1715
1736
|
(id,tenant_id,space_id,event_type,event_schema_version,subject_type,subject_id,
|
|
1716
1737
|
actor_id,actor_type,action_invocation_id,payload,sequence,occurred_at,recorded_at,
|
|
1717
|
-
correlation_id,causation_id,provenance)
|
|
1718
|
-
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11::jsonb,$12,$13,$14,$15,$16,$17::jsonb)
|
|
1738
|
+
correlation_id,causation_id,provenance,consistency)
|
|
1739
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11::jsonb,$12,$13,$14,$15,$16,$17::jsonb,$18)
|
|
1719
1740
|
ON CONFLICT (id) DO NOTHING`,
|
|
1720
1741
|
[
|
|
1721
1742
|
event.id,
|
|
@@ -1734,7 +1755,8 @@ var PostgresPlatformHostStore = class _PostgresPlatformHostStore {
|
|
|
1734
1755
|
event.recordedAt,
|
|
1735
1756
|
event.correlationId,
|
|
1736
1757
|
event.causationId ?? null,
|
|
1737
|
-
event.provenance ? JSON.stringify(event.provenance) : null
|
|
1758
|
+
event.provenance ? JSON.stringify(event.provenance) : null,
|
|
1759
|
+
event.consistency ?? null
|
|
1738
1760
|
]
|
|
1739
1761
|
);
|
|
1740
1762
|
}
|
|
@@ -1745,8 +1767,8 @@ var PostgresPlatformHostStore = class _PostgresPlatformHostStore {
|
|
|
1745
1767
|
INSERT INTO fabric_platform.asset_events
|
|
1746
1768
|
(id,tenant_id,space_id,event_type,event_schema_version,subject_type,subject_id,
|
|
1747
1769
|
actor_id,actor_type,action_invocation_id,payload,sequence,occurred_at,recorded_at,
|
|
1748
|
-
correlation_id,causation_id,provenance)
|
|
1749
|
-
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11::jsonb,$12,$13,$14,$15,$16,$17::jsonb)
|
|
1770
|
+
correlation_id,causation_id,provenance,consistency)
|
|
1771
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11::jsonb,$12,$13,$14,$15,$16,$17::jsonb,$19)
|
|
1750
1772
|
ON CONFLICT (id) DO NOTHING RETURNING id
|
|
1751
1773
|
)
|
|
1752
1774
|
INSERT INTO fabric_platform.event_outbox
|
|
@@ -1771,7 +1793,8 @@ var PostgresPlatformHostStore = class _PostgresPlatformHostStore {
|
|
|
1771
1793
|
event.correlationId,
|
|
1772
1794
|
event.causationId ?? null,
|
|
1773
1795
|
event.provenance ? JSON.stringify(event.provenance) : null,
|
|
1774
|
-
JSON.stringify(envelope)
|
|
1796
|
+
JSON.stringify(envelope),
|
|
1797
|
+
event.consistency ?? null
|
|
1775
1798
|
]
|
|
1776
1799
|
);
|
|
1777
1800
|
}
|
|
@@ -2013,7 +2036,8 @@ function toEventRecord(row) {
|
|
|
2013
2036
|
recordedAt: new Date(row.recorded_at),
|
|
2014
2037
|
correlationId: String(row.correlation_id),
|
|
2015
2038
|
...row.causation_id ? { causationId: String(row.causation_id) } : {},
|
|
2016
|
-
...row.provenance ? { provenance: row.provenance } : {}
|
|
2039
|
+
...row.provenance ? { provenance: row.provenance } : {},
|
|
2040
|
+
...row.consistency ? { consistency: row.consistency } : {}
|
|
2017
2041
|
};
|
|
2018
2042
|
}
|
|
2019
2043
|
function toOutboxRecord(row) {
|