@nodii/grpc-interceptors 0.3.8 → 0.4.1

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,3 +1,4 @@
1
+ import { type FramingSqlExecutor, type FramingWriter } from "./framing";
1
2
  import type { AuditConfig, CancellationConfig, DbConnection, DeadlineConfig, EnrichAuthConfig, ErrorMapEntry, InterceptorLogger, LoggingConfig, UnaryInterceptor } from "./types";
2
3
  export interface ConfigureGrpcInterceptorsOptions {
3
4
  /** Service short-name baked into the `<short>.audit_ctx` GUC. Required. */
@@ -18,6 +19,31 @@ export interface ConfigureGrpcInterceptorsOptions {
18
19
  errorCatalog?: Record<string, ErrorMapEntry>;
19
20
  logging?: LoggingConfig;
20
21
  audit?: AuditConfig;
22
+ /**
23
+ * Pattern-C framing-row target (request 2ecefe7c / D191 / 02-audit § 13).
24
+ *
25
+ * The audit interceptor writes coarse per-RPC framing rows to a SEPARATE,
26
+ * UNCHAINED `<svc>_audit_framing` table — distinct from the doctrinal
27
+ * in-tx RICH chain emit. This block makes the target CONFIGURABLE:
28
+ *
29
+ * - `sql` set → a `PostgresFramingWriter` is built automatically
30
+ * against `table` (DEFAULT `getAuditFramingTableName(serviceShortName)`,
31
+ * i.e. `<svc>_audit_framing`). `table` is the BACK-COMPAT override an
32
+ * existing consumer (e.g. billing) uses to point framing at its prior
33
+ * table.
34
+ * - `writer` set → that writer is used verbatim (full override).
35
+ * - neither → no framing writer; the interceptor falls back to the
36
+ * legacy `audit.emitter` / `@nodii/telemetry.audit.emit` path
37
+ * (back-compat).
38
+ */
39
+ framing?: {
40
+ /** Postgres executor (postgres.js / pg / drizzle wrapper) for the default writer. */
41
+ sql?: FramingSqlExecutor;
42
+ /** Override the framing table name. Default `<svc>_audit_framing`. */
43
+ table?: string;
44
+ /** Provide a fully-built writer instead of letting the helper construct one. */
45
+ writer?: FramingWriter;
46
+ };
21
47
  enrich?: EnrichAuthConfig;
22
48
  deadline?: DeadlineConfig;
23
49
  cancellation?: CancellationConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,aAAa,EAGb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,gCAAgC;IAC/C,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,iEAAiE;IACjE,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,gEAAgE;IAChE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,yBAAyB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CACxC;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,aAAa,IAAI,gBAAgB,CAAC;IAClC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,8BAA8B,CAAC;CACnD;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrD,QAAQ,CAAC,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChD;AAID;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,0BAA0B,CAuF5B;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,0BAA0B,GAAG,IAAI,CAEvE;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"AA8BA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAanB,OAAO,KAAK,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,aAAa,EAGb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,gCAAgC;IAC/C,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB;;;;OAIG;IACH,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,iEAAiE;IACjE,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,EAAE;QACR,qFAAqF;QACrF,GAAG,CAAC,EAAE,kBAAkB,CAAC;QACzB,sEAAsE;QACtE,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gFAAgF;QAChF,MAAM,CAAC,EAAE,aAAa,CAAC;KACxB,CAAC;IACF,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,gEAAgE;IAChE,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B;;;OAGG;IACH,yBAAyB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,oEAAoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;CACxC;AAED,MAAM,WAAW,0BAA0B;IACzC;;;;;;OAMG;IACH,aAAa,IAAI,gBAAgB,CAAC;IAClC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,8BAA8B,CAAC;CACnD;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACrD,QAAQ,CAAC,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,QAAQ,CAAC;CAChD;AAID;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,gCAAgC,GACxC,0BAA0B,CAgG5B;AAED,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,0BAA0B,GAAG,IAAI,CAEvE;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
package/dist/configure.js CHANGED
@@ -27,6 +27,7 @@
27
27
  // → error-map → handler).
28
28
  import { idempotencyGuard } from "@nodii/idempotency";
29
29
  import { sagaContext } from "@nodii/saga";
30
+ import { getAuditFramingTableName, PostgresFramingWriter, } from "./framing";
30
31
  import { signalBinder } from "./interceptors/signal-binder";
31
32
  import { cancellationGuard, deadlineGuard, enrichAuthContext, errorMap, STANDARD_ERROR_CATALOG, tenantContext, withAuditUnary, withLoggingUnary, } from "./interceptors-exports";
32
33
  import { auditContext } from "./interceptors/audit-context";
@@ -62,12 +63,19 @@ export function configureGrpcInterceptors(options) {
62
63
  requireSagaContextMethods: options.requireSagaContextMethods ?? new Set(),
63
64
  sagaContextEnforce: options.sagaContextEnforce ?? "warn",
64
65
  };
66
+ const framingWriter = resolveFramingWriter(options);
65
67
  const interceptors = [
66
68
  withLoggingUnary({
67
69
  ...(options.logging ?? {}),
68
70
  logger: options.logger ?? options.logging?.logger,
69
71
  }),
70
- withAuditUnary(options.audit ?? {}),
72
+ withAuditUnary({
73
+ ...(options.audit ?? {}),
74
+ serviceShortName: options.audit?.serviceShortName ?? options.serviceShortName,
75
+ // Explicit audit.framingWriter wins; else the resolved one from the
76
+ // `framing` block; else undefined (legacy emitter fallback).
77
+ framingWriter: options.audit?.framingWriter ?? framingWriter,
78
+ }),
71
79
  // withAuthUnary slot: services supply their own configured wrapper
72
80
  // via the re-exported `withAuthUnary` (it requires JWKS / token
73
81
  // manager wiring that varies per service). This factory composes
@@ -127,6 +135,24 @@ export function _resetConfigureForTests() {
127
135
  resolved = null;
128
136
  }
129
137
  // ── Internal slot helpers ────────────────────────────────────────────────────
138
+ /**
139
+ * Resolve the Pattern-C framing writer from the `framing` block (request
140
+ * 2ecefe7c / D191). Precedence: explicit `framing.writer` → built
141
+ * `PostgresFramingWriter` against `framing.table` (default
142
+ * `<svc>_audit_framing`) when `framing.sql` is supplied → undefined.
143
+ */
144
+ function resolveFramingWriter(options) {
145
+ const f = options.framing;
146
+ if (!f)
147
+ return undefined;
148
+ if (f.writer)
149
+ return f.writer;
150
+ if (f.sql) {
151
+ const tableName = f.table ?? getAuditFramingTableName(options.serviceShortName);
152
+ return new PostgresFramingWriter({ sql: f.sql, tableName });
153
+ }
154
+ return undefined;
155
+ }
130
156
  function passthroughSlot() {
131
157
  return (_method, handler) => async (call) => handler(call);
132
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../src/configure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import type { InterceptorLogger } from "./types";
2
+ /**
3
+ * Resolve the unchained framing-table name for a service.
4
+ *
5
+ * D191 / request 2ecefe7c: the DEFAULT target for new services is
6
+ * `<svc>_audit_framing`. `serviceName` is normalised the same way the rich
7
+ * `<svc>_audit_event` table is (lower-cased, `-`/spaces → `_`).
8
+ *
9
+ * @throws if the normalised name is not a safe Postgres identifier.
10
+ */
11
+ export declare function getAuditFramingTableName(serviceName: string): string;
12
+ /** Lower-case + `[-\s]` → `_`; matches telemetry's `<svc>_audit_event` derivation. */
13
+ export declare function normaliseServiceName(serviceName: string): string;
14
+ /**
15
+ * `CREATE TYPE` DDL for the shared `audit_actor_kind` enum (02-audit § 4).
16
+ * Re-emitted here so the framing migration is self-contained for services
17
+ * that adopt framing WITHOUT the rich `<svc>_audit_event` table. Idempotent.
18
+ * Identical to `@nodii/telemetry/drizzle`'s `AUDIT_ACTOR_KIND_ENUM_DDL`.
19
+ */
20
+ export declare const AUDIT_ACTOR_KIND_ENUM_DDL: string;
21
+ /** `CREATE TYPE` DDL for the shared `audit_outcome` enum (02-audit § 7). Idempotent. */
22
+ export declare const AUDIT_OUTCOME_ENUM_DDL: string;
23
+ /**
24
+ * Raw `CREATE TABLE` DDL for the UNCHAINED `<svc>_audit_framing` table.
25
+ *
26
+ * The column set is byte-for-byte the rich `<svc>_audit_event` shape (the
27
+ * exact columns `@nodii/telemetry/drizzle`'s `makeAuditEventTable` /
28
+ * `auditEventPartitionDDL` emit) MINUS the three chain columns:
29
+ * - `prev_hash` (BYTEA) — chain only
30
+ * - `row_hash` (BYTEA) — chain only
31
+ * - `tenant_audit_seq` (BIGINT) — chain only
32
+ *
33
+ * No `(tenant_id, tenant_audit_seq)` unique index either (that invariant is
34
+ * chain-only). Framing rows are observability-only and are NEVER hashed, so
35
+ * the per-tenant monotonic seq + linked hashes are intentionally absent.
36
+ *
37
+ * Unlike the rich table this is NOT partitioned and carries NO FK to
38
+ * `tenants(id)` — a framing row can be written for an RPC that was rejected
39
+ * before tenant resolution (e.g. UNAUTHENTICATED), so `tenant_id` is
40
+ * nullable here. (The rich table's `tenant_id` is `NOT NULL` because rich
41
+ * rows are emitted in-handler after tenant context is established.)
42
+ *
43
+ * @param serviceName service short-name; normalised to the table prefix.
44
+ * @param opts.includeEnumDdl prepend the two `CREATE TYPE` enum DDLs
45
+ * (idempotent) so the migration is self-contained. Default `true`.
46
+ */
47
+ export declare function makeAuditFramingTableDDL(serviceName: string, opts?: {
48
+ includeEnumDdl?: boolean;
49
+ }): string;
50
+ /**
51
+ * The supplementary B-tree indexes on the framing table. Mirrors the rich
52
+ * table's queryable read-paths MINUS the chain-only `(tenant_id,
53
+ * tenant_audit_seq)` index. Returned as one `CREATE INDEX` per element so
54
+ * the caller applies them individually.
55
+ */
56
+ export declare function auditFramingIndexDDL(serviceName: string): string[];
57
+ /** The resolved row a `FramingWriter` persists to the unchained framing table. */
58
+ export interface FramingRow {
59
+ tenant_id: string | null;
60
+ actor_kind: string;
61
+ actor_id: string | null;
62
+ action: string;
63
+ resource_type: string;
64
+ resource_id: string | null;
65
+ outcome: string;
66
+ grpc_code: string | null;
67
+ error_message: string | null;
68
+ correlation_id: string | null;
69
+ request_id: string | null;
70
+ trace_id: string | null;
71
+ span_id: string | null;
72
+ intent_id: string | null;
73
+ saga_id: string | null;
74
+ idempotency_key: string | null;
75
+ metadata: Record<string, unknown>;
76
+ }
77
+ /**
78
+ * Pattern-C framing writer. The interceptor hands a resolved `FramingRow`;
79
+ * the writer persists it to the UNCHAINED framing table on its own tx.
80
+ * Failures are best-effort per audit doctrine § 6.2 — the interceptor logs
81
+ * and proceeds (framing is observability, not the forensic record).
82
+ */
83
+ export interface FramingWriter {
84
+ write(row: FramingRow): Promise<void>;
85
+ }
86
+ /**
87
+ * Minimal Postgres handle the `PostgresFramingWriter` needs. `postgres.js`,
88
+ * `pg`, and `drizzle` all expose a parameterised exec; consumers adapt with
89
+ * a thin wrapper. Only `unsafe(sql, params)` (text + positional params) is
90
+ * used — Pattern C, no row-returning queries.
91
+ */
92
+ export interface FramingSqlExecutor {
93
+ unsafe(sql: string, params?: readonly unknown[]): Promise<unknown>;
94
+ }
95
+ /**
96
+ * Real Postgres `FramingWriter` (R1 — no Noop default in production paths).
97
+ * Writes one unchained row to the configured framing table per RPC entry.
98
+ * Each write is an independent INSERT (Pattern C — fresh connection from the
99
+ * caller's pool; NO caller tx, NO advisory lock, NO chain columns).
100
+ *
101
+ * `tableName` is the CONFIGURABLE target. New services pass
102
+ * `getAuditFramingTableName(svc)` (the default); a back-compat consumer that
103
+ * historically pointed framing at another table passes that name instead.
104
+ */
105
+ export declare class PostgresFramingWriter implements FramingWriter {
106
+ readonly tableName: string;
107
+ private readonly sql;
108
+ constructor(opts: {
109
+ sql: FramingSqlExecutor;
110
+ tableName: string;
111
+ });
112
+ write(row: FramingRow): Promise<void>;
113
+ }
114
+ /** A framing writer that records rows in memory — TEST DOUBLE ONLY (never a default). */
115
+ export declare class RecordingFramingWriter implements FramingWriter {
116
+ readonly rows: FramingRow[];
117
+ failOnce: boolean;
118
+ write(row: FramingRow): Promise<void>;
119
+ }
120
+ /** Helper used by the interceptor to log a best-effort framing write failure. */
121
+ export declare function logFramingWriteFailure(log: InterceptorLogger, method: string, err: unknown): void;
122
+ //# sourceMappingURL=framing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framing.d.ts","sourceRoot":"","sources":["../src/framing.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAKjD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CASpE;AAED,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,QAQ9B,CAAC;AAET,wFAAwF;AACxF,eAAO,MAAM,sBAAsB,QAO3B,CAAC;AAET;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,MAAM,CAoDR;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAQlE;AAED,kFAAkF;AAClF,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED;;;;;;;;;GASG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;gBAE7B,IAAI,EAAE;QAAE,GAAG,EAAE,kBAAkB,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAe1D,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CA+B5C;AAED,yFAAyF;AACzF,qBAAa,sBAAuB,YAAW,aAAa;IAC1D,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAM;IACjC,QAAQ,UAAS;IACX,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAO5C;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,OAAO,GACX,IAAI,CAKN"}
@@ -0,0 +1,232 @@
1
+ // Pattern-C audit FRAMING rows — request 2ecefe7c / D191 / 02-audit-doctrine § 13.
2
+ //
3
+ // `withAuditUnary` emits a coarse "framing" row on every RPC entry (Pattern
4
+ // C — no caller tx, fresh-connection emit). The doctrinal tamper-evident
5
+ // forensic record is the in-tx RICH chain emit (`audit.emit(tx, args)`,
6
+ // Pattern A/B) hashed by `@nodii/audit-chain`. Pattern C CANNOT acquire the
7
+ // per-tenant `pg_advisory_xact_lock` the chain append requires, so framing
8
+ // rows are NOT chained.
9
+ //
10
+ // Option B (recommended + locked by request 2ecefe7c): framing rows are
11
+ // OPERATIONAL TELEMETRY, not the forensic record. They land in a SEPARATE,
12
+ // UNCHAINED `<svc>_audit_framing` table whose columns mirror the rich
13
+ // `<svc>_audit_event` table MINUS the three chain columns (`prev_hash`,
14
+ // `row_hash`, `tenant_audit_seq`). The framing table is never hashed; it
15
+ // rides into ClickHouse / obs as needed.
16
+ //
17
+ // Cross-link: 02-audit-doctrine § 13 — chain = primary forensic record;
18
+ // framing = supplementary observability.
19
+ /** Postgres identifier guard — service short-names + table names are bare idents. */
20
+ const SAFE_IDENT = /^[a-z_][a-z0-9_]*$/;
21
+ /**
22
+ * Resolve the unchained framing-table name for a service.
23
+ *
24
+ * D191 / request 2ecefe7c: the DEFAULT target for new services is
25
+ * `<svc>_audit_framing`. `serviceName` is normalised the same way the rich
26
+ * `<svc>_audit_event` table is (lower-cased, `-`/spaces → `_`).
27
+ *
28
+ * @throws if the normalised name is not a safe Postgres identifier.
29
+ */
30
+ export function getAuditFramingTableName(serviceName) {
31
+ const norm = normaliseServiceName(serviceName);
32
+ const name = `${norm}_audit_framing`;
33
+ if (!SAFE_IDENT.test(name)) {
34
+ throw new Error(`@nodii/grpc-interceptors: unsafe framing table name derived from serviceName=${JSON.stringify(serviceName)} (got ${JSON.stringify(name)}).`);
35
+ }
36
+ return name;
37
+ }
38
+ /** Lower-case + `[-\s]` → `_`; matches telemetry's `<svc>_audit_event` derivation. */
39
+ export function normaliseServiceName(serviceName) {
40
+ return serviceName
41
+ .trim()
42
+ .toLowerCase()
43
+ .replace(/[-\s]+/g, "_");
44
+ }
45
+ /**
46
+ * `CREATE TYPE` DDL for the shared `audit_actor_kind` enum (02-audit § 4).
47
+ * Re-emitted here so the framing migration is self-contained for services
48
+ * that adopt framing WITHOUT the rich `<svc>_audit_event` table. Idempotent.
49
+ * Identical to `@nodii/telemetry/drizzle`'s `AUDIT_ACTOR_KIND_ENUM_DDL`.
50
+ */
51
+ export const AUDIT_ACTOR_KIND_ENUM_DDL = `
52
+ DO $$ BEGIN
53
+ CREATE TYPE audit_actor_kind AS ENUM (
54
+ 'employee_user','tenant_user','tenant_customer','service','worker',
55
+ 'webhook_provider','external_system','agent','system','unknown'
56
+ );
57
+ EXCEPTION WHEN duplicate_object THEN NULL;
58
+ END $$;
59
+ `.trim();
60
+ /** `CREATE TYPE` DDL for the shared `audit_outcome` enum (02-audit § 7). Idempotent. */
61
+ export const AUDIT_OUTCOME_ENUM_DDL = `
62
+ DO $$ BEGIN
63
+ CREATE TYPE audit_outcome AS ENUM (
64
+ 'success','failure','partial','queued','dry_run','denied_by_authz','denied_by_mfa'
65
+ );
66
+ EXCEPTION WHEN duplicate_object THEN NULL;
67
+ END $$;
68
+ `.trim();
69
+ /**
70
+ * Raw `CREATE TABLE` DDL for the UNCHAINED `<svc>_audit_framing` table.
71
+ *
72
+ * The column set is byte-for-byte the rich `<svc>_audit_event` shape (the
73
+ * exact columns `@nodii/telemetry/drizzle`'s `makeAuditEventTable` /
74
+ * `auditEventPartitionDDL` emit) MINUS the three chain columns:
75
+ * - `prev_hash` (BYTEA) — chain only
76
+ * - `row_hash` (BYTEA) — chain only
77
+ * - `tenant_audit_seq` (BIGINT) — chain only
78
+ *
79
+ * No `(tenant_id, tenant_audit_seq)` unique index either (that invariant is
80
+ * chain-only). Framing rows are observability-only and are NEVER hashed, so
81
+ * the per-tenant monotonic seq + linked hashes are intentionally absent.
82
+ *
83
+ * Unlike the rich table this is NOT partitioned and carries NO FK to
84
+ * `tenants(id)` — a framing row can be written for an RPC that was rejected
85
+ * before tenant resolution (e.g. UNAUTHENTICATED), so `tenant_id` is
86
+ * nullable here. (The rich table's `tenant_id` is `NOT NULL` because rich
87
+ * rows are emitted in-handler after tenant context is established.)
88
+ *
89
+ * @param serviceName service short-name; normalised to the table prefix.
90
+ * @param opts.includeEnumDdl prepend the two `CREATE TYPE` enum DDLs
91
+ * (idempotent) so the migration is self-contained. Default `true`.
92
+ */
93
+ export function makeAuditFramingTableDDL(serviceName, opts = {}) {
94
+ const table = getAuditFramingTableName(serviceName);
95
+ const includeEnumDdl = opts.includeEnumDdl ?? true;
96
+ const enumPrefix = includeEnumDdl
97
+ ? `${AUDIT_ACTOR_KIND_ENUM_DDL}\n${AUDIT_OUTCOME_ENUM_DDL}\n`
98
+ : "";
99
+ return `${enumPrefix}CREATE TABLE IF NOT EXISTS ${table} (
100
+ id UUID NOT NULL DEFAULT gen_random_uuid(),
101
+ tenant_id UUID,
102
+ at TIMESTAMPTZ NOT NULL DEFAULT now(),
103
+ actor_kind audit_actor_kind NOT NULL,
104
+ actor_id TEXT,
105
+ actor_external_id TEXT,
106
+ actor_display TEXT,
107
+ actor_ip INET,
108
+ actor_user_agent TEXT,
109
+ actor JSONB,
110
+ action TEXT NOT NULL,
111
+ resource_type TEXT NOT NULL,
112
+ resource_id TEXT,
113
+ resource_label TEXT,
114
+ secondary_resource_type TEXT,
115
+ secondary_resource_id TEXT,
116
+ outcome audit_outcome NOT NULL DEFAULT 'success',
117
+ http_status INTEGER,
118
+ grpc_code TEXT,
119
+ error_code TEXT,
120
+ error_message TEXT,
121
+ error_details JSONB,
122
+ before JSONB,
123
+ after JSONB,
124
+ patch JSONB,
125
+ changed_fields TEXT[],
126
+ reason_code TEXT,
127
+ reason_text TEXT,
128
+ request_id TEXT,
129
+ correlation_id TEXT,
130
+ trace_id TEXT,
131
+ span_id TEXT,
132
+ intent_id UUID,
133
+ saga_id TEXT,
134
+ step_id TEXT,
135
+ idempotency_key TEXT,
136
+ queue_name TEXT,
137
+ job_id TEXT,
138
+ parent_audit_event_id UUID,
139
+ read_count INTEGER,
140
+ first_read_at TIMESTAMPTZ,
141
+ last_read_at TIMESTAMPTZ,
142
+ metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
143
+ PRIMARY KEY (id)
144
+ );`;
145
+ }
146
+ /**
147
+ * The supplementary B-tree indexes on the framing table. Mirrors the rich
148
+ * table's queryable read-paths MINUS the chain-only `(tenant_id,
149
+ * tenant_audit_seq)` index. Returned as one `CREATE INDEX` per element so
150
+ * the caller applies them individually.
151
+ */
152
+ export function auditFramingIndexDDL(serviceName) {
153
+ const t = getAuditFramingTableName(serviceName);
154
+ const norm = normaliseServiceName(serviceName);
155
+ return [
156
+ `CREATE INDEX IF NOT EXISTS ${norm}_audit_framing_tenant_time ON ${t} (tenant_id, at);`,
157
+ `CREATE INDEX IF NOT EXISTS ${norm}_audit_framing_action_outcome ON ${t} (tenant_id, action, outcome, at);`,
158
+ `CREATE INDEX IF NOT EXISTS ${norm}_audit_framing_correlation ON ${t} (tenant_id, correlation_id);`,
159
+ ];
160
+ }
161
+ /**
162
+ * Real Postgres `FramingWriter` (R1 — no Noop default in production paths).
163
+ * Writes one unchained row to the configured framing table per RPC entry.
164
+ * Each write is an independent INSERT (Pattern C — fresh connection from the
165
+ * caller's pool; NO caller tx, NO advisory lock, NO chain columns).
166
+ *
167
+ * `tableName` is the CONFIGURABLE target. New services pass
168
+ * `getAuditFramingTableName(svc)` (the default); a back-compat consumer that
169
+ * historically pointed framing at another table passes that name instead.
170
+ */
171
+ export class PostgresFramingWriter {
172
+ tableName;
173
+ sql;
174
+ constructor(opts) {
175
+ if (!opts?.sql) {
176
+ throw new Error("@nodii/grpc-interceptors: PostgresFramingWriter requires a `sql` executor (R1 — no Noop default).");
177
+ }
178
+ if (!opts.tableName || !SAFE_IDENT.test(opts.tableName)) {
179
+ throw new Error(`@nodii/grpc-interceptors: PostgresFramingWriter requires a safe \`tableName\`; got ${JSON.stringify(opts.tableName)}.`);
180
+ }
181
+ this.sql = opts.sql;
182
+ this.tableName = opts.tableName;
183
+ }
184
+ async write(row) {
185
+ // Positional INSERT into the UNCHAINED table. Note: NO prev_hash /
186
+ // row_hash / tenant_audit_seq — framing rows are never in the chain.
187
+ await this.sql.unsafe(`INSERT INTO ${this.tableName}
188
+ (tenant_id, actor_kind, actor_id, action, resource_type, resource_id,
189
+ outcome, grpc_code, error_message, correlation_id, request_id,
190
+ trace_id, span_id, intent_id, saga_id, idempotency_key, metadata)
191
+ VALUES
192
+ ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17::jsonb)`, [
193
+ row.tenant_id,
194
+ row.actor_kind,
195
+ row.actor_id,
196
+ row.action,
197
+ row.resource_type,
198
+ row.resource_id,
199
+ row.outcome,
200
+ row.grpc_code,
201
+ row.error_message,
202
+ row.correlation_id,
203
+ row.request_id,
204
+ row.trace_id,
205
+ row.span_id,
206
+ row.intent_id,
207
+ row.saga_id,
208
+ row.idempotency_key,
209
+ JSON.stringify(row.metadata ?? {}),
210
+ ]);
211
+ }
212
+ }
213
+ /** A framing writer that records rows in memory — TEST DOUBLE ONLY (never a default). */
214
+ export class RecordingFramingWriter {
215
+ rows = [];
216
+ failOnce = false;
217
+ async write(row) {
218
+ if (this.failOnce) {
219
+ this.failOnce = false;
220
+ throw new Error("recording-framing-writer forced failure");
221
+ }
222
+ this.rows.push(row);
223
+ }
224
+ }
225
+ /** Helper used by the interceptor to log a best-effort framing write failure. */
226
+ export function logFramingWriteFailure(log, method, err) {
227
+ log.error("audit.framing_write_failed", {
228
+ method,
229
+ error: err instanceof Error ? err.message : String(err),
230
+ });
231
+ }
232
+ //# sourceMappingURL=framing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framing.js","sourceRoot":"","sources":["../src/framing.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -10,6 +10,8 @@ export { cancellationGuard } from "./interceptors/cancellation-guard";
10
10
  export { errorMap, STANDARD_ERROR_CATALOG, } from "./interceptors/error-map";
11
11
  export { createStandardServerStack } from "./factory";
12
12
  export { composeUnaryInterceptors } from "./compose";
13
+ export { getAuditFramingTableName, normaliseServiceName, makeAuditFramingTableDDL, auditFramingIndexDDL, AUDIT_ACTOR_KIND_ENUM_DDL, AUDIT_OUTCOME_ENUM_DDL, PostgresFramingWriter, RecordingFramingWriter, } from "./framing";
14
+ export type { FramingRow, FramingWriter, FramingSqlExecutor, } from "./framing";
13
15
  export { configureGrpcInterceptors, getConfiguredOrNull, _resetConfigureForTests, } from "./configure";
14
16
  export type { ConfigureGrpcInterceptorsOptions, ConfiguredGrpcInterceptors, ResolvedGrpcInterceptorsConfig, } from "./configure";
15
17
  export { _resetTelemetryShimForTests, _setTelemetryShimForTests, } from "./telemetry-shim";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,QAAQ,sBAAsB,CAAC;AAC5C,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,gCAAgC,EAChC,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAI1B,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGtE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,yBAAyB,EACzB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,QAAQ,sBAAsB,CAAC;AAC5C,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAGrD,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,UAAU,EACV,aAAa,EACb,kBAAkB,GACnB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,gCAAgC,EAChC,0BAA0B,EAC1B,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAI1B,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGtE,YAAY,EACV,WAAW,EACX,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,yBAAyB,EACzB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,gBAAgB,GACjB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -21,6 +21,8 @@ export { errorMap, STANDARD_ERROR_CATALOG, } from "./interceptors/error-map";
21
21
  // Composed-stack factory + composer.
22
22
  export { createStandardServerStack } from "./factory";
23
23
  export { composeUnaryInterceptors } from "./compose";
24
+ // Pattern-C UNCHAINED audit framing (request 2ecefe7c / D191 / § 13).
25
+ export { getAuditFramingTableName, normaliseServiceName, makeAuditFramingTableDDL, auditFramingIndexDDL, AUDIT_ACTOR_KIND_ENUM_DDL, AUDIT_OUTCOME_ENUM_DDL, PostgresFramingWriter, RecordingFramingWriter, } from "./framing";
24
26
  // Boot helper (spec § 5.2 + § 5.5).
25
27
  export { configureGrpcInterceptors, getConfiguredOrNull, _resetConfigureForTests, } from "./configure";
26
28
  // Test doubles + helpers.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,gFAAgF;AAChF,EAAE;AACF,mEAAmE;AACnE,oEAAoE;AACpE,qEAAqE;AACrE,oEAAoE;AACpE,6DAA6D;AAE7D,MAAM,CAAC,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAC5C,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,qCAAqC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,oCAAoC;AACpC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAOrB,0BAA0B;AAC1B,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,0EAA0E;AAC1E,mCAAmC;AACnC,cAAc,aAAa,CAAC;AAwB5B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,gFAAgF;AAChF,EAAE;AACF,mEAAmE;AACnE,oEAAoE;AACpE,qEAAqE;AACrE,oEAAoE;AACpE,6DAA6D;AAE7D,MAAM,CAAC,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAC5C,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,sBAAsB;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EACL,QAAQ,EACR,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAElC,qCAAqC;AACrC,OAAO,EAAE,yBAAyB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,sEAAsE;AACtE,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AAOnB,oCAAoC;AACpC,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAOrB,0BAA0B;AAC1B,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,0EAA0E;AAC1E,mCAAmC;AACnC,cAAc,aAAa,CAAC;AAwB5B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,WAAW,EAIX,gBAAgB,EACjB,MAAM,UAAU,CAAC;AA+BlB;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAE,WAAgB,GAAG,gBAAgB,CAoDzE"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EACV,WAAW,EAIX,gBAAgB,EACjB,MAAM,UAAU,CAAC;AA+BlB;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAE,WAAgB,GAAG,gBAAgB,CAmGzE"}
@@ -1,12 +1,30 @@
1
- // withAuditUnary — spec § 5.6.
1
+ // withAuditUnary — spec § 5.6 + request 2ecefe7c (D191 / 02-audit-doctrine § 13).
2
2
  //
3
3
  // Emits the *framing* row on every gRPC call (mutator + audited reads,
4
4
  // including rejections). The handler is still responsible for the
5
- // state-change row inside its own tx via `audit.emit(tx, ...)`. The
6
- // framing + state-change row join via `correlation_id`.
5
+ // state-change row inside its own tx via `audit.emit(tx, ...)` — that
6
+ // in-tx RICH emit (Pattern A/B) is the DOCTRINAL tamper-evident forensic
7
+ // record, hashed by `@nodii/audit-chain`. This interceptor NEVER touches
8
+ // that path.
7
9
  //
8
- // Routes through `@nodii/telemetry.audit.emit` (Pattern C) by default;
9
- // best-effort emitter failures log and proceed per audit doctrine § 6.2.
10
+ // Framing rows are Pattern C (no caller tx, fresh-connection emit) and so
11
+ // CANNOT acquire the per-tenant `pg_advisory_xact_lock` the chain append
12
+ // requires — they are therefore NOT chained. Per request 2ecefe7c
13
+ // (Option B), framing rows are OPERATIONAL TELEMETRY written to a SEPARATE,
14
+ // UNCHAINED `<svc>_audit_framing` table (§ 13: chain = primary forensic
15
+ // record; framing = supplementary observability). The framing + state-change
16
+ // row join via `correlation_id`.
17
+ //
18
+ // Target resolution (configurable):
19
+ // 1. `config.framingWriter` set → write the unchained framing row there
20
+ // (RECOMMENDED; new services point it at `<svc>_audit_framing`).
21
+ // 2. else `config.emitter` set → legacy Pattern-C emit (back-compat for
22
+ // consumers that historically pointed framing at their own table).
23
+ // 3. else → `@nodii/telemetry.audit.emit` fallback.
24
+ //
25
+ // All paths are best-effort — emitter/writer failures log and proceed per
26
+ // audit doctrine § 6.2.
27
+ import { logFramingWriteFailure } from "../framing";
10
28
  import { resolveTelemetry } from "../telemetry-shim";
11
29
  import { GrpcStatusError } from "../types";
12
30
  function mapOutcome(code, detail) {
@@ -45,7 +63,6 @@ export function withAuditUnary(config = {}) {
45
63
  if (skip.has(methodName))
46
64
  return handler(call);
47
65
  const t = resolveTelemetry();
48
- const emitter = config.emitter ?? t.audit;
49
66
  const log = t.logger;
50
67
  const isAuditOnRead = auditOnRead.has(methodName) || isLikelyMutator(methodName);
51
68
  let resultErr;
@@ -63,26 +80,74 @@ export function withAuditUnary(config = {}) {
63
80
  : "OK";
64
81
  const detail = resultErr ? classify(resultErr).detail : undefined;
65
82
  const outcome = mapOutcome(code, detail);
66
- try {
67
- await emitter.emit({
68
- action: `rpc.${methodName.replace(/^\/+/, "")}`,
69
- target_kind: "rpc",
70
- target_id: null,
71
- payload: {
72
- outcome,
73
- code,
74
- detail,
75
- correlation_id: call.auth?.requestContext?.correlation_id,
76
- actor_kind: deriveActorKind(call),
77
- tenant_id: call.auth?.requestContext?.tenant_id ?? null,
83
+ const action = `rpc.${methodName.replace(/^\/+/, "")}`;
84
+ const tenantId = call.auth?.requestContext?.tenant_id ?? null;
85
+ const correlationId = call.auth?.requestContext?.correlation_id ?? null;
86
+ const actorKind = deriveActorKind(call);
87
+ if (config.framingWriter) {
88
+ // Option B — write the UNCHAINED framing row to the separate
89
+ // `<svc>_audit_framing` table. NOT hashed, NOT in the chain.
90
+ const row = {
91
+ tenant_id: tenantId,
92
+ actor_kind: actorKind,
93
+ actor_id: deriveActorId(call),
94
+ action,
95
+ resource_type: "rpc",
96
+ resource_id: null,
97
+ outcome,
98
+ grpc_code: code,
99
+ error_message: detail ?? null,
100
+ correlation_id: correlationId,
101
+ request_id: call.auth?.requestContext?.intent_id ?? null,
102
+ trace_id: null,
103
+ span_id: null,
104
+ intent_id: call.auth?.requestContext?.intent_id ?? null,
105
+ saga_id: null,
106
+ idempotency_key: null,
107
+ metadata: {
108
+ framing: true,
109
+ ...(config.serviceShortName
110
+ ? { service: config.serviceShortName }
111
+ : {}),
78
112
  },
79
- });
113
+ };
114
+ // NOTE: deliberately NOT `return` here — a `return` inside a
115
+ // `finally` block would clobber the try-block's return value
116
+ // (the handler's response). Use if/else so the finally only
117
+ // performs side effects.
118
+ try {
119
+ await config.framingWriter.write(row);
120
+ }
121
+ catch (writeErr) {
122
+ logFramingWriteFailure(log, methodName, writeErr);
123
+ }
80
124
  }
81
- catch (emitErr) {
82
- log.error("audit.emit_failed", {
83
- method: methodName,
84
- error: emitErr instanceof Error ? emitErr.message : String(emitErr),
85
- });
125
+ else {
126
+ // Back-compat: legacy Pattern-C emit via the provided emitter or
127
+ // `@nodii/telemetry.audit.emit`. Consumers that historically
128
+ // pointed framing at their own table keep working unchanged.
129
+ const emitter = config.emitter ?? t.audit;
130
+ try {
131
+ await emitter.emit({
132
+ action,
133
+ target_kind: "rpc",
134
+ target_id: null,
135
+ payload: {
136
+ outcome,
137
+ code,
138
+ detail,
139
+ correlation_id: correlationId ?? undefined,
140
+ actor_kind: actorKind,
141
+ tenant_id: tenantId,
142
+ },
143
+ });
144
+ }
145
+ catch (emitErr) {
146
+ log.error("audit.emit_failed", {
147
+ method: methodName,
148
+ error: emitErr instanceof Error ? emitErr.message : String(emitErr),
149
+ });
150
+ }
86
151
  }
87
152
  }
88
153
  }
@@ -90,12 +155,22 @@ export function withAuditUnary(config = {}) {
90
155
  };
91
156
  }
92
157
  function deriveActorKind(call) {
158
+ // Map the coarse interceptor-level actor to the canonical 02-audit § 4
159
+ // `audit_actor_kind` enum so the framing row's `actor_kind` column (same
160
+ // enum type as the rich table) accepts the value.
93
161
  if (call.auth?.userActor?.user_id)
94
- return "user";
162
+ return "tenant_user";
95
163
  if (call.auth?.serviceActor?.service_id || call.auth?.serviceActor?.serviceId)
96
164
  return "service";
97
165
  return "unknown";
98
166
  }
167
+ function deriveActorId(call) {
168
+ if (call.auth?.userActor?.user_id)
169
+ return call.auth.userActor.user_id;
170
+ return (call.auth?.serviceActor?.service_id ??
171
+ call.auth?.serviceActor?.serviceId ??
172
+ null);
173
+ }
99
174
  /**
100
175
  * Heuristic: at v0.1.0 we emit a framing row for every method unless the
101
176
  * service explicitly opts out via `skipMethods` (e.g. health probes).
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/interceptors/audit.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -138,9 +138,33 @@ export interface LoggingConfig {
138
138
  /** Optional sample-rate hook for deterministic tests. Default `Math.random`. */
139
139
  random?: () => number;
140
140
  }
141
- /** Audit interceptor config — spec § 5.6. */
141
+ /** Audit interceptor config — spec § 5.6 + request 2ecefe7c (D191 / § 13). */
142
142
  export interface AuditConfig {
143
- /** Optional emitter override; defaults to `@nodii/telemetry.audit.emit`. */
143
+ /**
144
+ * UNCHAINED framing-row writer (request 2ecefe7c / Option B). When set,
145
+ * the interceptor writes Pattern-C framing rows to a SEPARATE
146
+ * `<svc>_audit_framing` table via this writer (NOT the chained forensic
147
+ * record). This is the RECOMMENDED target for new services — wire a
148
+ * `PostgresFramingWriter` against `getAuditFramingTableName(svc)`.
149
+ *
150
+ * Precedence: `framingWriter` (unchained table) takes precedence over the
151
+ * legacy `emitter` path. If neither is set the interceptor falls back to
152
+ * `@nodii/telemetry.audit.emit` (back-compat for existing consumers that
153
+ * historically pointed framing at their own table).
154
+ */
155
+ framingWriter?: import("./framing").FramingWriter;
156
+ /**
157
+ * Service short-name. Stamped into the framing row's `metadata.service`
158
+ * and used by `configureGrpcInterceptors` to derive the default
159
+ * `<svc>_audit_framing` table when building a `PostgresFramingWriter`.
160
+ */
161
+ serviceShortName?: string;
162
+ /**
163
+ * Legacy / back-compat emitter (Pattern C via `@nodii/telemetry.audit.emit`).
164
+ * Used only when `framingWriter` is NOT set. An existing consumer (e.g.
165
+ * billing) that pointed the interceptor at its chained audit table keeps
166
+ * working through this path. New services should prefer `framingWriter`.
167
+ */
144
168
  emitter?: AuditEmitter;
145
169
  /**
146
170
  * Method names (`/svc/Method`) that emit an audit-on-read framing row
@@ -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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodii/grpc-interceptors",
3
- "version": "0.3.8",
3
+ "version": "0.4.1",
4
4
  "description": "Substrate gRPC interceptor library for the Nodii microservice stack — 8 cross-cutting interceptors (logging, audit, enrichAuthContext, tenantContext, auditContext, deadlineGuard, cancellationGuard, errorMap) + re-export façade over @nodii/grpc-auth/saga/idempotency + locked-order createStandardServerStack factory. Spec: planning hub docKey=grpc-interceptors.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -25,11 +25,13 @@
25
25
  },
26
26
  "dependencies": {
27
27
  "@nodii/grpc-auth": "0.4.0",
28
- "@nodii/idempotency": "0.2.8",
29
- "@nodii/saga": "0.4.6",
30
- "@nodii/telemetry": "0.5.0"
28
+ "@nodii/idempotency": "0.2.9",
29
+ "@nodii/saga": "0.4.7",
30
+ "@nodii/telemetry": "0.5.1"
31
31
  },
32
32
  "devDependencies": {
33
+ "@nodii/audit-chain": "0.4.1",
34
+ "postgres": "^3.4.0",
33
35
  "typescript": "^5.9.3"
34
36
  },
35
37
  "repository": {