@nodii/saga 0.6.1 → 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.
@@ -1,6 +1,16 @@
1
1
  type SqlClient = {
2
2
  unsafe: (sql: string, args?: unknown[]) => Promise<any>;
3
3
  };
4
+ /**
5
+ * Return the canonical A1 RLS DDL for `saga_state`. Returns the inlined
6
+ * constant verbatim — no runtime `@nodii/db-rls` call (see `SAGA_STATE_RLS_DDL`).
7
+ */
8
+ export declare function generateSagaStateRlsDdl(): string;
9
+ /**
10
+ * Return the canonical A1 RLS DDL for `saga_outbox`. Inlined constant verbatim —
11
+ * no runtime `@nodii/db-rls` call (see `SAGA_OUTBOX_RLS_DDL`).
12
+ */
13
+ export declare function generateSagaOutboxRlsDdl(): string;
4
14
  export declare function getSagaStateMigrationSQL(): string;
5
15
  /**
6
16
  * Apply the saga_state + saga_outbox migrations idempotently. Safe to call
@@ -13,7 +23,15 @@ export declare function getSagaStateMigrationSQL(): string;
13
23
  * whitespace blocks are skipped.
14
24
  */
15
25
  export declare function applySagaMigrations(sql: SqlClient): Promise<void>;
16
- /** Internal — exported only for unit-test coverage on the splitter. */
26
+ /**
27
+ * Internal — exported only for unit-test coverage on the splitter.
28
+ *
29
+ * Dollar-quote-aware: a `$$`-delimited body (e.g. the D412 `DO $$ ... $$;`
30
+ * guarded TEXT→UUID migration) may contain inner lines ending in `;` that
31
+ * must NOT terminate the statement. We track an open `$tag$` ... `$tag$`
32
+ * span and only honor a trailing `;` as a statement boundary when no dollar
33
+ * quote is open. (postgres.js sends each split statement via `.unsafe`.)
34
+ */
17
35
  export declare function splitStatements(ddl: string): string[];
18
36
  export {};
19
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAOA,KAAK,SAAS,GAAG;IAEf,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACzD,CAAC;AAkEF,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvE;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAerD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAOA,KAAK,SAAS,GAAG;IAEf,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CACzD,CAAC;AA8CF;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AA8CD;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAgGD,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBrD"}
@@ -4,6 +4,106 @@
4
4
  // per-service migration runner. The SQL is shipped alongside this module
5
5
  // as `001-saga-state.sql` so a service that uses a different runner
6
6
  // (Flyway, golang-migrate, alembic, etc.) can copy it directly.
7
+ /**
8
+ * Canonical A1 RLS DDL for `saga_state` (D412 / 08-rls v7 § 4) — INLINED as a
9
+ * string constant so the runtime + published `@nodii/saga` package carry NO
10
+ * dependency on `@nodii/db-rls` (a runtime/peer dep would pull the whole RLS
11
+ * pooling + migrate-gen surface into saga and trigger a version cascade).
12
+ *
13
+ * saga_state does full CRUD, so it carries all four verbs: 1 owner policy + 4
14
+ * authenticated policies + 4 services policies, plus the per-role GRANTs.
15
+ * Postgres has no `CREATE POLICY IF NOT EXISTS`, so each `CREATE POLICY` is
16
+ * preceded by a matching `DROP POLICY IF EXISTS ... ;` to keep the migration
17
+ * idempotent. ENABLE + GRANT are already idempotent.
18
+ *
19
+ * This block is byte-equal to `@nodii/db-rls`'s
20
+ * `withRls("saga_state", { allow: ["SELECT","INSERT","UPDATE","DELETE"] })` +
21
+ * `generateTableGrants(...)` output (with the DROP-before-CREATE
22
+ * interleaving + grants reordered after ENABLE). The byte-equality is asserted
23
+ * in `tests/rls.integration.test.ts` against the live db-rls generators
24
+ * (db-rls is a DEV/test-only dependency that guards canonical drift — it is
25
+ * NEVER imported by shipped saga source). The vendored copy in
26
+ * `001-saga-state.sql` is byte-equal to this constant (sans the DO-block ALTER
27
+ * which lives above the table DDL there).
28
+ */
29
+ const SAGA_STATE_RLS_DDL = `ALTER TABLE saga_state ENABLE ROW LEVEL SECURITY;
30
+ GRANT SELECT, INSERT, UPDATE, DELETE ON saga_state TO nodii_services;
31
+ GRANT SELECT, INSERT, UPDATE, DELETE ON saga_state TO authenticated;
32
+ DROP POLICY IF EXISTS saga_state_owner_policy ON saga_state;
33
+ CREATE POLICY saga_state_owner_policy ON saga_state FOR ALL TO nodii_owner USING (true) WITH CHECK (true);
34
+ DROP POLICY IF EXISTS saga_state_auth_select_policy ON saga_state;
35
+ 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())));
36
+ DROP POLICY IF EXISTS saga_state_auth_insert_policy ON saga_state;
37
+ 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())));
38
+ DROP POLICY IF EXISTS saga_state_auth_update_policy ON saga_state;
39
+ 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())));
40
+ DROP POLICY IF EXISTS saga_state_auth_delete_policy ON saga_state;
41
+ 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())));
42
+ DROP POLICY IF EXISTS saga_state_svc_select_policy ON saga_state;
43
+ CREATE POLICY saga_state_svc_select_policy ON saga_state FOR SELECT TO nodii_services USING (tenant_id = auth.get_tenant_id());
44
+ DROP POLICY IF EXISTS saga_state_svc_insert_policy ON saga_state;
45
+ CREATE POLICY saga_state_svc_insert_policy ON saga_state FOR INSERT TO nodii_services WITH CHECK (tenant_id = auth.get_tenant_id());
46
+ DROP POLICY IF EXISTS saga_state_svc_update_policy ON saga_state;
47
+ 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());
48
+ DROP POLICY IF EXISTS saga_state_svc_delete_policy ON saga_state;
49
+ CREATE POLICY saga_state_svc_delete_policy ON saga_state FOR DELETE TO nodii_services USING (tenant_id = auth.get_tenant_id());`;
50
+ /**
51
+ * Return the canonical A1 RLS DDL for `saga_state`. Returns the inlined
52
+ * constant verbatim — no runtime `@nodii/db-rls` call (see `SAGA_STATE_RLS_DDL`).
53
+ */
54
+ export function generateSagaStateRlsDdl() {
55
+ return SAGA_STATE_RLS_DDL;
56
+ }
57
+ /**
58
+ * Canonical A1 RLS DDL for `saga_outbox` (D412 / 08-rls v7 § 1.1 — "every table
59
+ * with a `tenant_id` column gets the 5-policy A1 RLS, no exceptions"). The
60
+ * Pattern-2 outbox is tenant-scoped (every begin/completion row carries the
61
+ * saga's `tenant_id`) and `readOutboxForSaga` filters by `saga_id` ONLY — so RLS
62
+ * is the sole tenant-isolation boundary on this table, exactly as for
63
+ * `saga_state`.
64
+ *
65
+ * Identical structure to `SAGA_STATE_RLS_DDL` (1 owner + 4 authenticated + 4
66
+ * services policies + per-role GRANTs), retargeted to `saga_outbox`; byte-equal
67
+ * to `withRls("saga_outbox", { allow: [...] })` + `generateTableGrants(...)`,
68
+ * asserted in `tests/rls.integration.test.ts`.
69
+ *
70
+ * `saga_outbox.tenant_id` is `UUID` but — unlike `saga_state` — intentionally
71
+ * NULLABLE: the participant-worker writes a NULL tenant for tenant-less sagas
72
+ * (participant-worker.ts) and `createSaga` permits an absent tenant. Under these
73
+ * policies a NULL-tenant row is invisible to every non-owner role
74
+ * (`NULL = auth.get_tenant_id()` and `NULL IN (...)` are both NULL/false), i.e.
75
+ * owner-only — a safe, non-leaking outcome. A1 mandates the 5-policy RLS on
76
+ * every `tenant_id` table; it does NOT mandate NOT NULL (that is a `saga_state`
77
+ * choice), so this is fully A1-conformant.
78
+ */
79
+ const SAGA_OUTBOX_RLS_DDL = `ALTER TABLE saga_outbox ENABLE ROW LEVEL SECURITY;
80
+ GRANT SELECT, INSERT, UPDATE, DELETE ON saga_outbox TO nodii_services;
81
+ GRANT SELECT, INSERT, UPDATE, DELETE ON saga_outbox TO authenticated;
82
+ DROP POLICY IF EXISTS saga_outbox_owner_policy ON saga_outbox;
83
+ CREATE POLICY saga_outbox_owner_policy ON saga_outbox FOR ALL TO nodii_owner USING (true) WITH CHECK (true);
84
+ DROP POLICY IF EXISTS saga_outbox_auth_select_policy ON saga_outbox;
85
+ 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())));
86
+ DROP POLICY IF EXISTS saga_outbox_auth_insert_policy ON saga_outbox;
87
+ 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())));
88
+ DROP POLICY IF EXISTS saga_outbox_auth_update_policy ON saga_outbox;
89
+ 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())));
90
+ DROP POLICY IF EXISTS saga_outbox_auth_delete_policy ON saga_outbox;
91
+ 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())));
92
+ DROP POLICY IF EXISTS saga_outbox_svc_select_policy ON saga_outbox;
93
+ CREATE POLICY saga_outbox_svc_select_policy ON saga_outbox FOR SELECT TO nodii_services USING (tenant_id = auth.get_tenant_id());
94
+ DROP POLICY IF EXISTS saga_outbox_svc_insert_policy ON saga_outbox;
95
+ CREATE POLICY saga_outbox_svc_insert_policy ON saga_outbox FOR INSERT TO nodii_services WITH CHECK (tenant_id = auth.get_tenant_id());
96
+ DROP POLICY IF EXISTS saga_outbox_svc_update_policy ON saga_outbox;
97
+ 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());
98
+ DROP POLICY IF EXISTS saga_outbox_svc_delete_policy ON saga_outbox;
99
+ CREATE POLICY saga_outbox_svc_delete_policy ON saga_outbox FOR DELETE TO nodii_services USING (tenant_id = auth.get_tenant_id());`;
100
+ /**
101
+ * Return the canonical A1 RLS DDL for `saga_outbox`. Inlined constant verbatim —
102
+ * no runtime `@nodii/db-rls` call (see `SAGA_OUTBOX_RLS_DDL`).
103
+ */
104
+ export function generateSagaOutboxRlsDdl() {
105
+ return SAGA_OUTBOX_RLS_DDL;
106
+ }
7
107
  /**
8
108
  * Canonical saga_state + saga_outbox migration. Kept inline here (NOT
9
109
  * read from disk at runtime) so the published artifact + the synthetic-
@@ -15,7 +115,7 @@
15
115
  const SAGA_STATE_MIGRATION_SQL = `
16
116
  CREATE TABLE IF NOT EXISTS saga_state (
17
117
  id TEXT PRIMARY KEY,
18
- tenant_id TEXT,
118
+ tenant_id UUID NOT NULL,
19
119
  type TEXT NOT NULL,
20
120
  status TEXT NOT NULL,
21
121
  current_step TEXT,
@@ -43,6 +143,20 @@ CREATE TABLE IF NOT EXISTS saga_state (
43
143
  );
44
144
  ALTER TABLE saga_state ADD COLUMN IF NOT EXISTS reaper_grace_ms BIGINT;
45
145
  ALTER TABLE saga_state ADD COLUMN IF NOT EXISTS undo_stack JSONB NOT NULL DEFAULT '[]'::jsonb;
146
+ DO $$
147
+ BEGIN
148
+ IF EXISTS (
149
+ SELECT 1 FROM information_schema.columns
150
+ WHERE table_schema = current_schema()
151
+ AND table_name = 'saga_state'
152
+ AND column_name = 'tenant_id'
153
+ AND data_type <> 'uuid'
154
+ ) THEN
155
+ EXECUTE 'ALTER TABLE saga_state ALTER COLUMN tenant_id TYPE uuid USING tenant_id::uuid';
156
+ END IF;
157
+ END
158
+ $$;
159
+ ALTER TABLE saga_state ALTER COLUMN tenant_id SET NOT NULL;
46
160
  CREATE UNIQUE INDEX IF NOT EXISTS saga_state_trigger_trace_id_uniq
47
161
  ON saga_state (trigger_trace_id);
48
162
  CREATE INDEX IF NOT EXISTS saga_state_dead_letter_idx
@@ -59,13 +173,29 @@ CREATE TABLE IF NOT EXISTS saga_outbox (
59
173
  step_name TEXT NOT NULL,
60
174
  event_type TEXT NOT NULL,
61
175
  payload JSONB NOT NULL,
62
- tenant_id TEXT,
176
+ tenant_id UUID,
63
177
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
64
178
  delivered_at TIMESTAMPTZ
65
179
  );
66
180
  CREATE INDEX IF NOT EXISTS saga_outbox_saga_idx ON saga_outbox (saga_id, created_at);
67
181
  CREATE INDEX IF NOT EXISTS saga_outbox_undelivered_idx ON saga_outbox (delivered_at)
68
182
  WHERE delivered_at IS NULL;
183
+ DO $$
184
+ BEGIN
185
+ IF EXISTS (
186
+ SELECT 1 FROM information_schema.columns
187
+ WHERE table_schema = current_schema()
188
+ AND table_name = 'saga_outbox'
189
+ AND column_name = 'tenant_id'
190
+ AND data_type <> 'uuid'
191
+ ) THEN
192
+ EXECUTE 'ALTER TABLE saga_outbox ALTER COLUMN tenant_id TYPE uuid USING tenant_id::uuid';
193
+ 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';
194
+ END IF;
195
+ END
196
+ $$;
197
+ ${generateSagaStateRlsDdl()}
198
+ ${generateSagaOutboxRlsDdl()}
69
199
  `.trim();
70
200
  export function getSagaStateMigrationSQL() {
71
201
  return SAGA_STATE_MIGRATION_SQL;
@@ -87,16 +217,35 @@ export async function applySagaMigrations(sql) {
87
217
  await sql.unsafe(stmt);
88
218
  }
89
219
  }
90
- /** Internal — exported only for unit-test coverage on the splitter. */
220
+ /**
221
+ * Internal — exported only for unit-test coverage on the splitter.
222
+ *
223
+ * Dollar-quote-aware: a `$$`-delimited body (e.g. the D412 `DO $$ ... $$;`
224
+ * guarded TEXT→UUID migration) may contain inner lines ending in `;` that
225
+ * must NOT terminate the statement. We track an open `$tag$` ... `$tag$`
226
+ * span and only honor a trailing `;` as a statement boundary when no dollar
227
+ * quote is open. (postgres.js sends each split statement via `.unsafe`.)
228
+ */
91
229
  export function splitStatements(ddl) {
92
230
  const out = [];
93
231
  let buf = "";
232
+ let openTag = null;
94
233
  for (const rawLine of ddl.split("\n")) {
95
234
  const line = rawLine.trim();
96
- if (!line || line.startsWith("--"))
235
+ // Skip comment-only / blank lines, but only when we're not inside a
236
+ // dollar-quoted body (a `--` inside `$$` is body text, not a comment).
237
+ if (openTag === null && (!line || line.startsWith("--")))
97
238
  continue;
98
239
  buf = buf ? `${buf}\n${rawLine}` : rawLine;
99
- if (line.endsWith(";")) {
240
+ // Toggle dollar-quote state across every `$tag$` token on this line.
241
+ for (const m of rawLine.matchAll(/\$[A-Za-z0-9_]*\$/g)) {
242
+ const tag = m[0];
243
+ if (openTag === null)
244
+ openTag = tag;
245
+ else if (openTag === tag)
246
+ openTag = null;
247
+ }
248
+ if (openTag === null && line.endsWith(";")) {
100
249
  const cleaned = buf.trim();
101
250
  if (cleaned)
102
251
  out.push(cleaned);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,oEAAoE;AACpE,gEAAgE;AAOhE;;;;;;;GAOG;AACH,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsDhC,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,UAAU,wBAAwB;IACtC,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAc;IACtD,MAAM,GAAG,GAAG,wBAAwB,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7C,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3B,IAAI,OAAO;gBAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/B,GAAG,GAAG,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,EAAE;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,0EAA0E;AAC1E,yEAAyE;AACzE,oEAAoE;AACpE,gEAAgE;AAOhE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;gIAoBqG,CAAC;AAEjI;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;kIAoBsG,CAAC;AAEnI;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkF/B,uBAAuB,EAAE;EACzB,wBAAwB,EAAE;CAC3B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,UAAU,wBAAwB;IACtC,OAAO,wBAAwB,CAAC;AAClC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAc;IACtD,MAAM,GAAG,GAAG,wBAAwB,EAAE,CAAC;IACvC,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,OAAO,GAAkB,IAAI,CAAC;IAClC,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,oEAAoE;QACpE,uEAAuE;QACvE,IAAI,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAAE,SAAS;QACnE,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAC3C,qEAAqE;QACrE,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACvD,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjB,IAAI,OAAO,KAAK,IAAI;gBAAE,OAAO,GAAG,GAAG,CAAC;iBAC/B,IAAI,OAAO,KAAK,GAAG;gBAAE,OAAO,GAAG,IAAI,CAAC;QAC3C,CAAC;QACD,IAAI,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3B,IAAI,OAAO;gBAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/B,GAAG,GAAG,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,EAAE;QAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/state-store/postgres.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,cAAc,EAEd,cAAc,EACf,MAAM,UAAU,CAAC;AAIlB,KAAK,SAAS,GAAG;IAGf,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACxD,GAAG,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC;AAIF,MAAM,WAAW,0BAA0B;IACzC,6EAA6E;IAC7E,GAAG,EAAE,SAAS,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,KAAK,IAAI,CAAC;CACZ;AAED,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAIjB;gBAEC,IAAI,EAAE,0BAA0B;IAMtC,UAAU,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA8C5C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAoBrD,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,CACb,IAAI,CACF,YAAY,EACV,QAAQ,GACR,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,iBAAiB,CACpB,CACF,GACA,OAAO,CAAC,IAAI,CAAC;IAoCV,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC;IA6BV,qBAAqB,CACzB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAQV,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7C,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAoC7D;;;;uDAImD;IAC7C,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC;IAwB1B,4CAA4C;IACtC,gBAAgB,CAAC,IAAI,EAAE;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYX,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAC9C;QACE,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,EAAE,CACJ;CAiBF"}
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/state-store/postgres.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,cAAc,EAEd,cAAc,EACf,MAAM,UAAU,CAAC;AAIlB,KAAK,SAAS,GAAG;IAGf,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACxD,GAAG,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B,CAAC;AAIF,MAAM,WAAW,0BAA0B;IACzC,6EAA6E;IAC7E,GAAG,EAAE,SAAS,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,KAAK,IAAI,CAAC;CACZ;AAED,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAIjB;gBAEC,IAAI,EAAE,0BAA0B;IAMtC,UAAU,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA8C5C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAoBrD,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,CACb,IAAI,CACF,YAAY,EACV,QAAQ,GACR,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,mBAAmB,GACnB,qBAAqB,GACrB,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,iBAAiB,CACpB,CACF,GACA,OAAO,CAAC,IAAI,CAAC;IAoCV,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,IAAI,CAAC;IA6BV,qBAAqB,CACzB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,IAAI,CAAC;IAQV,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7C,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAoC7D;;;;uDAImD;IAC7C,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC;IAwB1B,4CAA4C;IACtC,gBAAgB,CAAC,IAAI,EAAE;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYX,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAC9C;QACE,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB,EAAE,CACJ;CAiBF"}
@@ -7,13 +7,19 @@
7
7
  // `src/migrations/001-saga-state.sql`.
8
8
  //
9
9
  // Wire shape:
10
- // - tenant_id, parent_saga_id, parent_relationship: persisted as TEXT
11
- // to allow non-UUID test tenants. Production callers pass UUIDs.
10
+ // - tenant_id: persisted as UUID NOT NULL (D412 / 08-rls v7 A1 — the stale
11
+ // audit-only § 5.5 "no RLS, TEXT tenant" posture is SUPERSEDED). The
12
+ // migration (`src/migrations/`) emits the canonical 5-policy A1 RLS DDL
13
+ // for saga_state, INLINED as a string constant that is byte-equal to
14
+ // @nodii/db-rls's `withRls` (db-rls is a dev/test-only dep; the published
15
+ // package has no runtime db-rls dependency).
16
+ // - parent_saga_id, parent_relationship: persisted as TEXT.
12
17
  // - step_outputs + children + compensation_log: jsonb columns.
13
18
  // - next_resume_at: the reaper queries this; we keep it nullable.
14
19
  // - All reads/writes go through the configured `nodii_services` pool
15
- // (or any postgres.Sql) RLS is not applied to saga_state per
16
- // audit-only doctrine § 5.5.
20
+ // (or any postgres.Sql). The manual `tenant_id = $N` filter in `list()`
21
+ // is kept as defense-in-depth; RLS (gated on the app.tenant_id GUC the
22
+ // adopter binds per 08-rls § 7) is the new enforcement layer.
17
23
  //
18
24
  // 16KB cap on step_outputs entries (§ 5.5 three-level resolution): we
19
25
  // enforce on `appendStepOutput` — entries exceeding the cap are stored
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/state-store/postgres.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/state-store/postgres.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.6.1",
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,6 +44,7 @@
44
44
  }
45
45
  },
46
46
  "devDependencies": {
47
+ "@nodii/db-rls": "0.7.2",
47
48
  "@nodii/grpc-auth": "0.9.1",
48
49
  "@nodii/telemetry": "0.9.0",
49
50
  "@types/bun": "^1.3.13",
@@ -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 canonical source for the per-service migration; the
8
- -- `migrate-gen` helper (`src/migrate-gen.ts`) copies the contents into a
9
- -- service's migrations folder verbatim.
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 TEXT,
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,
@@ -62,6 +70,27 @@ ALTER TABLE saga_state ADD COLUMN IF NOT EXISTS reaper_grace_ms BIGINT;
62
70
  -- durable undo stack existed (saga admin-authz + undo-durability wave).
63
71
  ALTER TABLE saga_state ADD COLUMN IF NOT EXISTS undo_stack JSONB NOT NULL DEFAULT '[]'::jsonb;
64
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;
93
+
65
94
  -- Spec § 5.5 — four indexes.
66
95
  CREATE UNIQUE INDEX IF NOT EXISTS saga_state_trigger_trace_id_uniq
67
96
  ON saga_state (trigger_trace_id);
@@ -84,7 +113,11 @@ CREATE TABLE IF NOT EXISTS saga_outbox (
84
113
  step_name TEXT NOT NULL,
85
114
  event_type TEXT NOT NULL,
86
115
  payload JSONB NOT NULL,
87
- tenant_id TEXT,
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,
88
121
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
89
122
  delivered_at TIMESTAMPTZ
90
123
  );
@@ -92,3 +125,96 @@ CREATE TABLE IF NOT EXISTS saga_outbox (
92
125
  CREATE INDEX IF NOT EXISTS saga_outbox_saga_idx ON saga_outbox (saga_id, created_at);
93
126
  CREATE INDEX IF NOT EXISTS saga_outbox_undelivered_idx ON saga_outbox (delivered_at)
94
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());