@nodii/saga 0.6.0 → 0.7.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/dist/admin-service.d.ts +19 -5
- package/dist/admin-service.d.ts.map +1 -1
- package/dist/admin-service.js +85 -8
- package/dist/admin-service.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/migrations/index.d.ts +19 -1
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +156 -5
- package/dist/migrations/index.js.map +1 -1
- package/dist/saga.d.ts +40 -0
- package/dist/saga.d.ts.map +1 -1
- package/dist/saga.js +141 -6
- package/dist/saga.js.map +1 -1
- package/dist/state-store/postgres.d.ts +3 -1
- package/dist/state-store/postgres.d.ts.map +1 -1
- package/dist/state-store/postgres.js +32 -9
- package/dist/state-store/postgres.js.map +1 -1
- package/dist/test-doubles/in-memory-state-store.d.ts +3 -1
- package/dist/test-doubles/in-memory-state-store.d.ts.map +1 -1
- package/dist/test-doubles/in-memory-state-store.js +14 -0
- package/dist/test-doubles/in-memory-state-store.js.map +1 -1
- package/dist/types.d.ts +95 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +24 -0
- package/dist/types.js.map +1 -1
- package/package.json +4 -3
- package/src/migrations/001-saga-state.sql +139 -5
package/dist/types.d.ts
CHANGED
|
@@ -30,6 +30,12 @@ export interface SagaStateRow {
|
|
|
30
30
|
failure_reason: string | null;
|
|
31
31
|
failure_step: string | null;
|
|
32
32
|
compensation_log: CompensationLogEntry[];
|
|
33
|
+
/** Durable compensation/undo stack (§ 5.8 recovery). Persisted in
|
|
34
|
+
* completed-step order so a fresh process can reload the pending
|
|
35
|
+
* compensations and run them in reverse on recovery. Empty when the
|
|
36
|
+
* saga has no completed compensable steps, or after a successful
|
|
37
|
+
* completion / compensation walk clears it. */
|
|
38
|
+
undo_stack: UndoStackEntry[];
|
|
33
39
|
last_admin_action: string | null;
|
|
34
40
|
last_admin_actor_id: string | null;
|
|
35
41
|
last_admin_at: string | null;
|
|
@@ -42,6 +48,26 @@ export interface CompensationLogEntry {
|
|
|
42
48
|
error?: string;
|
|
43
49
|
ts: string;
|
|
44
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Durable undo-stack entry persisted on `saga_state.undo_stack`.
|
|
53
|
+
*
|
|
54
|
+
* The compensation/undo stack was process-local (an in-memory `Map`) until
|
|
55
|
+
* this entry was added — a process restart mid-saga LOST the list of
|
|
56
|
+
* completed steps' compensations, so a recovering process could not roll
|
|
57
|
+
* the saga back. The undo *function* itself cannot be serialized, so the
|
|
58
|
+
* durable record carries the step's IDENTITY (`step_name`), its `output`
|
|
59
|
+
* (the argument the undo fn receives), the compensation `mode`, and
|
|
60
|
+
* `has_undo` (false for steps registered with no undo — they log
|
|
61
|
+
* `skipped_no_undo`). On recovery, a fresh process re-binds the undo fn
|
|
62
|
+
* from the registered saga handler keyed by `step_name`.
|
|
63
|
+
*/
|
|
64
|
+
export interface UndoStackEntry {
|
|
65
|
+
step_name: string;
|
|
66
|
+
output: unknown;
|
|
67
|
+
mode: "strict" | "best-effort";
|
|
68
|
+
/** false → the step had no undo (no-op compensation; logs skipped_no_undo). */
|
|
69
|
+
has_undo: boolean;
|
|
70
|
+
}
|
|
45
71
|
/** § 5.4 — saga owns inputs only; @nodii/idempotency computes the key. */
|
|
46
72
|
export interface IdempotencyShim {
|
|
47
73
|
/**
|
|
@@ -76,6 +102,16 @@ export interface SagaStateStore {
|
|
|
76
102
|
updateSagaStatus(sagaId: string, update: Partial<Pick<SagaStateRow, "status" | "current_step" | "completed_at" | "failure_reason" | "failure_step" | "last_admin_action" | "last_admin_actor_id" | "last_admin_at" | "cancel_reason" | "next_resume_at" | "reaper_grace_ms">>): Promise<void>;
|
|
77
103
|
appendStepOutput(sagaId: string, stepName: string, output: unknown): Promise<void>;
|
|
78
104
|
appendCompensationLog(sagaId: string, entry: CompensationLogEntry): Promise<void>;
|
|
105
|
+
/** Durably append one undo-stack entry to `saga_state.undo_stack` (§ 5.8
|
|
106
|
+
* recovery). Called by `step()` after a compensable step succeeds, so
|
|
107
|
+
* the pending-compensation list survives a process restart. Append-only
|
|
108
|
+
* + ordered (completed-step order) — the recovery + compensation walk
|
|
109
|
+
* reverse it. Production-bound stores (Postgres) persist to the jsonb
|
|
110
|
+
* column; the in-memory double mirrors it in the row. */
|
|
111
|
+
appendUndoEntry(sagaId: string, entry: UndoStackEntry): Promise<void>;
|
|
112
|
+
/** Clear `saga_state.undo_stack` once compensation has fully run (or the
|
|
113
|
+
* saga completed and no rollback is possible/needed). Idempotent. */
|
|
114
|
+
clearUndoStack(sagaId: string): Promise<void>;
|
|
79
115
|
/** Optional enumeration — production-bound stores (Postgres) MUST
|
|
80
116
|
* implement this; tests can omit. Returns a defensive snapshot. */
|
|
81
117
|
list?(filter?: ListSagasFilter): Promise<SagaStateRow[]>;
|
|
@@ -228,10 +264,50 @@ export interface SagaInterceptorCall {
|
|
|
228
264
|
};
|
|
229
265
|
request: unknown;
|
|
230
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Authorization context handed to the {@link SagaAdminAuthorizer} for every
|
|
269
|
+
* admin RPC. `actorPermissions` is the caller's effective permission set —
|
|
270
|
+
* the consuming service resolves it from the verified actor envelope
|
|
271
|
+
* (`@nodii/grpc-auth` `checkUserPermission` / `NodiiClaims.permissions`)
|
|
272
|
+
* and passes it on the request. The authorizer decides whether the actor
|
|
273
|
+
* holds `requiredPermission` (one of the locked {@link SAGA_ADMIN_PERMISSIONS}).
|
|
274
|
+
*/
|
|
275
|
+
export interface SagaAdminAuthContext {
|
|
276
|
+
/** The locked permission the RPC requires (a `SAGA_ADMIN_PERMISSIONS` value). */
|
|
277
|
+
requiredPermission: SagaAdminPermission;
|
|
278
|
+
/** The gRPC-style method name being authorized (e.g. "RetryStep"). */
|
|
279
|
+
method: string;
|
|
280
|
+
/** Saga the op targets (for tenant-scoped or row-scoped authorizers). */
|
|
281
|
+
sagaId: string;
|
|
282
|
+
/** The caller's effective permission set, resolved upstream from the
|
|
283
|
+
* verified actor envelope. Empty/absent ⇒ unauthorized. */
|
|
284
|
+
actorPermissions: readonly string[];
|
|
285
|
+
/** Opaque actor id (audit + row-scoped checks); optional. */
|
|
286
|
+
actorId?: string;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Pluggable admin authorizer (§ 5.10). Returns `true` to allow, `false` (or
|
|
290
|
+
* throws) to reject. The DEFAULT authorizer (when none is supplied) is a
|
|
291
|
+
* pure permission-set membership check against the locked
|
|
292
|
+
* {@link SAGA_ADMIN_PERMISSIONS} — i.e. `ctx.actorPermissions.includes(
|
|
293
|
+
* ctx.requiredPermission)`. Services that need tenant/row scoping or a
|
|
294
|
+
* remote RBAC resolver supply their own. There is NO "allow-all" default
|
|
295
|
+
* (R1): an op with no matching permission in `actorPermissions` is rejected
|
|
296
|
+
* with {@link SagaAdminUnauthorized}.
|
|
297
|
+
*/
|
|
298
|
+
export type SagaAdminAuthorizer = (ctx: SagaAdminAuthContext) => boolean | Promise<boolean>;
|
|
231
299
|
/** SagaAdminService factory opts. */
|
|
232
300
|
export interface SagaAdminServiceOpts {
|
|
233
301
|
stateStore: SagaStateStore;
|
|
234
302
|
audit?: TelemetryAuditEmitter;
|
|
303
|
+
/**
|
|
304
|
+
* Admin authorizer (§ 5.10). When omitted, the built-in
|
|
305
|
+
* permission-membership authorizer is used: each write/read RPC is gated
|
|
306
|
+
* on its locked {@link SAGA_ADMIN_PERMISSIONS} value, checked against the
|
|
307
|
+
* `actorPermissions` carried on the request. Supply a custom authorizer
|
|
308
|
+
* for tenant/row-scoped checks or a remote RBAC resolver.
|
|
309
|
+
*/
|
|
310
|
+
authorizer?: SagaAdminAuthorizer;
|
|
235
311
|
}
|
|
236
312
|
/** § 5.10 — minimum justification length per D164. */
|
|
237
313
|
export declare const MIN_JUSTIFICATION_CHARS = 20;
|
|
@@ -281,6 +357,25 @@ export declare class SagaCompensationFailed extends SagaError {
|
|
|
281
357
|
export declare class JustificationRequired extends SagaError {
|
|
282
358
|
constructor(actual: number);
|
|
283
359
|
}
|
|
360
|
+
/**
|
|
361
|
+
* Raised by every `SagaAdminServer` RPC when the caller does not hold the
|
|
362
|
+
* locked admin permission the op requires (one of {@link SAGA_ADMIN_PERMISSIONS}).
|
|
363
|
+
*
|
|
364
|
+
* Administrative saga operations (force-complete / cancel / retry / skip /
|
|
365
|
+
* force-compensate / manual-resolve, and the read RPCs) MUST be gated on an
|
|
366
|
+
* admin authorization — before this error existed, any caller could drive
|
|
367
|
+
* them with only a `justification` string. The rejection path still emits
|
|
368
|
+
* the `*_unauthorized` audit row so the denied attempt is traceable.
|
|
369
|
+
*
|
|
370
|
+
* gRPC mapping: PERMISSION_DENIED (code 7).
|
|
371
|
+
*/
|
|
372
|
+
export declare class SagaAdminUnauthorized extends SagaError {
|
|
373
|
+
/** The locked permission the rejected op required. */
|
|
374
|
+
readonly requiredPermission: SagaAdminPermission;
|
|
375
|
+
/** The RPC method that was rejected. */
|
|
376
|
+
readonly method: string;
|
|
377
|
+
constructor(method: string, requiredPermission: SagaAdminPermission);
|
|
378
|
+
}
|
|
284
379
|
export declare class SagaTypeNotRegistered extends SagaError {
|
|
285
380
|
readonly sagaType: string;
|
|
286
381
|
constructor(sagaType: string);
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -103,6 +103,30 @@ export class JustificationRequired extends SagaError {
|
|
|
103
103
|
this.name = "JustificationRequired";
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Raised by every `SagaAdminServer` RPC when the caller does not hold the
|
|
108
|
+
* locked admin permission the op requires (one of {@link SAGA_ADMIN_PERMISSIONS}).
|
|
109
|
+
*
|
|
110
|
+
* Administrative saga operations (force-complete / cancel / retry / skip /
|
|
111
|
+
* force-compensate / manual-resolve, and the read RPCs) MUST be gated on an
|
|
112
|
+
* admin authorization — before this error existed, any caller could drive
|
|
113
|
+
* them with only a `justification` string. The rejection path still emits
|
|
114
|
+
* the `*_unauthorized` audit row so the denied attempt is traceable.
|
|
115
|
+
*
|
|
116
|
+
* gRPC mapping: PERMISSION_DENIED (code 7).
|
|
117
|
+
*/
|
|
118
|
+
export class SagaAdminUnauthorized extends SagaError {
|
|
119
|
+
/** The locked permission the rejected op required. */
|
|
120
|
+
requiredPermission;
|
|
121
|
+
/** The RPC method that was rejected. */
|
|
122
|
+
method;
|
|
123
|
+
constructor(method, requiredPermission) {
|
|
124
|
+
super(`saga_admin_unauthorized: ${method} requires the '${requiredPermission}' permission; caller is not authorized.`);
|
|
125
|
+
this.name = "SagaAdminUnauthorized";
|
|
126
|
+
this.method = method;
|
|
127
|
+
this.requiredPermission = requiredPermission;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
106
130
|
export class SagaTypeNotRegistered extends SagaError {
|
|
107
131
|
sagaType;
|
|
108
132
|
constructor(sagaType) {
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,kEAAkE;AAClE,uDAAuD;AACvD,EAAE;AACF,gBAAgB;AAChB,oFAAoF;AACpF,gFAAgF;AAChF,oEAAoE;AACpE,2EAA2E;AAC3E,8EAA8E;AAC9E,iFAAiF;AACjF,wEAAwE;AACxE,gDAAgD;AAChD,oFAAoF;AACpF,EAAE;AACF,qCAAqC;AACrC,kEAAkE;AAClE,sCAAsC;AACtC,iDAAiD;AACjD,2DAA2D;AAC3D,oDAAoD;AACpD,+EAA+E;AAC/E,mFAAmF;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodii/saga",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Saga orchestration library for the Nodii microservice stack — createSaga + step + stepParallel + cross-saga signals + sagaContext interceptor + SagaAdminService factory + @sagaCallable discipline tag + real PostgresSagaStateStore + RedisSignalBus + Pattern 2 async-step + reaper. Polyglot per D159 (TS + Python + Go).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,8 +44,9 @@
|
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@nodii/
|
|
48
|
-
"@nodii/
|
|
47
|
+
"@nodii/db-rls": "0.7.2",
|
|
48
|
+
"@nodii/grpc-auth": "0.9.1",
|
|
49
|
+
"@nodii/telemetry": "0.9.0",
|
|
49
50
|
"@types/bun": "^1.3.13",
|
|
50
51
|
"ioredis": "^5.4.0",
|
|
51
52
|
"postgres": "^3.4.0",
|
|
@@ -4,13 +4,21 @@
|
|
|
4
4
|
-- 5.5 lists it under "lifecycle" alongside completed_at). Plus a small
|
|
5
5
|
-- saga_outbox for Pattern 2 begin/completion events.
|
|
6
6
|
--
|
|
7
|
-
-- This file is the
|
|
8
|
-
--
|
|
9
|
-
--
|
|
7
|
+
-- This file is the downstream-facing copy of the saga migration for services
|
|
8
|
+
-- that run their own migration tool (Flyway / sqlx-cli / golang-migrate /
|
|
9
|
+
-- alembic). The runtime source of truth is the inlined SAGA_STATE_MIGRATION_SQL
|
|
10
|
+
-- constant in `src/migrations/index.ts` (applied by `applySagaMigrations`); this
|
|
11
|
+
-- .sql must stay in lockstep with it. A drift-guard test in
|
|
12
|
+
-- `tests/rls.integration.test.ts` asserts the two produce an identical statement
|
|
13
|
+
-- sequence (via `splitStatements`), so an edit to one that misses the other
|
|
14
|
+
-- fails CI.
|
|
10
15
|
|
|
11
16
|
CREATE TABLE IF NOT EXISTS saga_state (
|
|
12
17
|
id TEXT PRIMARY KEY,
|
|
13
|
-
tenant_id
|
|
18
|
+
-- D412 / 08-rls v7 (A1): tenant_id is UUID NOT NULL. Fresh installs get the
|
|
19
|
+
-- UUID type directly; pre-D412 installs (tenant_id TEXT) are migrated in
|
|
20
|
+
-- place by the guarded ALTER block below.
|
|
21
|
+
tenant_id UUID NOT NULL,
|
|
14
22
|
type TEXT NOT NULL,
|
|
15
23
|
status TEXT NOT NULL,
|
|
16
24
|
current_step TEXT,
|
|
@@ -39,6 +47,11 @@ CREATE TABLE IF NOT EXISTS saga_state (
|
|
|
39
47
|
|
|
40
48
|
-- Compensation
|
|
41
49
|
compensation_log JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
50
|
+
-- Durable undo/compensation stack (§ 5.8 recovery). Pending-compensation
|
|
51
|
+
-- list persisted in completed-step order so a fresh process can reload it
|
|
52
|
+
-- after a restart and run the undos in reverse. Was process-local (in-
|
|
53
|
+
-- memory) before this column existed → a crash mid-saga lost the rollback.
|
|
54
|
+
undo_stack JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
42
55
|
|
|
43
56
|
-- Admin recovery (D164)
|
|
44
57
|
last_admin_action TEXT,
|
|
@@ -53,6 +66,30 @@ CREATE TABLE IF NOT EXISTS saga_state (
|
|
|
53
66
|
-- Idempotent add for services that bootstrapped saga_state before the
|
|
54
67
|
-- per-step grace column existed (request 5092d0ba / drift e5e813d0).
|
|
55
68
|
ALTER TABLE saga_state ADD COLUMN IF NOT EXISTS reaper_grace_ms BIGINT;
|
|
69
|
+
-- Idempotent add for services that bootstrapped saga_state before the
|
|
70
|
+
-- durable undo stack existed (saga admin-authz + undo-durability wave).
|
|
71
|
+
ALTER TABLE saga_state ADD COLUMN IF NOT EXISTS undo_stack JSONB NOT NULL DEFAULT '[]'::jsonb;
|
|
72
|
+
|
|
73
|
+
-- D412 / 08-rls v7 (A1) — idempotent in-place migration of pre-D412 installs
|
|
74
|
+
-- whose tenant_id is still TEXT. Guarded so re-runs (and fresh UUID installs)
|
|
75
|
+
-- are a no-op: only ALTER when the column's current type is not already uuid.
|
|
76
|
+
-- `USING tenant_id::uuid` fails loudly on non-UUID rows — under A1 those are
|
|
77
|
+
-- malformed tenant identifiers that must be fixed, not silently coerced.
|
|
78
|
+
DO $$
|
|
79
|
+
BEGIN
|
|
80
|
+
IF EXISTS (
|
|
81
|
+
SELECT 1 FROM information_schema.columns
|
|
82
|
+
WHERE table_schema = current_schema()
|
|
83
|
+
AND table_name = 'saga_state'
|
|
84
|
+
AND column_name = 'tenant_id'
|
|
85
|
+
AND data_type <> 'uuid'
|
|
86
|
+
) THEN
|
|
87
|
+
EXECUTE 'ALTER TABLE saga_state ALTER COLUMN tenant_id TYPE uuid USING tenant_id::uuid';
|
|
88
|
+
END IF;
|
|
89
|
+
END
|
|
90
|
+
$$;
|
|
91
|
+
-- Enforce NOT NULL (A1: every tenant-scoped row carries a tenant). Idempotent.
|
|
92
|
+
ALTER TABLE saga_state ALTER COLUMN tenant_id SET NOT NULL;
|
|
56
93
|
|
|
57
94
|
-- Spec § 5.5 — four indexes.
|
|
58
95
|
CREATE UNIQUE INDEX IF NOT EXISTS saga_state_trigger_trace_id_uniq
|
|
@@ -76,7 +113,11 @@ CREATE TABLE IF NOT EXISTS saga_outbox (
|
|
|
76
113
|
step_name TEXT NOT NULL,
|
|
77
114
|
event_type TEXT NOT NULL,
|
|
78
115
|
payload JSONB NOT NULL,
|
|
79
|
-
tenant_id
|
|
116
|
+
-- D412 / 08-rls v7 (A1): tenant_id is UUID so the canonical UUID-typed A1
|
|
117
|
+
-- policies below can bind. NULLABLE by design (unlike saga_state): the
|
|
118
|
+
-- participant-worker writes a NULL tenant for tenant-less sagas, and a NULL
|
|
119
|
+
-- tenant row is owner-only (invisible to non-owner roles) under the policies.
|
|
120
|
+
tenant_id UUID,
|
|
80
121
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
81
122
|
delivered_at TIMESTAMPTZ
|
|
82
123
|
);
|
|
@@ -84,3 +125,96 @@ CREATE TABLE IF NOT EXISTS saga_outbox (
|
|
|
84
125
|
CREATE INDEX IF NOT EXISTS saga_outbox_saga_idx ON saga_outbox (saga_id, created_at);
|
|
85
126
|
CREATE INDEX IF NOT EXISTS saga_outbox_undelivered_idx ON saga_outbox (delivered_at)
|
|
86
127
|
WHERE delivered_at IS NULL;
|
|
128
|
+
|
|
129
|
+
-- D412 / 08-rls v7 (A1) — idempotent in-place migration of pre-D412 installs
|
|
130
|
+
-- whose saga_outbox.tenant_id is still TEXT. Guarded so re-runs (and fresh UUID
|
|
131
|
+
-- installs) are a no-op. Both the type change AND the one-time backfill of any
|
|
132
|
+
-- legacy NULL tenant (from the parent saga_state row) live INSIDE the guard, so
|
|
133
|
+
-- the backfill runs only during the actual upgrade — not as an unbounded scan on
|
|
134
|
+
-- every boot. The backfill runs after the type change (both columns uuid) via a
|
|
135
|
+
-- dynamic EXECUTE so it is planned against the just-altered column; orphaned rows
|
|
136
|
+
-- whose saga is gone simply stay NULL (owner-only under RLS).
|
|
137
|
+
DO $$
|
|
138
|
+
BEGIN
|
|
139
|
+
IF EXISTS (
|
|
140
|
+
SELECT 1 FROM information_schema.columns
|
|
141
|
+
WHERE table_schema = current_schema()
|
|
142
|
+
AND table_name = 'saga_outbox'
|
|
143
|
+
AND column_name = 'tenant_id'
|
|
144
|
+
AND data_type <> 'uuid'
|
|
145
|
+
) THEN
|
|
146
|
+
EXECUTE 'ALTER TABLE saga_outbox ALTER COLUMN tenant_id TYPE uuid USING tenant_id::uuid';
|
|
147
|
+
EXECUTE 'UPDATE saga_outbox o SET tenant_id = s.tenant_id FROM saga_state s WHERE o.saga_id = s.id AND o.tenant_id IS NULL';
|
|
148
|
+
END IF;
|
|
149
|
+
END
|
|
150
|
+
$$;
|
|
151
|
+
|
|
152
|
+
-- D412 / 08-rls v7 (A1) — canonical 5-policy* RLS on saga_state. The CREATE
|
|
153
|
+
-- POLICY statements below are byte-equal to
|
|
154
|
+
-- withRls('saga_state', { allow: ['SELECT','INSERT','UPDATE','DELETE'] })
|
|
155
|
+
-- from @nodii/db-rls. generateSagaStateRlsDdl() in migrations/index.ts INLINES
|
|
156
|
+
-- that same block as a string constant (NO runtime db-rls call → the published
|
|
157
|
+
-- @nodii/saga has no runtime db-rls dependency); a byte-equality test asserts
|
|
158
|
+
-- the inlined const stays equal to db-rls's live generator output, so this file
|
|
159
|
+
-- and the inlined const stay in lockstep. *full-CRUD allow → 1 owner
|
|
160
|
+
-- + 4 authenticated + 4 services = 9 policies; "5-policy" is the doctrine's
|
|
161
|
+
-- floor name for the per-role/per-verb family.
|
|
162
|
+
--
|
|
163
|
+
-- CREATE POLICY has no IF NOT EXISTS, so each is preceded by DROP POLICY
|
|
164
|
+
-- IF EXISTS to keep the migration idempotent. ENABLE ROW LEVEL SECURITY and
|
|
165
|
+
-- the GRANTs are already idempotent.
|
|
166
|
+
--
|
|
167
|
+
-- Adopters bind the app.tenant_id GUC (via auth.set_tenant_id / the db-rls
|
|
168
|
+
-- withSystemContext dispatch) on the nodii_services pool; this lib only
|
|
169
|
+
-- emits the DDL (08-rls § 7).
|
|
170
|
+
ALTER TABLE saga_state ENABLE ROW LEVEL SECURITY;
|
|
171
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON saga_state TO nodii_services;
|
|
172
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON saga_state TO authenticated;
|
|
173
|
+
DROP POLICY IF EXISTS saga_state_owner_policy ON saga_state;
|
|
174
|
+
CREATE POLICY saga_state_owner_policy ON saga_state FOR ALL TO nodii_owner USING (true) WITH CHECK (true);
|
|
175
|
+
DROP POLICY IF EXISTS saga_state_auth_select_policy ON saga_state;
|
|
176
|
+
CREATE POLICY saga_state_auth_select_policy ON saga_state FOR SELECT TO authenticated USING (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
177
|
+
DROP POLICY IF EXISTS saga_state_auth_insert_policy ON saga_state;
|
|
178
|
+
CREATE POLICY saga_state_auth_insert_policy ON saga_state FOR INSERT TO authenticated WITH CHECK (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
179
|
+
DROP POLICY IF EXISTS saga_state_auth_update_policy ON saga_state;
|
|
180
|
+
CREATE POLICY saga_state_auth_update_policy ON saga_state FOR UPDATE TO authenticated USING (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id()))) WITH CHECK (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
181
|
+
DROP POLICY IF EXISTS saga_state_auth_delete_policy ON saga_state;
|
|
182
|
+
CREATE POLICY saga_state_auth_delete_policy ON saga_state FOR DELETE TO authenticated USING (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
183
|
+
DROP POLICY IF EXISTS saga_state_svc_select_policy ON saga_state;
|
|
184
|
+
CREATE POLICY saga_state_svc_select_policy ON saga_state FOR SELECT TO nodii_services USING (tenant_id = auth.get_tenant_id());
|
|
185
|
+
DROP POLICY IF EXISTS saga_state_svc_insert_policy ON saga_state;
|
|
186
|
+
CREATE POLICY saga_state_svc_insert_policy ON saga_state FOR INSERT TO nodii_services WITH CHECK (tenant_id = auth.get_tenant_id());
|
|
187
|
+
DROP POLICY IF EXISTS saga_state_svc_update_policy ON saga_state;
|
|
188
|
+
CREATE POLICY saga_state_svc_update_policy ON saga_state FOR UPDATE TO nodii_services USING (tenant_id = auth.get_tenant_id()) WITH CHECK (tenant_id = auth.get_tenant_id());
|
|
189
|
+
DROP POLICY IF EXISTS saga_state_svc_delete_policy ON saga_state;
|
|
190
|
+
CREATE POLICY saga_state_svc_delete_policy ON saga_state FOR DELETE TO nodii_services USING (tenant_id = auth.get_tenant_id());
|
|
191
|
+
|
|
192
|
+
-- D412 / 08-rls v7 (A1) — canonical 5-policy* RLS on saga_outbox (every table
|
|
193
|
+
-- with a tenant_id column, no exceptions). saga_outbox is tenant-scoped (each
|
|
194
|
+
-- row carries the saga's tenant_id) and readOutboxForSaga filters by saga_id
|
|
195
|
+
-- ONLY, so RLS is the sole tenant-isolation boundary. Byte-equal to
|
|
196
|
+
-- withRls('saga_outbox', { allow: ['SELECT','INSERT','UPDATE','DELETE'] })
|
|
197
|
+
-- from @nodii/db-rls; generateSagaOutboxRlsDdl() in migrations/index.ts inlines
|
|
198
|
+
-- the same block (no runtime db-rls dep), byte-equality-asserted in
|
|
199
|
+
-- tests/rls.integration.test.ts. *1 owner + 4 authenticated + 4 services = 9.
|
|
200
|
+
ALTER TABLE saga_outbox ENABLE ROW LEVEL SECURITY;
|
|
201
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON saga_outbox TO nodii_services;
|
|
202
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON saga_outbox TO authenticated;
|
|
203
|
+
DROP POLICY IF EXISTS saga_outbox_owner_policy ON saga_outbox;
|
|
204
|
+
CREATE POLICY saga_outbox_owner_policy ON saga_outbox FOR ALL TO nodii_owner USING (true) WITH CHECK (true);
|
|
205
|
+
DROP POLICY IF EXISTS saga_outbox_auth_select_policy ON saga_outbox;
|
|
206
|
+
CREATE POLICY saga_outbox_auth_select_policy ON saga_outbox FOR SELECT TO authenticated USING (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
207
|
+
DROP POLICY IF EXISTS saga_outbox_auth_insert_policy ON saga_outbox;
|
|
208
|
+
CREATE POLICY saga_outbox_auth_insert_policy ON saga_outbox FOR INSERT TO authenticated WITH CHECK (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
209
|
+
DROP POLICY IF EXISTS saga_outbox_auth_update_policy ON saga_outbox;
|
|
210
|
+
CREATE POLICY saga_outbox_auth_update_policy ON saga_outbox FOR UPDATE TO authenticated USING (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id()))) WITH CHECK (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
211
|
+
DROP POLICY IF EXISTS saga_outbox_auth_delete_policy ON saga_outbox;
|
|
212
|
+
CREATE POLICY saga_outbox_auth_delete_policy ON saga_outbox FOR DELETE TO authenticated USING (tenant_id IN (SELECT auth.user_tenant_ids(auth.get_user_id())));
|
|
213
|
+
DROP POLICY IF EXISTS saga_outbox_svc_select_policy ON saga_outbox;
|
|
214
|
+
CREATE POLICY saga_outbox_svc_select_policy ON saga_outbox FOR SELECT TO nodii_services USING (tenant_id = auth.get_tenant_id());
|
|
215
|
+
DROP POLICY IF EXISTS saga_outbox_svc_insert_policy ON saga_outbox;
|
|
216
|
+
CREATE POLICY saga_outbox_svc_insert_policy ON saga_outbox FOR INSERT TO nodii_services WITH CHECK (tenant_id = auth.get_tenant_id());
|
|
217
|
+
DROP POLICY IF EXISTS saga_outbox_svc_update_policy ON saga_outbox;
|
|
218
|
+
CREATE POLICY saga_outbox_svc_update_policy ON saga_outbox FOR UPDATE TO nodii_services USING (tenant_id = auth.get_tenant_id()) WITH CHECK (tenant_id = auth.get_tenant_id());
|
|
219
|
+
DROP POLICY IF EXISTS saga_outbox_svc_delete_policy ON saga_outbox;
|
|
220
|
+
CREATE POLICY saga_outbox_svc_delete_policy ON saga_outbox FOR DELETE TO nodii_services USING (tenant_id = auth.get_tenant_id());
|