@nodii/telemetry 0.0.2 → 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.
- package/README.md +223 -1
- package/dist/active-span.d.ts +12 -0
- package/dist/active-span.d.ts.map +1 -0
- package/dist/active-span.js +20 -0
- package/dist/active-span.js.map +1 -0
- package/dist/agent-invocable.d.ts +24 -0
- package/dist/agent-invocable.d.ts.map +1 -0
- package/dist/agent-invocable.js +64 -0
- package/dist/agent-invocable.js.map +1 -0
- package/dist/audit-types.d.ts +15 -0
- package/dist/audit-types.d.ts.map +1 -0
- package/dist/audit-types.js +39 -0
- package/dist/audit-types.js.map +1 -0
- package/dist/audit.d.ts +226 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +255 -0
- package/dist/audit.js.map +1 -0
- package/dist/configure.d.ts +34 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +23 -0
- package/dist/configure.js.map +1 -0
- package/dist/context.d.ts +40 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +70 -0
- package/dist/context.js.map +1 -0
- package/dist/drizzle/audit-schema.d.ts +884 -0
- package/dist/drizzle/audit-schema.d.ts.map +1 -0
- package/dist/drizzle/audit-schema.js +268 -0
- package/dist/drizzle/audit-schema.js.map +1 -0
- package/dist/drizzle/index.d.ts +3 -0
- package/dist/drizzle/index.d.ts.map +1 -0
- package/dist/drizzle/index.js +5 -0
- package/dist/drizzle/index.js.map +1 -0
- package/dist/index.d.ts +21 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -5
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +39 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +114 -0
- package/dist/init.js.map +1 -0
- package/dist/intent.d.ts +21 -0
- package/dist/intent.d.ts.map +1 -0
- package/dist/intent.js +123 -0
- package/dist/intent.js.map +1 -0
- package/dist/logger.d.ts +19 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +99 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +53 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +152 -0
- package/dist/metrics.js.map +1 -0
- package/dist/otlp-adapter.d.ts +44 -0
- package/dist/otlp-adapter.d.ts.map +1 -0
- package/dist/otlp-adapter.js +351 -0
- package/dist/otlp-adapter.js.map +1 -0
- package/dist/outbox-emit.d.ts +34 -0
- package/dist/outbox-emit.d.ts.map +1 -0
- package/dist/outbox-emit.js +58 -0
- package/dist/outbox-emit.js.map +1 -0
- package/dist/redaction.d.ts +51 -0
- package/dist/redaction.d.ts.map +1 -0
- package/dist/redaction.js +173 -0
- package/dist/redaction.js.map +1 -0
- package/dist/sdk-counters.d.ts +14 -0
- package/dist/sdk-counters.d.ts.map +1 -0
- package/dist/sdk-counters.js +42 -0
- package/dist/sdk-counters.js.map +1 -0
- package/dist/tracer.d.ts +63 -0
- package/dist/tracer.d.ts.map +1 -0
- package/dist/tracer.js +214 -0
- package/dist/tracer.js.map +1 -0
- package/dist/types.d.ts +230 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +66 -0
- package/dist/types.js.map +1 -0
- package/dist/uuid.d.ts +5 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +34 -0
- package/dist/uuid.js.map +1 -0
- package/package.json +44 -7
package/README.md
CHANGED
|
@@ -1,5 +1,227 @@
|
|
|
1
1
|
# @nodii/telemetry
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Substrate observability library for the Nodii microservice stack. v0.1.0
|
|
4
|
+
ships the SDK surface — bootstrap, log envelope, tracer, meter, audit
|
|
5
|
+
signal, intent lifecycle, agent registry, context propagation — without
|
|
6
|
+
the OTel-SDK wiring (deferred to a v0.1.x follow-up; see
|
|
7
|
+
`.agent-todo.md` TS-12).
|
|
4
8
|
|
|
5
9
|
**Spec**: `https://planning.dev.nucleus-cloud.in/api/v1/feature-docs?serviceId=nodii-libs&docKey=telemetry`
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
bun add @nodii/telemetry
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Bootstrap (D152)
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { initTelemetry } from "@nodii/telemetry";
|
|
21
|
+
|
|
22
|
+
initTelemetry({
|
|
23
|
+
serviceName: "nodii-billing-service",
|
|
24
|
+
env: process.env.APPLICATION_STATE!, // 'dev' | 'uat' | 'prod'
|
|
25
|
+
otlpEndpoint: process.env.OTLP_ENDPOINT,
|
|
26
|
+
vocabularyRegistry: {
|
|
27
|
+
billing_payments_total: {
|
|
28
|
+
family: "async_worker",
|
|
29
|
+
description: "Payments processed",
|
|
30
|
+
decision: "D23",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
intentTypes: {
|
|
34
|
+
"billing.invoice.create": {
|
|
35
|
+
typeName: "billing.invoice.create",
|
|
36
|
+
server_mintable: true,
|
|
37
|
+
client_mintable: false,
|
|
38
|
+
timeout_seconds: 300,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Subsequent `initTelemetry()` calls warn-log + no-op. Calling any public
|
|
45
|
+
API before init throws `TelemetryNotInitialized`.
|
|
46
|
+
|
|
47
|
+
## Logger (D13)
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { logger } from "@nodii/telemetry";
|
|
51
|
+
|
|
52
|
+
logger.info("payment.charged", { invoice_id, amount_minor_units });
|
|
53
|
+
logger.error("saga.compensation.failed", { saga_id, step, reason });
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The 11-field envelope (`level, ts, msg, service, env, tenant_id,
|
|
57
|
+
user_id, request_id, trace_id, span_id, intent_id`) is auto-attached
|
|
58
|
+
from the active `NodiiContext` + the init config + the active OTel
|
|
59
|
+
span. **Do not pass envelope fields yourself** — they get filled in.
|
|
60
|
+
|
|
61
|
+
D15 redaction runs on every line (structured-field keys against the D2
|
|
62
|
+
PII list + regex pass on the message string) and is **fail-closed**:
|
|
63
|
+
if redaction throws, the line is DROPPED and
|
|
64
|
+
`telemetry.sdk.redaction_failure_total{reason}` bumps.
|
|
65
|
+
|
|
66
|
+
## Tracer (D26 / D27 / D28)
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import { tracer, withSpanAttributes } from "@nodii/telemetry";
|
|
70
|
+
|
|
71
|
+
await withSpanAttributes({ invoice_id }, async () => {
|
|
72
|
+
await tracer.span("billing.invoice.create", async (span) => {
|
|
73
|
+
span.setAttribute("payment.method", method);
|
|
74
|
+
// ... business logic; mandatory attrs auto-applied
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Mandatory attributes (`tenant_id, request_id, intent_id`) are stamped
|
|
80
|
+
on span start. 4 KB per-value cap with `_truncated=true` marker. D27
|
|
81
|
+
status mapping: `recordException` auto-pairs with `ERROR`; clean
|
|
82
|
+
return defaults to `OK`.
|
|
83
|
+
|
|
84
|
+
## Metrics (D18 / D19 / D20 / D24)
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { metrics } from "@nodii/telemetry";
|
|
88
|
+
|
|
89
|
+
const paymentsCounter = metrics.counter("billing_payments_total", {
|
|
90
|
+
family: "async_worker",
|
|
91
|
+
description: "Payments processed",
|
|
92
|
+
});
|
|
93
|
+
paymentsCounter.inc({ tenant_id, pgw, status });
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Names must exist in the vocabulary registry passed to
|
|
97
|
+
`initTelemetry({ vocabularyRegistry })` — D24 ADR-gated. Mismatched
|
|
98
|
+
family or off-vocab name → `MetricVocabularyError` + bumps
|
|
99
|
+
`telemetry.sdk.cardinality_rejected_total{family, reason}`.
|
|
100
|
+
|
|
101
|
+
D20 bare-label discipline: registration rejects `tenant.id` and
|
|
102
|
+
`tenantId` variants.
|
|
103
|
+
|
|
104
|
+
D19: exponential histograms, max 160 buckets.
|
|
105
|
+
|
|
106
|
+
## Audit (D17 / D33)
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
import { audit } from "@nodii/telemetry";
|
|
110
|
+
|
|
111
|
+
await audit.emit({
|
|
112
|
+
action: "payment.refund.issued",
|
|
113
|
+
target_kind: "payment",
|
|
114
|
+
target_id: payment.id,
|
|
115
|
+
payload: { amount_minor_units, reason },
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The library ships the adapter (write path); the emission policy
|
|
120
|
+
(method-level interceptor, saga lifecycle events, agent-layer
|
|
121
|
+
double-emission) and the `audit_log` schema live in the audit
|
|
122
|
+
doctrine + each consuming service.
|
|
123
|
+
|
|
124
|
+
## Intent lifecycle (D46 / D155)
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { intent } from "@nodii/telemetry";
|
|
128
|
+
|
|
129
|
+
const id = await intent.begin("billing.invoice.create", { invoice_id });
|
|
130
|
+
try {
|
|
131
|
+
// work
|
|
132
|
+
await intent.complete(id, { result: "ok" });
|
|
133
|
+
} catch (err) {
|
|
134
|
+
await intent.abandon(id, "error");
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`intent.begin` HARD-validates the type name against the registry
|
|
140
|
+
(D155); unknown type → `IntentTypeNotRegistered`. Activates the intent
|
|
141
|
+
on the active `NodiiContext` (sets `intent_id`). Nested begins stack
|
|
142
|
+
by id match.
|
|
143
|
+
|
|
144
|
+
`intent.progress` is a no-op stub at v0.1.0 per D155 § M02
|
|
145
|
+
carry-forward.
|
|
146
|
+
|
|
147
|
+
## @agentInvocable (D156)
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { agentInvocable } from "@nodii/telemetry";
|
|
151
|
+
|
|
152
|
+
class PaymentService {
|
|
153
|
+
@agentInvocable({
|
|
154
|
+
mode: "composable",
|
|
155
|
+
authTier: "confirmation-required",
|
|
156
|
+
sideEffects: ["payment.refund"],
|
|
157
|
+
idempotency: "keyed-by-request-id",
|
|
158
|
+
description: "Refund a captured payment",
|
|
159
|
+
})
|
|
160
|
+
async refundPayment(req: RefundRequest): Promise<RefundResult> {
|
|
161
|
+
/* ... */
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Runtime is a no-op at v0.1.0 (D156). The decorator attaches the
|
|
167
|
+
config to the method + the class prototype under a symbol-keyed
|
|
168
|
+
property; the build-time codegen (separate tool, deferred) walks the
|
|
169
|
+
tsc AST + falls back to the runtime registry to emit
|
|
170
|
+
`agent-methods.generated.json`.
|
|
171
|
+
|
|
172
|
+
## Context propagation (D40 / D41)
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import {
|
|
176
|
+
type NodiiContext,
|
|
177
|
+
withContext,
|
|
178
|
+
getContext,
|
|
179
|
+
requireContext,
|
|
180
|
+
} from "@nodii/telemetry";
|
|
181
|
+
|
|
182
|
+
const ctx: NodiiContext = {
|
|
183
|
+
tenant_id: "...",
|
|
184
|
+
user_id: "...",
|
|
185
|
+
actor_type: "user",
|
|
186
|
+
on_behalf_of: null,
|
|
187
|
+
role: "owner",
|
|
188
|
+
request_id: "...",
|
|
189
|
+
intent_id: null,
|
|
190
|
+
};
|
|
191
|
+
await withContext(ctx, async () => {
|
|
192
|
+
/* every log / span / metric / audit emit picks up this context */
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Read with `getContext()` (returns null when no scope active) or
|
|
197
|
+
`requireContext()` (throws). SDK middleware adapters (deferred to
|
|
198
|
+
TS-9) are the ONLY writers of the parent-scope context per D41 lock;
|
|
199
|
+
service code uses `withContext` for child scopes only.
|
|
200
|
+
|
|
201
|
+
## SDK-internal counters
|
|
202
|
+
|
|
203
|
+
The library increments these on its own behaviors (do not register
|
|
204
|
+
them in your vocabulary):
|
|
205
|
+
|
|
206
|
+
- `telemetry.sdk.redaction_failure_total{reason}` — D15 fail-closed
|
|
207
|
+
drop.
|
|
208
|
+
- `telemetry.sdk.cardinality_rejected_total{family, reason}` — D18.
|
|
209
|
+
- `telemetry.sdk.export_failures_total{signal, reason}` — D153.
|
|
210
|
+
- `telemetry.sdk.trace_propagation_missing_total` — § 5.9 D25.
|
|
211
|
+
|
|
212
|
+
## Deferred to v0.1.x
|
|
213
|
+
|
|
214
|
+
See `.agent-todo.md` at the repo root:
|
|
215
|
+
|
|
216
|
+
- **TS-9**: Subpath adapters (`/grpc`, `/bullmq`, `/outbox`,
|
|
217
|
+
`/system-process`, `/lambda`).
|
|
218
|
+
- **TS-12**: Real OTel SDK wiring — replaces the no-op
|
|
219
|
+
`SpanEmitter` + the default JSON log sink with the OTLP
|
|
220
|
+
exporters.
|
|
221
|
+
- **TS-13**: Smoke service per D157 at `ts/telemetry-smoke/`.
|
|
222
|
+
- **TS-14**: Telemetry-tax-budget benchmark (D28 ≤ 200µs SDK-side
|
|
223
|
+
per typical RPC).
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ActiveSpanRef {
|
|
2
|
+
trace_id: string;
|
|
3
|
+
span_id: string;
|
|
4
|
+
}
|
|
5
|
+
export type ActiveSpanGetter = () => ActiveSpanRef | null;
|
|
6
|
+
/** SDK-internal: the tracer module installs this on initialization. */
|
|
7
|
+
export declare function _setActiveSpanGetter(g: ActiveSpanGetter): void;
|
|
8
|
+
/** Read the active span ids. Returns null when no span is active. */
|
|
9
|
+
export declare function getActiveSpan(): ActiveSpanRef | null;
|
|
10
|
+
/** Test-only reset. */
|
|
11
|
+
export declare function _resetActiveSpanForTests(): void;
|
|
12
|
+
//# sourceMappingURL=active-span.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-span.d.ts","sourceRoot":"","sources":["../src/active-span.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,aAAa,GAAG,IAAI,CAAC;AAI1D,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAE9D;AAED,qEAAqE;AACrE,wBAAgB,aAAa,IAAI,aAAa,GAAG,IAAI,CAEpD;AAED,uBAAuB;AACvB,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Active-span hooks. The tracer (§ 5.3) registers a getter that returns
|
|
2
|
+
// the current `{ trace_id, span_id }` pair, or null if no span is
|
|
3
|
+
// active. The logger reads this on every log line so envelope fields
|
|
4
|
+
// `trace_id` and `span_id` (D13) are auto-stamped without the logger
|
|
5
|
+
// importing the tracer (avoids a cycle and lets the OTel wiring land
|
|
6
|
+
// in TS-12 as a strict module-internal swap).
|
|
7
|
+
let getter = () => null;
|
|
8
|
+
/** SDK-internal: the tracer module installs this on initialization. */
|
|
9
|
+
export function _setActiveSpanGetter(g) {
|
|
10
|
+
getter = g;
|
|
11
|
+
}
|
|
12
|
+
/** Read the active span ids. Returns null when no span is active. */
|
|
13
|
+
export function getActiveSpan() {
|
|
14
|
+
return getter();
|
|
15
|
+
}
|
|
16
|
+
/** Test-only reset. */
|
|
17
|
+
export function _resetActiveSpanForTests() {
|
|
18
|
+
getter = () => null;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=active-span.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"active-span.js","sourceRoot":"","sources":["../src/active-span.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,kEAAkE;AAClE,qEAAqE;AACrE,qEAAqE;AACrE,qEAAqE;AACrE,8CAA8C;AAS9C,IAAI,MAAM,GAAqB,GAAG,EAAE,CAAC,IAAI,CAAC;AAE1C,uEAAuE;AACvE,MAAM,UAAU,oBAAoB,CAAC,CAAmB;IACtD,MAAM,GAAG,CAAC,CAAC;AACb,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,aAAa;IAC3B,OAAO,MAAM,EAAE,CAAC;AAClB,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,wBAAwB;IACtC,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type AgentInvocableConfig } from "./types";
|
|
2
|
+
export declare const AGENT_INVOCABLE_METADATA: unique symbol;
|
|
3
|
+
/**
|
|
4
|
+
* Method decorator. TS legacy decorators are still the only widely
|
|
5
|
+
* deployed form for class methods; we attach metadata under a
|
|
6
|
+
* symbol-keyed property on the method itself + on the class prototype.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
*
|
|
10
|
+
* class PaymentService {
|
|
11
|
+
* @agentInvocable({ mode: 'composable', authTier: 'confirmation-required',
|
|
12
|
+
* sideEffects: ['payment.refund'], idempotency: 'keyed-by-request-id',
|
|
13
|
+
* description: 'Refund a captured payment' })
|
|
14
|
+
* async refundPayment(req) { ... }
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
export declare function agentInvocable(cfg: AgentInvocableConfig): (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
18
|
+
/**
|
|
19
|
+
* Read the registry from a class. Used by tests + the codegen fallback
|
|
20
|
+
* (when AST discovery doesn't find a decorator, e.g. when the file was
|
|
21
|
+
* transformed by a different toolchain).
|
|
22
|
+
*/
|
|
23
|
+
export declare function readAgentRegistry<T extends object>(ctor: T): Record<string | symbol, AgentInvocableConfig>;
|
|
24
|
+
//# sourceMappingURL=agent-invocable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-invocable.d.ts","sourceRoot":"","sources":["../src/agent-invocable.ts"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,wBAAwB,eAEpC,CAAC;AAoBF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,oBAAoB,IAGpD,QAAQ,MAAM,EACd,aAAa,MAAM,GAAG,MAAM,EAC5B,YAAY,kBAAkB,KAC7B,kBAAkB,CAuBtB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAChD,IAAI,EAAE,CAAC,GACN,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,oBAAoB,CAAC,CAM/C"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// `@agentInvocable` decorator per D156. Runtime no-op at v0.1.0 — the
|
|
2
|
+
// agent dispatcher consumes the build-time codegen registry
|
|
3
|
+
// (`agent-methods.generated.json`), not the runtime metadata.
|
|
4
|
+
//
|
|
5
|
+
// At v0.1.0 we attach the supplied config to the method's prototype
|
|
6
|
+
// under a well-known symbol so the codegen step (a separate tsc AST
|
|
7
|
+
// walk in TS-8 wave 2) can also discover registrations via runtime
|
|
8
|
+
// import if it falls back from the AST path.
|
|
9
|
+
import { AGENT_INVOCABLE_SIDE_EFFECTS, } from "./types";
|
|
10
|
+
export const AGENT_INVOCABLE_METADATA = Symbol.for("@nodii/telemetry/agentInvocable");
|
|
11
|
+
function validate(cfg) {
|
|
12
|
+
if (cfg.mode === "strict-only" && !cfg.allowedPipelines?.length) {
|
|
13
|
+
throw new Error("@agentInvocable: `allowedPipelines` is required when `mode = 'strict-only'`");
|
|
14
|
+
}
|
|
15
|
+
for (const eff of cfg.sideEffects) {
|
|
16
|
+
if (!AGENT_INVOCABLE_SIDE_EFFECTS.includes(eff)) {
|
|
17
|
+
throw new Error(`@agentInvocable: sideEffect '${eff}' is not in the locked vocabulary (D156).`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
if (!cfg.description) {
|
|
21
|
+
throw new Error("@agentInvocable: `description` is required");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Method decorator. TS legacy decorators are still the only widely
|
|
26
|
+
* deployed form for class methods; we attach metadata under a
|
|
27
|
+
* symbol-keyed property on the method itself + on the class prototype.
|
|
28
|
+
*
|
|
29
|
+
* Usage:
|
|
30
|
+
*
|
|
31
|
+
* class PaymentService {
|
|
32
|
+
* @agentInvocable({ mode: 'composable', authTier: 'confirmation-required',
|
|
33
|
+
* sideEffects: ['payment.refund'], idempotency: 'keyed-by-request-id',
|
|
34
|
+
* description: 'Refund a captured payment' })
|
|
35
|
+
* async refundPayment(req) { ... }
|
|
36
|
+
* }
|
|
37
|
+
*/
|
|
38
|
+
export function agentInvocable(cfg) {
|
|
39
|
+
validate(cfg);
|
|
40
|
+
return function decorate(target, propertyKey, descriptor) {
|
|
41
|
+
const original = descriptor.value;
|
|
42
|
+
if (typeof original !== "function") {
|
|
43
|
+
throw new Error("@agentInvocable can only be applied to methods (PropertyDescriptor.value must be a function).");
|
|
44
|
+
}
|
|
45
|
+
// Attach metadata to the method function itself.
|
|
46
|
+
original[AGENT_INVOCABLE_METADATA] =
|
|
47
|
+
cfg;
|
|
48
|
+
// Mirror onto a class-level registry under the same symbol.
|
|
49
|
+
const ctor = target.constructor;
|
|
50
|
+
const existing = ctor[AGENT_INVOCABLE_METADATA] ?? {};
|
|
51
|
+
existing[propertyKey] = cfg;
|
|
52
|
+
ctor[AGENT_INVOCABLE_METADATA] = existing;
|
|
53
|
+
return descriptor;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Read the registry from a class. Used by tests + the codegen fallback
|
|
58
|
+
* (when AST discovery doesn't find a decorator, e.g. when the file was
|
|
59
|
+
* transformed by a different toolchain).
|
|
60
|
+
*/
|
|
61
|
+
export function readAgentRegistry(ctor) {
|
|
62
|
+
return (ctor[AGENT_INVOCABLE_METADATA] ?? {});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=agent-invocable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-invocable.js","sourceRoot":"","sources":["../src/agent-invocable.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,4DAA4D;AAC5D,8DAA8D;AAC9D,EAAE;AACF,oEAAoE;AACpE,oEAAoE;AACpE,mEAAmE;AACnE,6CAA6C;AAE7C,OAAO,EACL,4BAA4B,GAE7B,MAAM,SAAS,CAAC;AAEjB,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,GAAG,CAChD,iCAAiC,CAClC,CAAC;AAEF,SAAS,QAAQ,CAAC,GAAyB;IACzC,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,4BAA4B,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CACb,gCAAgC,GAAG,2CAA2C,CAC/E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,GAAyB;IACtD,QAAQ,CAAC,GAAG,CAAC,CAAC;IACd,OAAO,SAAS,QAAQ,CACtB,MAAc,EACd,WAA4B,EAC5B,UAA8B;QAE9B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC;QAClC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,+FAA+F,CAChG,CAAC;QACJ,CAAC;QACD,iDAAiD;QAChD,QAA+C,CAAC,wBAAwB,CAAC;YACxE,GAAG,CAAC;QACN,4DAA4D;QAC5D,MAAM,IAAI,GAAI,MAAkC,CAAC,WAGhD,CAAC;QACF,MAAM,QAAQ,GACX,IAAI,CAAC,wBAAwB,CAEhB,IAAI,EAAE,CAAC;QACvB,QAAQ,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC;QAC5B,IAAI,CAAC,wBAAwB,CAAC,GAAG,QAAQ,CAAC;QAC1C,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAO;IAEP,OAAO,CACH,IAA2C,CAC3C,wBAAwB,CACyB,IAAI,EAAE,CAC1D,CAAC;AACJ,CAAC"}
|
|
@@ -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
ADDED
|
@@ -0,0 +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
|
+
*/
|
|
130
|
+
export interface AuditEvent {
|
|
131
|
+
/** D33-locked vocabulary, e.g. `payment.refund.issued`. */
|
|
132
|
+
action: string;
|
|
133
|
+
/** Maps to `resource_type` per doctrine § 3. */
|
|
134
|
+
target_kind: string;
|
|
135
|
+
/** Maps to `resource_id` per doctrine § 3. */
|
|
136
|
+
target_id: string | null;
|
|
137
|
+
/** Maps to `metadata` per doctrine § 3. */
|
|
138
|
+
payload?: Record<string, unknown>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
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.
|
|
158
|
+
*/
|
|
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
|
+
}
|
|
181
|
+
/**
|
|
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.
|
|
194
|
+
*/
|
|
195
|
+
export declare function _setAuditWriter(w: AuditWriter): void;
|
|
196
|
+
/** Test-only reset. Clears the wired writer; the next `audit.emit` will throw. */
|
|
197
|
+
export declare function _resetAuditWriterForTests(): void;
|
|
198
|
+
/**
|
|
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.
|
|
221
|
+
*/
|
|
222
|
+
declare function emit(event: AuditEvent): Promise<void>;
|
|
223
|
+
export declare const audit: {
|
|
224
|
+
readonly emit: typeof emit;
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"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"}
|