@nodii/telemetry 0.1.1 → 0.3.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.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Doctrine `02-audit-doctrine.md § 4` — the canonical `actor_kind` enum.
3
+ * 10 values, in this exact order; tests assert the order, so don't
4
+ * reorder without a drift entry. The SQL enum type is `audit_actor_kind`
5
+ * (one Postgres type shared across every service DB).
6
+ *
7
+ * `unknown` is the security marker per § 4.2 — emitted when no actor
8
+ * stamp can be derived; surfaces as a security alert via obs M17.
9
+ */
10
+ export declare const AUDIT_ACTOR_KINDS: readonly ["employee_user", "tenant_user", "tenant_customer", "service", "worker", "webhook_provider", "external_system", "agent", "system", "unknown"];
11
+ export type ActorKind = (typeof AUDIT_ACTOR_KINDS)[number];
12
+ /** Doctrine § 7 — 7-value `outcome` enum. Order matches the doctrine. */
13
+ export declare const AUDIT_OUTCOMES: readonly ["success", "failure", "partial", "queued", "dry_run", "denied_by_authz", "denied_by_mfa"];
14
+ export type AuditOutcome = (typeof AUDIT_OUTCOMES)[number];
15
+ //# sourceMappingURL=audit-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-types.d.ts","sourceRoot":"","sources":["../src/audit-types.ts"],"names":[],"mappings":"AAQA;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,wJAWpB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,yEAAyE;AACzE,eAAO,MAAM,cAAc,qGAQjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ // Type + enum constants for the audit signal. Kept separate from
2
+ // `audit.ts` so the top-level `@nodii/telemetry` barrel does not
3
+ // transitively pull `drizzle-orm` (which lives under `./drizzle/`).
4
+ //
5
+ // Consumers who don't run Drizzle still get `ActorKind`, `AuditOutcome`,
6
+ // and the value arrays via the main barrel — and the Drizzle schema
7
+ // fragment that uses these is reachable via `@nodii/telemetry/drizzle`.
8
+ /**
9
+ * Doctrine `02-audit-doctrine.md § 4` — the canonical `actor_kind` enum.
10
+ * 10 values, in this exact order; tests assert the order, so don't
11
+ * reorder without a drift entry. The SQL enum type is `audit_actor_kind`
12
+ * (one Postgres type shared across every service DB).
13
+ *
14
+ * `unknown` is the security marker per § 4.2 — emitted when no actor
15
+ * stamp can be derived; surfaces as a security alert via obs M17.
16
+ */
17
+ export const AUDIT_ACTOR_KINDS = [
18
+ "employee_user",
19
+ "tenant_user",
20
+ "tenant_customer",
21
+ "service",
22
+ "worker",
23
+ "webhook_provider",
24
+ "external_system",
25
+ "agent",
26
+ "system",
27
+ "unknown",
28
+ ];
29
+ /** Doctrine § 7 — 7-value `outcome` enum. Order matches the doctrine. */
30
+ export const AUDIT_OUTCOMES = [
31
+ "success",
32
+ "failure",
33
+ "partial",
34
+ "queued",
35
+ "dry_run",
36
+ "denied_by_authz",
37
+ "denied_by_mfa",
38
+ ];
39
+ //# sourceMappingURL=audit-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-types.js","sourceRoot":"","sources":["../src/audit-types.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,iEAAiE;AACjE,oEAAoE;AACpE,EAAE;AACF,yEAAyE;AACzE,oEAAoE;AACpE,wEAAwE;AAExE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,eAAe;IACf,aAAa;IACb,iBAAiB;IACjB,SAAS;IACT,QAAQ;IACR,kBAAkB;IAClB,iBAAiB;IACjB,OAAO;IACP,QAAQ;IACR,SAAS;CACD,CAAC;AAIX,yEAAyE;AACzE,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS;IACT,SAAS;IACT,SAAS;IACT,QAAQ;IACR,SAAS;IACT,iBAAiB;IACjB,eAAe;CACP,CAAC"}
package/dist/audit.d.ts CHANGED
@@ -1,47 +1,226 @@
1
+ import { AUDIT_ACTOR_KINDS, AUDIT_OUTCOMES, type ActorKind, type AuditOutcome } from "./audit-types";
2
+ export { AUDIT_ACTOR_KINDS, AUDIT_OUTCOMES };
3
+ export type { ActorKind, AuditOutcome };
4
+ /**
5
+ * Structured `actor` jsonb extension per doctrine § 4.1. Open-ended map;
6
+ * each `actor_kind` defines its own well-known fields (employee/user:
7
+ * `capacity`/`mfa`/`mfa_at`/`jti`; service: `instance_id`/`scopes`;
8
+ * worker: `queue_name`/`job_id`; webhook_provider: `transaction_id`/
9
+ * `signature_verified`; agent: `on_behalf_of`/`intent_id`/`tool`). NOT
10
+ * type-checked here — services that need stricter typing can layer their
11
+ * own discriminated union on top.
12
+ */
13
+ export type ActorStamp = Record<string, unknown>;
14
+ /**
15
+ * The rich audit-emit input shape per doctrine § 3 + § 6.0. Every field
16
+ * except `action` and `resourceType` is optional; the SDK resolves missing
17
+ * fields from `NodiiContext` + the active OTel span before handing the row
18
+ * to the writer.
19
+ *
20
+ * Field name convention: camelCase on the input; the SDK normalises to
21
+ * snake_case for the persisted row (`AuditEventRow`) matching the
22
+ * `<service>_audit_event` column names. This mirrors how Drizzle / pgx /
23
+ * SQLAlchemy schemas are typically declared in service code.
24
+ */
25
+ export interface AuditArgs {
26
+ tenantId?: string | null;
27
+ action: string;
28
+ resourceType: string;
29
+ resourceId?: string | null;
30
+ resourceLabel?: string | null;
31
+ secondaryResourceType?: string | null;
32
+ secondaryResourceId?: string | null;
33
+ actorKind?: ActorKind | null;
34
+ actorId?: string | null;
35
+ actorExternalId?: string | null;
36
+ actorDisplay?: string | null;
37
+ actorIp?: string | null;
38
+ actorUserAgent?: string | null;
39
+ actor?: ActorStamp | null;
40
+ outcome?: AuditOutcome;
41
+ httpStatus?: number | null;
42
+ grpcCode?: string | null;
43
+ errorCode?: string | null;
44
+ errorMessage?: string | null;
45
+ errorDetails?: Record<string, unknown> | null;
46
+ before?: Record<string, unknown> | null;
47
+ after?: Record<string, unknown> | null;
48
+ patch?: Record<string, unknown> | null;
49
+ changedFields?: string[] | null;
50
+ reasonCode?: string | null;
51
+ reasonText?: string | null;
52
+ requestId?: string | null;
53
+ correlationId?: string | null;
54
+ traceId?: string | null;
55
+ spanId?: string | null;
56
+ intentId?: string | null;
57
+ sagaId?: string | null;
58
+ stepId?: string | null;
59
+ idempotencyKey?: string | null;
60
+ queueName?: string | null;
61
+ jobId?: string | null;
62
+ parentAuditEventId?: string | null;
63
+ readCount?: number | null;
64
+ firstReadAt?: Date | null;
65
+ lastReadAt?: Date | null;
66
+ metadata?: Record<string, unknown>;
67
+ }
68
+ /**
69
+ * The fully-resolved row handed to the writer (and, if wired, to the chain
70
+ * adapter). Snake_case names match the `<service>_audit_event` columns 1:1
71
+ * per doctrine § 3 — the writer can copy fields into the SQL INSERT without
72
+ * a translation layer.
73
+ */
74
+ export interface AuditEventRow {
75
+ id: string;
76
+ tenant_id: string;
77
+ at: Date;
78
+ actor_kind: ActorKind;
79
+ actor_id: string | null;
80
+ actor_external_id: string | null;
81
+ actor_display: string | null;
82
+ actor_ip: string | null;
83
+ actor_user_agent: string | null;
84
+ actor: ActorStamp | null;
85
+ action: string;
86
+ resource_type: string;
87
+ resource_id: string | null;
88
+ resource_label: string | null;
89
+ secondary_resource_type: string | null;
90
+ secondary_resource_id: string | null;
91
+ outcome: AuditOutcome;
92
+ http_status: number | null;
93
+ grpc_code: string | null;
94
+ error_code: string | null;
95
+ error_message: string | null;
96
+ error_details: Record<string, unknown> | null;
97
+ before: Record<string, unknown> | null;
98
+ after: Record<string, unknown> | null;
99
+ patch: Record<string, unknown> | null;
100
+ changed_fields: string[] | null;
101
+ reason_code: string | null;
102
+ reason_text: string | null;
103
+ request_id: string | null;
104
+ correlation_id: string | null;
105
+ trace_id: string | null;
106
+ span_id: string | null;
107
+ intent_id: string | null;
108
+ saga_id: string | null;
109
+ step_id: string | null;
110
+ idempotency_key: string | null;
111
+ queue_name: string | null;
112
+ job_id: string | null;
113
+ parent_audit_event_id: string | null;
114
+ read_count: number | null;
115
+ first_read_at: Date | null;
116
+ last_read_at: Date | null;
117
+ prev_hash: Uint8Array | null;
118
+ row_hash: Uint8Array | null;
119
+ tenant_audit_seq: bigint | null;
120
+ metadata: Record<string, unknown>;
121
+ }
122
+ /**
123
+ * Legacy minimal shape from v0.1.0–v0.2.0. Still accepted by `audit.emit`
124
+ * so call sites in `@nodii/pii`, `@nodii/saga`, `@nodii/grpc-interceptors`
125
+ * continue to work unchanged. New callers should use `AuditArgs`.
126
+ *
127
+ * @deprecated Use `AuditArgs`. Mapping: `target_kind` → `resource_type`,
128
+ * `target_id` → `resource_id`, `payload` → `metadata`.
129
+ */
1
130
  export interface AuditEvent {
2
131
  /** D33-locked vocabulary, e.g. `payment.refund.issued`. */
3
132
  action: string;
4
- /** D33: target_kind, e.g. `payment`, `service`, `feature_doc`. */
133
+ /** Maps to `resource_type` per doctrine § 3. */
5
134
  target_kind: string;
6
- /** Stable id of the row being acted on. May be null for create-then-id. */
135
+ /** Maps to `resource_id` per doctrine § 3. */
7
136
  target_id: string | null;
8
- /** Free-form payload; redaction happens in `audit.emit`. */
137
+ /** Maps to `metadata` per doctrine § 3. */
9
138
  payload?: Record<string, unknown>;
10
139
  }
11
140
  /**
12
- * The pluggable Postgres-write path. Services wire this on init by
13
- * passing `auditWriter` to `initTelemetry({ ... })` (deferred) OR by
14
- * calling `_setAuditWriter` from a `@nodii/db-rls` adapter. v0.1.0 ships
15
- * a default no-op writer; consumers replace it.
141
+ * The pluggable Postgres-write path per doctrine § 15.1 + § 15.4.
142
+ *
143
+ * Services wire this at boot by calling `_setAuditWriter(...)` from a
144
+ * `@nodii/db-rls` adapter (or any service-supplied writer that implements
145
+ * this signature). The writer receives the canonical `AuditEventRow`
146
+ * matching `<service>_audit_event` columns 1:1.
147
+ *
148
+ * `tx` argument carries the in-flight transaction handle when `audit.emit`
149
+ * is called via Pattern A or B (in-tx); `undefined` for Pattern C
150
+ * (out-of-band — writer is responsible for opening its own short-lived tx
151
+ * scoped to `row.tenant_id`).
152
+ *
153
+ * v0.1.2 (drift `4cc80f62`) — the Noop default is GONE. If a service calls
154
+ * `audit.emit(...)` before wiring a real writer, the SDK throws
155
+ * `TelemetryAuditWriterMissing`. This closes the R1 violation in which
156
+ * audit rows were silently dropped because the lib defaulted to a no-op
157
+ * writer in production paths.
16
158
  */
17
- export type AuditWriter = (row: {
18
- actor: string;
19
- action: string;
20
- target_kind: string;
21
- target_id: string | null;
22
- payload: Record<string, unknown> | null;
23
- tenant_id: string | null;
24
- request_id: string | null;
25
- intent_id: string | null;
26
- ts: string;
27
- }) => Promise<void> | void;
159
+ export type AuditWriter = (row: AuditEventRow, tx?: unknown) => Promise<void> | void;
160
+ /**
161
+ * Opt-in tamper-evident chain layer per doctrine § 13 + § 15.3. Wired via
162
+ * `configureTelemetry({audit: {chain}})` — typically from
163
+ * `@nodii/audit-chain`'s boot adapter.
164
+ *
165
+ * `augment` receives the canonical row (with `prev_hash` / `row_hash` /
166
+ * `tenant_audit_seq` all `null`) plus the in-flight tx (or `undefined`)
167
+ * and returns the computed chain triple. The implementation MUST acquire
168
+ * `pg_advisory_xact_lock(hash(tenant_id || 'audit'))` inside the tx so
169
+ * sequence allocation is per-tenant monotonic.
170
+ *
171
+ * Services that don't run the chain leave the three columns NULL; the
172
+ * library writes them as `null` to Postgres.
173
+ */
174
+ export interface AuditChainAdapter {
175
+ augment(row: AuditEventRow, tx?: unknown): Promise<{
176
+ prev_hash: Uint8Array | null;
177
+ row_hash: Uint8Array;
178
+ tenant_audit_seq: bigint;
179
+ }>;
180
+ }
28
181
  /**
29
- * SDK-internal: services or the `@nodii/db-rls` adapter sets the
30
- * writer. Public callers MUST NOT call this; the override exists for
31
- * the adapter layer.
182
+ * Thrown by `audit.emit` when no `AuditWriter` has been wired. v0.1.2
183
+ * replaces the v0.1.0–v0.1.1 silent-Noop failure mode (R1 violation,
184
+ * drift `4cc80f62`). Services MUST wire a writer via `_setAuditWriter(...)`
185
+ * before the first `audit.emit` fires.
186
+ */
187
+ export declare class TelemetryAuditWriterMissing extends Error {
188
+ constructor();
189
+ }
190
+ /**
191
+ * SDK-internal: services or the `@nodii/db-rls` adapter sets the writer.
192
+ * Public callers MUST NOT call this; the override exists for the adapter
193
+ * layer.
32
194
  */
33
195
  export declare function _setAuditWriter(w: AuditWriter): void;
34
- /** Test-only restore. */
196
+ /** Test-only reset. Clears the wired writer; the next `audit.emit` will throw. */
35
197
  export declare function _resetAuditWriterForTests(): void;
36
198
  /**
37
- * The `audit.emit` API. Awaits the writer so the caller can await one
38
- * write before responding; failures propagate to the caller (audit is
39
- * NOT best-effort the way logs are — D33 requires durable emission for
40
- * mutations).
199
+ * SDK-internal: `configureTelemetry({audit: {chain}})` calls this to wire
200
+ * the opt-in chain adapter. Setting `null` removes it.
201
+ */
202
+ export declare function _setAuditChain(adapter: AuditChainAdapter | null): void;
203
+ /** Test-only reset. Removes the wired chain adapter. */
204
+ export declare function _resetAuditChainForTests(): void;
205
+ /** SDK-internal accessor for tests + chain-layer integration probes. */
206
+ export declare function _getAuditChain(): AuditChainAdapter | null;
207
+ /**
208
+ * Pattern A / B (in-tx) — atomic with the mutation. Writer receives the
209
+ * caller's transaction handle and writes the audit row inside it.
210
+ */
211
+ declare function emit(tx: unknown, args: AuditArgs): Promise<void>;
212
+ /** Pattern C (out-of-band) — writer opens its own tenant-scoped tx. */
213
+ declare function emit(args: AuditArgs): Promise<void>;
214
+ /**
215
+ * Backward-compatible overload for the legacy minimal shape. Maps onto
216
+ * `AuditArgs` per doctrine § 3 before entering the shared write path.
217
+ *
218
+ * @deprecated Use the rich `AuditArgs` form. This overload exists so the
219
+ * v0.2.x call sites in `@nodii/pii`, `@nodii/saga`, `@nodii/grpc-
220
+ * interceptors` keep working unchanged while their authors migrate.
41
221
  */
42
222
  declare function emit(event: AuditEvent): Promise<void>;
43
223
  export declare const audit: {
44
224
  readonly emit: typeof emit;
45
225
  };
46
- export {};
47
226
  //# sourceMappingURL=audit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;CACZ,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAQ3B;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,CAEpD;AAED,yBAAyB;AACzB,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED;;;;;GAKG;AACH,iBAAe,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAepD;AAwBD,eAAO,MAAM,KAAK;;CAER,CAAC"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
package/dist/audit.js CHANGED
@@ -1,77 +1,254 @@
1
- // Audit signal class per D17 + D33 + D149. Separate from logs.
1
+ // Audit signal class the canonical adapter per `02-audit-doctrine.md`
2
+ // § 3 (row shape) + § 6.0 (Patterns A/B/C tx-bound) + § 13 (opt-in chain).
2
3
  //
3
4
  // "If a tenant could legitimately need to see this row, it's audit, not
4
- // log." — D17 cultural rule.
5
+ // log." — D17 cultural rule, doctrine § 1.
5
6
  //
6
7
  // The library ships the adapter (the write path); the audit emission
7
8
  // policy (D33 three paths: method-level interceptor, saga lifecycle,
8
- // agent-layer double-emission) and the audit_log SCHEMA live in the
9
- // audit doctrine, not here. `@nodii/telemetry`'s job is to provide
10
- // `audit.emit(...)` that lands the row in:
11
- // - per-service Postgres audit_log table (via the configured writer)
12
- // - ClickHouse mirror (via OTLP audit signal; deferred to TS-12)
9
+ // agent-layer double-emission) and the `<service>_audit_event` schema
10
+ // live in `02-audit-doctrine.md`, not here. The Drizzle schema fragment
11
+ // for the table ships from `@nodii/telemetry/drizzle`.
12
+ //
13
+ // Three emission patterns per § 6.0:
14
+ // - Pattern A — explicit tx pass: `audit.emit(tx, args)`
15
+ // - Pattern B — Hono `c.set("txn", tx)` middleware: also `audit.emit(tx, args)`
16
+ // - Pattern C — out-of-band: `audit.emit(args)` (writer owns its tx)
17
+ import { AUDIT_ACTOR_KINDS, AUDIT_OUTCOMES, } from "./audit-types";
13
18
  import { getContext } from "./context";
14
19
  import { requireTelemetry } from "./init";
15
- const noopWriter = () => {
16
- /* no-op default; services wire a real writer */
17
- };
18
- let writer = noopWriter;
20
+ import { uuidv7 } from "./uuid";
21
+ export { AUDIT_ACTOR_KINDS, AUDIT_OUTCOMES };
22
+ /**
23
+ * Thrown by `audit.emit` when no `AuditWriter` has been wired. v0.1.2
24
+ * replaces the v0.1.0–v0.1.1 silent-Noop failure mode (R1 violation,
25
+ * drift `4cc80f62`). Services MUST wire a writer via `_setAuditWriter(...)`
26
+ * before the first `audit.emit` fires.
27
+ */
28
+ export class TelemetryAuditWriterMissing extends Error {
29
+ constructor() {
30
+ super("@nodii/telemetry: audit.emit called before an AuditWriter was wired. " +
31
+ "Drift 4cc80f62 (R1, breaking) removed the v0.1.0–v0.1.1 Noop default " +
32
+ "because it silently dropped audit rows. Wire a real writer via " +
33
+ "`_setAuditWriter(...)` (typically from `@nodii/db-rls`'s adapter " +
34
+ "writing to <serviceName>_audit_event per 02-audit-doctrine.md § 6.0).");
35
+ this.name = "TelemetryAuditWriterMissing";
36
+ }
37
+ }
38
+ let writer = null;
39
+ let chain = null;
19
40
  /**
20
- * SDK-internal: services or the `@nodii/db-rls` adapter sets the
21
- * writer. Public callers MUST NOT call this; the override exists for
22
- * the adapter layer.
41
+ * SDK-internal: services or the `@nodii/db-rls` adapter sets the writer.
42
+ * Public callers MUST NOT call this; the override exists for the adapter
43
+ * layer.
23
44
  */
24
45
  export function _setAuditWriter(w) {
25
46
  writer = w;
26
47
  }
27
- /** Test-only restore. */
48
+ /** Test-only reset. Clears the wired writer; the next `audit.emit` will throw. */
28
49
  export function _resetAuditWriterForTests() {
29
- writer = noopWriter;
50
+ writer = null;
30
51
  }
31
52
  /**
32
- * The `audit.emit` API. Awaits the writer so the caller can await one
33
- * write before responding; failures propagate to the caller (audit is
34
- * NOT best-effort the way logs are — D33 requires durable emission for
35
- * mutations).
53
+ * SDK-internal: `configureTelemetry({audit: {chain}})` calls this to wire
54
+ * the opt-in chain adapter. Setting `null` removes it.
36
55
  */
37
- async function emit(event) {
38
- requireTelemetry(); // throws if SDK not init'd
39
- const ctx = getContext();
40
- const actor = formatActor(ctx);
41
- await writer({
42
- actor,
56
+ export function _setAuditChain(adapter) {
57
+ chain = adapter;
58
+ }
59
+ /** Test-only reset. Removes the wired chain adapter. */
60
+ export function _resetAuditChainForTests() {
61
+ chain = null;
62
+ }
63
+ /** SDK-internal accessor for tests + chain-layer integration probes. */
64
+ export function _getAuditChain() {
65
+ return chain;
66
+ }
67
+ /**
68
+ * Type guard distinguishing the legacy `AuditEvent` from the rich `AuditArgs`.
69
+ * The discriminator is `target_kind`: present on the legacy shape, absent on
70
+ * the rich shape (which uses `resourceType`). Both shapes carry `action`.
71
+ */
72
+ function isLegacyEvent(arg) {
73
+ return ("target_kind" in arg &&
74
+ typeof arg.target_kind === "string" &&
75
+ !("resourceType" in arg));
76
+ }
77
+ /**
78
+ * Map the legacy shape onto the rich `AuditArgs` so the rest of the
79
+ * pipeline only handles one input form. Mapping per doctrine § 3:
80
+ * target_kind → resource_type
81
+ * target_id → resource_id
82
+ * payload → metadata
83
+ * Other rich fields are left undefined for `resolveRow` to fill from ctx.
84
+ */
85
+ function legacyToRich(event) {
86
+ return {
43
87
  action: event.action,
44
- target_kind: event.target_kind,
45
- target_id: event.target_id,
46
- payload: event.payload ?? null,
47
- tenant_id: ctx?.tenant_id ?? null,
48
- request_id: ctx?.request_id ?? null,
49
- intent_id: ctx?.intent_id ?? null,
50
- ts: new Date().toISOString(),
51
- });
88
+ resourceType: event.target_kind,
89
+ resourceId: event.target_id,
90
+ metadata: event.payload ?? {},
91
+ };
52
92
  }
53
- function formatActor(ctx) {
93
+ /**
94
+ * Derive the canonical `actor_kind` from a `NodiiContext`. Falls back to
95
+ * `'unknown'` per doctrine § 4.2 — the SDK MUST emit `unknown` when no
96
+ * actor stamp can be derived; this is a security-event marker, not a
97
+ * silent default.
98
+ *
99
+ * Mapping rules per § 4 + auth-sdk § 5.6:
100
+ * ctx.actor_type='user' → 'tenant_user' (callers override to 'employee_user' when platform-admin)
101
+ * ctx.actor_type='agent' → 'agent'
102
+ * ctx.actor_type='service' → 'service'
103
+ * ctx.actor_type='system' → 'system'
104
+ * ctx absent → 'unknown' (security marker)
105
+ */
106
+ function deriveActorKind(ctx) {
54
107
  if (!ctx)
55
- return "system";
108
+ return "unknown";
56
109
  switch (ctx.actor_type) {
57
110
  case "user":
58
- return ctx.user_id ? `user:${ctx.user_id}` : "user:unknown";
111
+ return "tenant_user";
59
112
  case "agent":
60
- return ctx.on_behalf_of
61
- ? `agent:on_behalf_of:${ctx.on_behalf_of}`
62
- : "agent:unknown";
113
+ return "agent";
63
114
  case "service":
64
115
  return "service";
65
116
  case "system":
66
117
  return "system";
67
118
  default: {
68
- // Exhaustiveness check.
119
+ // Exhaustiveness check + future-proofing if ActorType grows.
69
120
  const _exhaustive = ctx.actor_type;
70
121
  void _exhaustive;
71
122
  return "unknown";
72
123
  }
73
124
  }
74
125
  }
126
+ /**
127
+ * Derive the canonical `actor_id` from `NodiiContext`. For `actor_type='user'`
128
+ * use `user_id`; for `actor_type='agent'` use `on_behalf_of` (the human who
129
+ * authorised the dispatch — per doctrine § 4.1 agent extension); for service
130
+ * + system contexts no `actor_id` is derivable and the caller must supply
131
+ * one if needed.
132
+ */
133
+ function deriveActorId(ctx) {
134
+ if (!ctx)
135
+ return null;
136
+ switch (ctx.actor_type) {
137
+ case "user":
138
+ return ctx.user_id;
139
+ case "agent":
140
+ return ctx.on_behalf_of;
141
+ case "service":
142
+ case "system":
143
+ return null;
144
+ default:
145
+ return null;
146
+ }
147
+ }
148
+ /**
149
+ * Build the canonical `AuditEventRow` from `AuditArgs` + the active
150
+ * `NodiiContext`. Resolution rules (in order):
151
+ * 1. `tenant_id`: args.tenantId → ctx.tenant_id → throw
152
+ * 2. `actor_kind`: args.actorKind → derive from ctx → 'unknown'
153
+ * 3. `actor_id`: args.actorId → derive from ctx → null
154
+ * 4. `request_id`, `intent_id`: args → ctx → null
155
+ * 5. Other fields: pass through args (null when undefined)
156
+ *
157
+ * Throws `Error` when neither args nor ctx carry a `tenant_id` — the
158
+ * audit row cannot be RLS-bound without one, so silently dropping it
159
+ * would be a doctrine § 3 + R1 violation.
160
+ */
161
+ function resolveRow(args) {
162
+ const ctx = getContext();
163
+ const tenantId = args.tenantId ?? ctx?.tenant_id ?? null;
164
+ if (!tenantId) {
165
+ throw new Error("audit.emit: tenant_id is required — pass `tenantId` in args or " +
166
+ "invoke inside a `withContext({tenant_id: ...})` scope. The audit " +
167
+ "row cannot be RLS-bound without it (02-audit-doctrine.md § 3).");
168
+ }
169
+ const actorKind = args.actorKind ?? deriveActorKind(ctx);
170
+ const actorId = args.actorId ?? deriveActorId(ctx);
171
+ return {
172
+ id: uuidv7(),
173
+ tenant_id: tenantId,
174
+ at: new Date(),
175
+ actor_kind: actorKind,
176
+ actor_id: actorId,
177
+ actor_external_id: args.actorExternalId ?? null,
178
+ actor_display: args.actorDisplay ?? null,
179
+ actor_ip: args.actorIp ?? null,
180
+ actor_user_agent: args.actorUserAgent ?? null,
181
+ actor: args.actor ?? null,
182
+ action: args.action,
183
+ resource_type: args.resourceType,
184
+ resource_id: args.resourceId ?? null,
185
+ resource_label: args.resourceLabel ?? null,
186
+ secondary_resource_type: args.secondaryResourceType ?? null,
187
+ secondary_resource_id: args.secondaryResourceId ?? null,
188
+ outcome: args.outcome ?? "success",
189
+ http_status: args.httpStatus ?? null,
190
+ grpc_code: args.grpcCode ?? null,
191
+ error_code: args.errorCode ?? null,
192
+ error_message: args.errorMessage ?? null,
193
+ error_details: args.errorDetails ?? null,
194
+ before: args.before ?? null,
195
+ after: args.after ?? null,
196
+ patch: args.patch ?? null,
197
+ changed_fields: args.changedFields ?? null,
198
+ reason_code: args.reasonCode ?? null,
199
+ reason_text: args.reasonText ?? null,
200
+ request_id: args.requestId ?? ctx?.request_id ?? null,
201
+ correlation_id: args.correlationId ?? null,
202
+ trace_id: args.traceId ?? null,
203
+ span_id: args.spanId ?? null,
204
+ intent_id: args.intentId ?? ctx?.intent_id ?? null,
205
+ saga_id: args.sagaId ?? null,
206
+ step_id: args.stepId ?? null,
207
+ idempotency_key: args.idempotencyKey ?? null,
208
+ queue_name: args.queueName ?? null,
209
+ job_id: args.jobId ?? null,
210
+ parent_audit_event_id: args.parentAuditEventId ?? null,
211
+ read_count: args.readCount ?? null,
212
+ first_read_at: args.firstReadAt ?? null,
213
+ last_read_at: args.lastReadAt ?? null,
214
+ // Chain columns left null unless an adapter is wired (see emitImpl).
215
+ prev_hash: null,
216
+ row_hash: null,
217
+ tenant_audit_seq: null,
218
+ metadata: args.metadata ?? {},
219
+ };
220
+ }
221
+ /**
222
+ * Shared write path. Resolves the row, optionally runs the chain adapter,
223
+ * and hands the row + tx to the writer. Throws `TelemetryAuditWriterMissing`
224
+ * when no writer is wired (drift `4cc80f62` enforcement).
225
+ */
226
+ async function emitImpl(args, tx) {
227
+ requireTelemetry();
228
+ if (writer === null) {
229
+ throw new TelemetryAuditWriterMissing();
230
+ }
231
+ const row = resolveRow(args);
232
+ if (chain !== null) {
233
+ const augmented = await chain.augment(row, tx);
234
+ row.prev_hash = augmented.prev_hash;
235
+ row.row_hash = augmented.row_hash;
236
+ row.tenant_audit_seq = augmented.tenant_audit_seq;
237
+ }
238
+ await writer(row, tx);
239
+ }
240
+ async function emit(a, b) {
241
+ if (b !== undefined) {
242
+ // emit(tx, args) — Pattern A / B.
243
+ return emitImpl(b, a);
244
+ }
245
+ const arg = a;
246
+ if (isLegacyEvent(arg)) {
247
+ return emitImpl(legacyToRich(arg));
248
+ }
249
+ // emit(args) — Pattern C.
250
+ return emitImpl(arg);
251
+ }
75
252
  export const audit = {
76
253
  emit,
77
254
  };
package/dist/audit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,EAAE;AACF,wEAAwE;AACxE,6BAA6B;AAC7B,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,oEAAoE;AACpE,mEAAmE;AACnE,2CAA2C;AAC3C,uEAAuE;AACvE,mEAAmE;AAEnE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AA+B1C,MAAM,UAAU,GAAgB,GAAG,EAAE;IACnC,gDAAgD;AAClD,CAAC,CAAC;AAEF,IAAI,MAAM,GAAgB,UAAU,CAAC;AAErC;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,CAAc;IAC5C,MAAM,GAAG,CAAC,CAAC;AACb,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,yBAAyB;IACvC,MAAM,GAAG,UAAU,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,IAAI,CAAC,KAAiB;IACnC,gBAAgB,EAAE,CAAC,CAAC,2BAA2B;IAC/C,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,MAAM,CAAC;QACX,KAAK;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,IAAI;QACjC,UAAU,EAAE,GAAG,EAAE,UAAU,IAAI,IAAI;QACnC,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,IAAI;QACjC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAC7B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,GAAkC;IACrD,IAAI,CAAC,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC1B,QAAQ,GAAG,CAAC,UAAU,EAAE,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;QAC9D,KAAK,OAAO;YACV,OAAO,GAAG,CAAC,YAAY;gBACrB,CAAC,CAAC,sBAAsB,GAAG,CAAC,YAAY,EAAE;gBAC1C,CAAC,CAAC,eAAe,CAAC;QACtB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAC;QAClB,OAAO,CAAC,CAAC,CAAC;YACR,wBAAwB;YACxB,MAAM,WAAW,GAAU,GAAG,CAAC,UAAU,CAAC;YAC1C,KAAK,WAAW,CAAC;YACjB,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI;CACI,CAAC"}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}