pipework 0.94.0 → 0.96.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/data/db/db.d.ts +6 -3
  3. package/dist/data/db/db.d.ts.map +1 -1
  4. package/dist/data/db/db.js +10 -6
  5. package/dist/data/db/db.js.map +1 -1
  6. package/dist/data/db/pool.d.ts +2 -0
  7. package/dist/data/db/pool.d.ts.map +1 -1
  8. package/dist/data/db/pool.js.map +1 -1
  9. package/dist/data/migrate/internal-definitions.d.ts.map +1 -1
  10. package/dist/data/migrate/internal-definitions.js +2 -1
  11. package/dist/data/migrate/internal-definitions.js.map +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/infra/alerts/handle.d.ts +108 -7
  16. package/dist/infra/alerts/handle.d.ts.map +1 -1
  17. package/dist/infra/alerts/handle.js +291 -26
  18. package/dist/infra/alerts/handle.js.map +1 -1
  19. package/dist/infra/alerts/http.d.ts +19 -0
  20. package/dist/infra/alerts/http.d.ts.map +1 -0
  21. package/dist/infra/alerts/http.js +172 -0
  22. package/dist/infra/alerts/http.js.map +1 -0
  23. package/dist/infra/alerts/index.d.ts +4 -2
  24. package/dist/infra/alerts/index.d.ts.map +1 -1
  25. package/dist/infra/alerts/index.js +1 -0
  26. package/dist/infra/alerts/index.js.map +1 -1
  27. package/dist/infra/alerts/namespace.d.ts +3 -0
  28. package/dist/infra/alerts/namespace.d.ts.map +1 -1
  29. package/dist/infra/alerts/namespace.js +3 -0
  30. package/dist/infra/alerts/namespace.js.map +1 -1
  31. package/dist/infra/alerts/schema.d.ts +91 -5
  32. package/dist/infra/alerts/schema.d.ts.map +1 -1
  33. package/dist/infra/alerts/schema.js +29 -3
  34. package/dist/infra/alerts/schema.js.map +1 -1
  35. package/dist/infra/alerts/sinks.d.ts +37 -3
  36. package/dist/infra/alerts/sinks.d.ts.map +1 -1
  37. package/dist/infra/alerts/sinks.js.map +1 -1
  38. package/dist/test/plugin.d.ts.map +1 -1
  39. package/dist/test/plugin.js +11 -4
  40. package/dist/test/plugin.js.map +1 -1
  41. package/dist/test/savepoints.d.ts +4 -1
  42. package/dist/test/savepoints.d.ts.map +1 -1
  43. package/dist/test/savepoints.js +12 -5
  44. package/dist/test/savepoints.js.map +1 -1
  45. package/dist/test/setup.d.ts.map +1 -1
  46. package/dist/test/setup.js +36 -0
  47. package/dist/test/setup.js.map +1 -1
  48. package/dist/test/system-channel.d.ts +14 -0
  49. package/dist/test/system-channel.d.ts.map +1 -0
  50. package/dist/test/system-channel.js +41 -0
  51. package/dist/test/system-channel.js.map +1 -0
  52. package/package.json +1 -1
@@ -0,0 +1,172 @@
1
+ import { createHash, timingSafeEqual } from 'node:crypto';
2
+ import { Builder } from '../../request/di/builder.js';
3
+ import { schema } from '../../data/schema/namespace.js';
4
+ import { PipeworkError, NotFoundError, UnauthorizedError } from '../../core/errors/index.js';
5
+ class BadRequestError extends PipeworkError {
6
+ code = 'BAD_REQUEST';
7
+ httpStatus = 400;
8
+ }
9
+ const STATUSES = ['open', 'acknowledged', 'resolved'];
10
+ const SEVERITIES = ['info', 'warning', 'error', 'critical'];
11
+ const sha = (s) => createHash('sha256').update(s).digest();
12
+ function authenticate(credentials, header) {
13
+ const match = header !== undefined ? /^Bearer (.+)$/.exec(header) : null;
14
+ const given = sha(match?.[1] ?? '');
15
+ let name = null;
16
+ for (const [credName, digest] of credentials) {
17
+ if (timingSafeEqual(given, digest) && match !== null && name === null)
18
+ name = credName;
19
+ }
20
+ if (name === null)
21
+ throw new UnauthorizedError('A valid service credential is required: send Authorization: Bearer <secret>.');
22
+ return name;
23
+ }
24
+ function bad(field, problem) {
25
+ throw new BadRequestError(`Invalid ${field}: ${problem}.`, { field });
26
+ }
27
+ function optString(source, field) {
28
+ const value = source?.[field];
29
+ if (value === undefined)
30
+ return undefined;
31
+ if (typeof value !== 'string')
32
+ bad(field, 'must be a string');
33
+ return value;
34
+ }
35
+ function body(raw) {
36
+ if (raw === undefined || raw === null)
37
+ return {};
38
+ if (typeof raw !== 'object' || Array.isArray(raw))
39
+ bad('body', 'must be a JSON object');
40
+ return raw;
41
+ }
42
+ function csv(raw, field, allowed) {
43
+ if (raw === undefined || raw === '')
44
+ return undefined;
45
+ const out = [];
46
+ for (const part of raw.split(',')) {
47
+ if (!allowed.includes(part))
48
+ bad(field, `"${part}" is not one of ${allowed.join(', ')}`);
49
+ out.push(part);
50
+ }
51
+ return out;
52
+ }
53
+ function limitOf(raw) {
54
+ if (raw === undefined)
55
+ return undefined;
56
+ if (!/^[1-9][0-9]*$/.test(raw))
57
+ bad('limit', 'must be a positive integer');
58
+ return Number(raw);
59
+ }
60
+ function pageQuery(query) {
61
+ const limit = optString(query, 'limit');
62
+ const cursor = optString(query, 'cursor');
63
+ const out = {};
64
+ const n = limitOf(limit);
65
+ if (n !== undefined)
66
+ out.limit = n;
67
+ if (cursor !== undefined)
68
+ out.cursor = cursor;
69
+ return out;
70
+ }
71
+ function validateOptions(options) {
72
+ if (!options.path.startsWith('/') || options.path.length < 2 || options.path.endsWith('/')) {
73
+ throw new Error(`alerts.http: path "${options.path}" must start with "/" and have no trailing slash, e.g. "/ops/alerts".`);
74
+ }
75
+ const entries = Object.entries(options.credentials);
76
+ if (entries.length === 0) {
77
+ throw new Error('alerts.http: credentials needs at least one entry, name -> secret (the secret is at least 32 characters).');
78
+ }
79
+ for (const [name, secret] of entries) {
80
+ if (typeof secret !== 'string' || secret.length < 32) {
81
+ throw new Error(`alerts.http: the secret for credential "${name}" is under 32 characters; use a long random value.`);
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Routes for an operations agent, under `options.path` (all JSON, no session, no tenant):
87
+ * GET list (`status`, `severity` comma lists, `limit`, `cursor`), GET `/totals`, GET `/health`,
88
+ * GET `/:key` (an alert keyed `totals` or `health` is not reachable here), GET `/:key/occurrences`, and POST `/:key/acknowledge`, `/:key/resolve`, `/:key/link`.
89
+ * `:key` is URL-encoded. Every request needs `Authorization: Bearer <secret>` matching one of
90
+ * `credentials`; the credential's name is the default `by` for acknowledge and resolve.
91
+ * Reads cross tenants (the handle reads through `pipe.system()`). Resolve never notifies:
92
+ * the agent does not hear its own change. Dates are ISO strings. A bad value is 400 naming the field.
93
+ */
94
+ export function alertsHttp(handle, options) {
95
+ validateOptions(options);
96
+ const credentials = Object.entries(options.credentials).map(([name, secret]) => [name, sha(secret)]);
97
+ const base = options.path;
98
+ const any = schema.check.unknown();
99
+ const get = (path) => new Builder().public().request().query(any).params(any).route('GET', path);
100
+ const post = (path) => new Builder().public().request().query(any).params(any).input(any).route('POST', path);
101
+ // Dates inside the results serialize through JSON.stringify as ISO strings.
102
+ const keyOf = (params) => String(params.key);
103
+ const known = async (key) => {
104
+ if ((await handle.get(key)) === null)
105
+ throw new NotFoundError(`Alert "${key}"`);
106
+ };
107
+ return [
108
+ get(base).fit(async ({ request, query }) => {
109
+ authenticate(credentials, request.headers['authorization']);
110
+ const q = pageQuery(query);
111
+ const status = csv(optString(query, 'status'), 'status', STATUSES);
112
+ const severity = csv(optString(query, 'severity'), 'severity', SEVERITIES);
113
+ if (status !== undefined)
114
+ q.status = status;
115
+ if (severity !== undefined)
116
+ q.severity = severity;
117
+ return handle.list(q);
118
+ }),
119
+ get(`${base}/totals`).fit(async ({ request }) => {
120
+ authenticate(credentials, request.headers['authorization']);
121
+ return handle.totals();
122
+ }),
123
+ get(`${base}/health`).fit(async ({ request }) => {
124
+ authenticate(credentials, request.headers['authorization']);
125
+ return handle.health();
126
+ }),
127
+ get(`${base}/:key`).fit(async ({ request, params }) => {
128
+ authenticate(credentials, request.headers['authorization']);
129
+ const found = await handle.get(keyOf(params));
130
+ if (found === null)
131
+ throw new NotFoundError(`Alert "${keyOf(params)}"`);
132
+ return found;
133
+ }),
134
+ get(`${base}/:key/occurrences`).fit(async ({ request, params, query }) => {
135
+ authenticate(credentials, request.headers['authorization']);
136
+ const page = pageQuery(query);
137
+ await known(keyOf(params));
138
+ return handle.occurrences(keyOf(params), page);
139
+ }),
140
+ post(`${base}/:key/acknowledge`).fit(async ({ request, params, input }) => {
141
+ const name = authenticate(credentials, request.headers['authorization']);
142
+ const b = body(input);
143
+ const by = optString(b, 'by') ?? name;
144
+ const note = optString(b, 'note');
145
+ return { acknowledged: await handle.acknowledge(keyOf(params), note === undefined ? { by } : { by, note }) };
146
+ }),
147
+ post(`${base}/:key/resolve`).fit(async ({ request, params, input }) => {
148
+ const name = authenticate(credentials, request.headers['authorization']);
149
+ const b = body(input);
150
+ const by = optString(b, 'by') ?? name;
151
+ const note = optString(b, 'note');
152
+ const release = optString(b, 'release');
153
+ return {
154
+ resolved: await handle.resolve(keyOf(params), {
155
+ by, notify: false,
156
+ ...(note === undefined ? {} : { note }),
157
+ ...(release === undefined ? {} : { release }),
158
+ }),
159
+ };
160
+ }),
161
+ post(`${base}/:key/link`).fit(async ({ request, params, input }) => {
162
+ authenticate(credentials, request.headers['authorization']);
163
+ const url = optString(body(input), 'url');
164
+ if (url === undefined)
165
+ bad('url', 'is required');
166
+ if (!/^https?:\/\/[^\s]+$/i.test(url))
167
+ bad('url', 'must be an http or https URL');
168
+ return { linked: await handle.link(keyOf(params), url) };
169
+ }),
170
+ ];
171
+ }
172
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/infra/alerts/http.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  export { createAlerts } from './handle.js';
2
- export type { Alerts, AlertsConfig, Alert, AlertSeverity, AlertSubject, RaiseOptions, DeliveryRow, TickResult, } from './handle.js';
3
- export type { AlertSink, AlertDelivery, AlertPayload, AlertWebhookConfig, MemoryAlertSink } from './sinks.js';
2
+ export type { Alerts, AlertsConfig, Alert, AlertSeverity, AlertSubject, RaiseOptions, DeliveryRow, TickResult, AlertStatus, JsonValue, AlertOccurrence, Page, AlertTotals, DeliveryHealth, ResolveOptions, } from './handle.js';
3
+ export type { AlertSink, AlertDelivery, AlertPayload, AlertEventPayload, AlertDigestPayload, AlertWebhookConfig, MemoryAlertSink } from './sinks.js';
4
4
  export type { AlertSource, AlertCondition } from './sources.js';
5
+ export { alertsHttp } from './http.js';
6
+ export type { AlertsHttpOptions } from './http.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EACV,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,GAChG,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC7G,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EACV,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAC/F,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,GAC3F,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACpJ,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA"}
@@ -1,2 +1,3 @@
1
1
  export { createAlerts } from './handle.js';
2
+ export { alertsHttp } from './http.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infra/alerts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infra/alerts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA"}
@@ -1,10 +1,13 @@
1
1
  import { createAlerts } from './handle.js';
2
+ import { alertsHttp } from './http.js';
2
3
  import { webhookSink, memorySink } from './sinks.js';
3
4
  import { deadLetterSource, longRunningSource, backlogSource, healthSource } from './sources.js';
4
5
  /** Alerts namespace — raise and resolve keyed conditions, grouped, delivered to sinks through an outbox, traced. */
5
6
  export declare const alerts: {
6
7
  /** Creates an alerts handle. */
7
8
  readonly create: typeof createAlerts;
9
+ /** Routes for an operations agent: list, get, totals, delivery health, acknowledge, resolve, link; bearer credentials. */
10
+ readonly http: typeof alertsHttp;
8
11
  /** A sink that POSTs the alert as signed JSON to a URL. */
9
12
  readonly webhook: typeof webhookSink;
10
13
  /** A sink that keeps deliveries in `.delivered`, for tests. */
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE/F,oHAAoH;AACpH,eAAO,MAAM,MAAM;IACjB,gCAAgC;;IAEhC,2DAA2D;;IAE3D,+DAA+D;;;QAG7D,4EAA4E;;QAE5E,iFAAiF;;QAEjF,mGAAmG;;QAEnG,yDAAyD;;;CAGnD,CAAA"}
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE/F,oHAAoH;AACpH,eAAO,MAAM,MAAM;IACjB,gCAAgC;;IAEhC,0HAA0H;;IAE1H,2DAA2D;;IAE3D,+DAA+D;;;QAG7D,4EAA4E;;QAE5E,iFAAiF;;QAEjF,mGAAmG;;QAEnG,yDAAyD;;;CAGnD,CAAA"}
@@ -1,10 +1,13 @@
1
1
  import { createAlerts } from './handle.js';
2
+ import { alertsHttp } from './http.js';
2
3
  import { webhookSink, memorySink } from './sinks.js';
3
4
  import { deadLetterSource, longRunningSource, backlogSource, healthSource } from './sources.js';
4
5
  /** Alerts namespace — raise and resolve keyed conditions, grouped, delivered to sinks through an outbox, traced. */
5
6
  export const alerts = {
6
7
  /** Creates an alerts handle. */
7
8
  create: createAlerts,
9
+ /** Routes for an operations agent: list, get, totals, delivery health, acknowledge, resolve, link; bearer credentials. */
10
+ http: alertsHttp,
8
11
  /** A sink that POSTs the alert as signed JSON to a URL. */
9
12
  webhook: webhookSink,
10
13
  /** A sink that keeps deliveries in `.delivered`, for tests. */
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/infra/alerts/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE/F,oHAAoH;AACpH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,gCAAgC;IAChC,MAAM,EAAE,YAAY;IACpB,2DAA2D;IAC3D,OAAO,EAAE,WAAW;IACpB,+DAA+D;IAC/D,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE;QACN,4EAA4E;QAC5E,UAAU,EAAE,gBAAgB;QAC5B,iFAAiF;QACjF,WAAW,EAAE,iBAAiB;QAC9B,mGAAmG;QACnG,OAAO,EAAE,aAAa;QACtB,yDAAyD;QACzD,MAAM,EAAE,YAAY;KACrB;CACO,CAAA"}
1
+ {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/infra/alerts/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE/F,oHAAoH;AACpH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,gCAAgC;IAChC,MAAM,EAAE,YAAY;IACpB,0HAA0H;IAC1H,IAAI,EAAE,UAAU;IAChB,2DAA2D;IAC3D,OAAO,EAAE,WAAW;IACpB,+DAA+D;IAC/D,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE;QACN,4EAA4E;QAC5E,UAAU,EAAE,gBAAgB;QAC5B,iFAAiF;QACjF,WAAW,EAAE,iBAAiB;QAC9B,mGAAmG;QACnG,OAAO,EAAE,aAAa;QACtB,yDAAyD;QACzD,MAAM,EAAE,YAAY;KACrB;CACO,CAAA"}
@@ -1,15 +1,15 @@
1
- export declare const ALERT_STATUSES: readonly ["open", "resolved"];
1
+ export declare const ALERT_STATUSES: readonly ["open", "acknowledged", "resolved"];
2
2
  export declare const ALERT_SEVERITIES: readonly ["info", "warning", "error", "critical"];
3
- export declare const ALERT_DELIVERY_KINDS: readonly ["raise", "repeat", "resolve"];
3
+ export declare const ALERT_DELIVERY_KINDS: readonly ["raise", "repeat", "resolve", "reopen", "digest"];
4
4
  export declare const alerts: import("../../data/domain/types.js").DefinedTable<{
5
5
  key: import("../../data/domain/types.js").FieldDescriptor<string, {
6
6
  primaryKey: true;
7
7
  }> & import("../../data/domain/field.js").FieldModifiers<string, {
8
8
  primaryKey: true;
9
9
  }>;
10
- status: import("../../data/domain/types.js").FieldDescriptor<"open" | "resolved", {
10
+ status: import("../../data/domain/types.js").FieldDescriptor<"open" | "acknowledged" | "resolved", {
11
11
  hasDefault: true;
12
- }> & import("../../data/domain/field.js").FieldModifiers<"open" | "resolved", {
12
+ }> & import("../../data/domain/field.js").FieldModifiers<"open" | "acknowledged" | "resolved", {
13
13
  hasDefault: true;
14
14
  }>;
15
15
  severity: import("../../data/domain/types.js").FieldDescriptor<"error" | "info" | "warning" | "critical", {}> & import("../../data/domain/field.js").FieldModifiers<"error" | "info" | "warning" | "critical", {}>;
@@ -19,6 +19,21 @@ export declare const alerts: import("../../data/domain/types.js").DefinedTable<{
19
19
  }> & import("../../data/domain/field.js").FieldModifiers<import("zod/v4").JSONType, {
20
20
  nullable: true;
21
21
  }>;
22
+ owner: import("../../data/domain/types.js").FieldDescriptor<string | null, {
23
+ nullable: true;
24
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
25
+ nullable: true;
26
+ }>;
27
+ runbook: import("../../data/domain/types.js").FieldDescriptor<string | null, {
28
+ nullable: true;
29
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
30
+ nullable: true;
31
+ }>;
32
+ context: import("../../data/domain/types.js").FieldDescriptor<import("zod/v4").JSONType, {
33
+ nullable: true;
34
+ }> & import("../../data/domain/field.js").FieldModifiers<import("zod/v4").JSONType, {
35
+ nullable: true;
36
+ }>;
22
37
  count: import("../../data/domain/types.js").FieldDescriptor<number, {
23
38
  hasDefault: true;
24
39
  }> & import("../../data/domain/field.js").FieldModifiers<number, {
@@ -44,6 +59,46 @@ export declare const alerts: import("../../data/domain/types.js").DefinedTable<{
44
59
  }> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
45
60
  nullable: true;
46
61
  }>;
62
+ reopenCount: import("../../data/domain/types.js").FieldDescriptor<number, {
63
+ hasDefault: true;
64
+ }> & import("../../data/domain/field.js").FieldModifiers<number, {
65
+ hasDefault: true;
66
+ }>;
67
+ reopenedAt: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
68
+ nullable: true;
69
+ }> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
70
+ nullable: true;
71
+ }>;
72
+ acknowledgedAt: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
73
+ nullable: true;
74
+ }> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
75
+ nullable: true;
76
+ }>;
77
+ acknowledgedBy: import("../../data/domain/types.js").FieldDescriptor<string | null, {
78
+ nullable: true;
79
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
80
+ nullable: true;
81
+ }>;
82
+ resolvedBy: import("../../data/domain/types.js").FieldDescriptor<string | null, {
83
+ nullable: true;
84
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
85
+ nullable: true;
86
+ }>;
87
+ resolveNote: import("../../data/domain/types.js").FieldDescriptor<string | null, {
88
+ nullable: true;
89
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
90
+ nullable: true;
91
+ }>;
92
+ resolvedRelease: import("../../data/domain/types.js").FieldDescriptor<string | null, {
93
+ nullable: true;
94
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
95
+ nullable: true;
96
+ }>;
97
+ issueUrl: import("../../data/domain/types.js").FieldDescriptor<string | null, {
98
+ nullable: true;
99
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
100
+ nullable: true;
101
+ }>;
47
102
  traceIds: import("../../data/domain/types.js").FieldDescriptor<string[], {
48
103
  hasDefault: true;
49
104
  }> & import("../../data/domain/field.js").FieldModifiers<string[], {
@@ -65,6 +120,37 @@ export declare const alerts: import("../../data/domain/types.js").DefinedTable<{
65
120
  hasDefault: true;
66
121
  }>;
67
122
  }, "pipework_alerts">;
123
+ export declare const alertOccurrences: import("../../data/domain/types.js").DefinedTable<{
124
+ id: import("../../data/domain/types.js").FieldDescriptor<string, {
125
+ defaultRandom: true;
126
+ hasDefault: true;
127
+ } & {
128
+ primaryKey: true;
129
+ }> & import("../../data/domain/field.js").FieldModifiers<string, {
130
+ defaultRandom: true;
131
+ hasDefault: true;
132
+ } & {
133
+ primaryKey: true;
134
+ }>;
135
+ alertKey: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
136
+ at: import("../../data/domain/types.js").FieldDescriptor<Date, {
137
+ hasDefault: true;
138
+ }> & import("../../data/domain/field.js").FieldModifiers<Date, {
139
+ hasDefault: true;
140
+ }>;
141
+ severity: import("../../data/domain/types.js").FieldDescriptor<"error" | "info" | "warning" | "critical", {}> & import("../../data/domain/field.js").FieldModifiers<"error" | "info" | "warning" | "critical", {}>;
142
+ message: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
143
+ context: import("../../data/domain/types.js").FieldDescriptor<import("zod/v4").JSONType, {
144
+ nullable: true;
145
+ }> & import("../../data/domain/field.js").FieldModifiers<import("zod/v4").JSONType, {
146
+ nullable: true;
147
+ }>;
148
+ traceId: import("../../data/domain/types.js").FieldDescriptor<string | null, {
149
+ nullable: true;
150
+ }> & import("../../data/domain/field.js").FieldModifiers<string | null, {
151
+ nullable: true;
152
+ }>;
153
+ }, "pipework_alert_occurrences">;
68
154
  export declare const alertDeliveries: import("../../data/domain/types.js").DefinedTable<{
69
155
  id: import("../../data/domain/types.js").FieldDescriptor<string, {
70
156
  defaultRandom: true;
@@ -78,7 +164,7 @@ export declare const alertDeliveries: import("../../data/domain/types.js").Defin
78
164
  primaryKey: true;
79
165
  }>;
80
166
  alertKey: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
81
- kind: import("../../data/domain/types.js").FieldDescriptor<"repeat" | "raise" | "resolve", {}> & import("../../data/domain/field.js").FieldModifiers<"repeat" | "raise" | "resolve", {}>;
167
+ kind: import("../../data/domain/types.js").FieldDescriptor<"repeat" | "raise" | "resolve" | "reopen" | "digest", {}> & import("../../data/domain/field.js").FieldModifiers<"repeat" | "raise" | "resolve" | "reopen" | "digest", {}>;
82
168
  sink: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
83
169
  payload: import("../../data/domain/types.js").FieldDescriptor<import("zod/v4").JSONType, {}> & import("../../data/domain/field.js").FieldModifiers<import("zod/v4").JSONType, {}>;
84
170
  attempts: import("../../data/domain/types.js").FieldDescriptor<number, {
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/schema.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,cAAc,+BAAgC,CAAA;AAC3D,eAAO,MAAM,gBAAgB,mDAAoD,CAAA;AACjF,eAAO,MAAM,oBAAoB,yCAA0C,CAAA;AAE3E,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAmBjB,CAAA;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAmB1B,CAAA;AAEF,eAAO,MAAM,gBAAgB;;;;;;;iCAG3B,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/schema.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,cAAc,+CAAgD,CAAA;AAC3E,eAAO,MAAM,gBAAgB,mDAAoD,CAAA;AACjF,eAAO,MAAM,oBAAoB,6DAA8D,CAAA;AAE/F,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA8BjB,CAAA;AAGF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAa3B,CAAA;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAmB1B,CAAA;AAEF,eAAO,MAAM,gBAAgB;;;;;;;iCAG3B,CAAA"}
@@ -1,24 +1,35 @@
1
- // The tables behind alerts: one row per alert key, the outbox of deliveries (one row per
1
+ // The tables behind alerts: one row per alert key, one per raise (occurrences), the outbox of deliveries (one row per
2
2
  // event and sink), and the cursor a source keeps between evaluations. Not tenant-scoped.
3
3
  import { define } from '../../data/domain/index.js';
4
4
  import { field } from '../../data/domain/field.js';
5
5
  import { schema } from '../../data/schema/namespace.js';
6
6
  import { index } from '../../data/db/idx/index.js';
7
7
  import { sql } from '../../data/db/sql.js';
8
- export const ALERT_STATUSES = ['open', 'resolved'];
8
+ export const ALERT_STATUSES = ['open', 'acknowledged', 'resolved'];
9
9
  export const ALERT_SEVERITIES = ['info', 'warning', 'error', 'critical'];
10
- export const ALERT_DELIVERY_KINDS = ['raise', 'repeat', 'resolve'];
10
+ export const ALERT_DELIVERY_KINDS = ['raise', 'repeat', 'resolve', 'reopen', 'digest'];
11
11
  export const alerts = define('pipework_alerts', {
12
12
  key: field.text().primaryKey(),
13
13
  status: field.enum(ALERT_STATUSES).default('open'),
14
14
  severity: field.enum(ALERT_SEVERITIES),
15
15
  message: field.text(),
16
16
  subject: field.jsonb(schema.check.json()).nullable(),
17
+ owner: field.text().nullable(),
18
+ runbook: field.text().nullable(),
19
+ context: field.jsonb(schema.check.json()).nullable(),
17
20
  count: field.integer().default(1),
18
21
  firstSeenAt: field.timestamp().default('now'),
19
22
  lastSeenAt: field.timestamp().default('now'),
20
23
  lastSentAt: field.timestamp().nullable(),
21
24
  resolvedAt: field.timestamp().nullable(),
25
+ reopenCount: field.integer().default(0),
26
+ reopenedAt: field.timestamp().nullable(),
27
+ acknowledgedAt: field.timestamp().nullable(),
28
+ acknowledgedBy: field.text().nullable(),
29
+ resolvedBy: field.text().nullable(),
30
+ resolveNote: field.text().nullable(),
31
+ resolvedRelease: field.text().nullable(),
32
+ issueUrl: field.text().nullable(),
22
33
  traceIds: field.custom(schema.col.text('trace_ids').array(), schema.check.array(schema.check.string())).default('{}'),
23
34
  resendAfterMs: field.integer().nullable(),
24
35
  resolveAfterQuietMs: field.integer().nullable(),
@@ -28,6 +39,21 @@ export const alerts = define('pipework_alerts', {
28
39
  byStatus: index('idx_pipework_alerts_status').on(t['status']),
29
40
  }),
30
41
  });
42
+ // One row per raise, kept for `occurrenceRetentionMs`.
43
+ export const alertOccurrences = define('pipework_alert_occurrences', {
44
+ id: field.uuid().defaultRandom().primaryKey(),
45
+ alertKey: field.text(),
46
+ at: field.timestamp().default('now'),
47
+ severity: field.enum(ALERT_SEVERITIES),
48
+ message: field.text(),
49
+ context: field.jsonb(schema.check.json()).nullable(),
50
+ traceId: field.text().nullable(),
51
+ }, {
52
+ indexes: (t) => ({
53
+ byKey: index('idx_pipework_alert_occurrences_key').on(t['alertKey'], t['at'], t['id']),
54
+ byAt: index('idx_pipework_alert_occurrences_at').on(t['at']),
55
+ }),
56
+ });
31
57
  export const alertDeliveries = define('pipework_alert_deliveries', {
32
58
  id: field.uuid().defaultRandom().primaryKey(),
33
59
  alertKey: field.text(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/infra/alerts/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/infra/alerts/schema.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import type { WebhookSignatureOptions } from '../webhook/sign.js';
2
2
  import type { Sink, SinkDelivery } from '../outbox/core.js';
3
- /** What a sink receives, and what the webhook sink POSTs as its body. */
4
- export interface AlertPayload {
5
- readonly kind: 'raise' | 'repeat' | 'resolve';
3
+ /** One alert's event, delivered at once. */
4
+ export interface AlertEventPayload {
5
+ readonly kind: 'raise' | 'repeat' | 'resolve' | 'reopen';
6
6
  readonly key: string;
7
7
  readonly severity: 'info' | 'warning' | 'error' | 'critical';
8
8
  readonly message: string;
@@ -11,13 +11,47 @@ export interface AlertPayload {
11
11
  readonly entity?: string;
12
12
  readonly entityId?: string;
13
13
  } | null;
14
+ readonly owner: string | null;
15
+ readonly runbook: string | null;
16
+ readonly context: Readonly<Record<string, unknown>> | null;
14
17
  readonly count: number;
18
+ /** Times a raise came after a resolve. */
19
+ readonly reopenCount: number;
15
20
  readonly firstSeenAt: string;
16
21
  readonly lastSeenAt: string;
17
22
  readonly resolvedAt: string | null;
23
+ readonly acknowledgedAt: string | null;
24
+ readonly acknowledgedBy: string | null;
25
+ /** On a `reopen`, those of the resolve it reopens. */
26
+ readonly resolvedBy: string | null;
27
+ readonly resolveNote: string | null;
28
+ readonly resolvedRelease: string | null;
29
+ readonly issueUrl: string | null;
30
+ readonly environment: string;
18
31
  /** The latest traces that raised it, newest first. */
19
32
  readonly traceIds: readonly string[];
20
33
  }
34
+ /** The alerts of the digest severities that changed in one window, sent once per sink. */
35
+ export interface AlertDigestPayload {
36
+ readonly kind: 'digest';
37
+ readonly key: 'pipework.alerts.digest';
38
+ readonly environment: string;
39
+ /** The previous digest's time; null on the first. */
40
+ readonly since: string | null;
41
+ readonly until: string;
42
+ readonly alerts: readonly {
43
+ readonly key: string;
44
+ readonly severity: 'info' | 'warning' | 'error' | 'critical';
45
+ readonly status: 'open' | 'acknowledged' | 'resolved';
46
+ readonly message: string;
47
+ readonly owner: string | null;
48
+ readonly count: number;
49
+ readonly reopenCount: number;
50
+ readonly lastSeenAt: string;
51
+ }[];
52
+ }
53
+ /** What a sink receives, and what the webhook sink POSTs as its body; tell them apart by `kind`. */
54
+ export type AlertPayload = AlertEventPayload | AlertDigestPayload;
21
55
  export type AlertDelivery = SinkDelivery<AlertPayload>;
22
56
  /** A place alerts are sent; see `Sink`. */
23
57
  export type AlertSink = Sink<AlertPayload>;
@@ -1 +1 @@
1
- {"version":3,"file":"sinks.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/sinks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE3D,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAA;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAA;IAC5D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC7G,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAED,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC,YAAY,CAAC,CAAA;AAEtD,2CAA2C;AAC3C,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAA;AAE1C,MAAM,WAAW,kBAAkB;IACjC,mFAAmF;IACnF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,kHAAkH;IAClH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,uBAAuB,CAAA;CAC3C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC,CAAC,CAAC,CA8BnH;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAAE,SAAQ,IAAI,CAAC,CAAC,CAAC;IAClG,yCAAyC;IACzC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAA;IACrC,KAAK,IAAI,IAAI,CAAA;CACd;AAED,+LAA+L;AAC/L,wBAAgB,UAAU,CAAC,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;AAC/H,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAAA"}
1
+ {"version":3,"file":"sinks.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/sinks.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sinks.js","sourceRoot":"","sources":["../../../src/infra/alerts/sinks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAkChD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAqD,MAA0B;IACxG,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAA;IAC5C,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wCAAwC,MAAM,CAAC,SAAS,CAAC,kHAAkH,CAAC,CAAA;IAC9L,CAAC;IACD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,SAAS;QAC9B,KAAK,CAAC,IAAI,CAAC,QAAQ;YACjB,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;YAC1G,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAA;YAC7D,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE;oBACvC,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,cAAc,EAAE,MAAM,CAAC,SAAS;wBAChC,qBAAqB,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;wBAClD,qBAAqB,EAAE,MAAM,CAAC,SAAS;qBACxC;oBACD,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,MAAM,EAAE,UAAU,CAAC,MAAM;iBAC1B,CAAC,CAAA;gBACF,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;gBACrC,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG;oBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAC1H,CAAC;oBAAS,CAAC;gBACT,YAAY,CAAC,KAAK,CAAC,CAAA;YACrB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAWD,MAAM,UAAU,UAAU,CAAC,UAA6B,EAAE;IACxD,MAAM,SAAS,GAA8C,EAAE,CAAA;IAC/D,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ;QAC9B,SAAS;QACT,0FAA0F;QAC1F,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA,CAAC,CAAC;QACjD,KAAK,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA,CAAC,CAAC;KACjC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"sinks.js","sourceRoot":"","sources":["../../../src/infra/alerts/sinks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAsEhD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAqD,MAA0B;IACxG,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAA;IAC5C,IAAI,SAAS,GAAG,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,wCAAwC,MAAM,CAAC,SAAS,CAAC,kHAAkH,CAAC,CAAA;IAC9L,CAAC;IACD,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,SAAS;QAC9B,KAAK,CAAC,IAAI,CAAC,QAAQ;YACjB,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;YAC1G,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAA;YAC7D,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE;oBACvC,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE;wBACP,cAAc,EAAE,kBAAkB;wBAClC,cAAc,EAAE,MAAM,CAAC,SAAS;wBAChC,qBAAqB,EAAE,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE;wBAClD,qBAAqB,EAAE,MAAM,CAAC,SAAS;qBACxC;oBACD,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,MAAM,EAAE,UAAU,CAAC,MAAM;iBAC1B,CAAC,CAAA;gBACF,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAA;gBACrC,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG;oBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAC1H,CAAC;oBAAS,CAAC;gBACT,YAAY,CAAC,KAAK,CAAC,CAAA;YACrB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAWD,MAAM,UAAU,UAAU,CAAC,UAA6B,EAAE;IACxD,MAAM,SAAS,GAA8C,EAAE,CAAA;IAC/D,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,QAAQ;QAC9B,SAAS;QACT,0FAA0F;QAC1F,KAAK,CAAC,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA,CAAC,CAAC;QACjD,KAAK,KAAK,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA,CAAC,CAAC;KACjC,CAAA;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/test/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,oCAAoC,CAAA;AAErF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAIvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAGnE,MAAM,WAAW,uBAAuB;IACtC,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,uBAAuB,CAAA;CAC5B;AASD,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CAyBjF;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB1F;AAoBD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAMhI;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,WAAW,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,aAAa,CAAC,EAAE,qBAAqB,GACpC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAM7D;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/test/plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,kBAAkB,EAAE,MAAM,oCAAoC,CAAA;AAErF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAA;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAA;AAIvD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAInE,MAAM,WAAW,uBAAuB;IACtC,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAAA;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,uBAAuB,CAAA;CAC5B;AAWD,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CA4BjF;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB1F;AA0BD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAMhI;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,QAAQ,EAClB,eAAe,EAAE,WAAW,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,aAAa,CAAC,EAAE,qBAAqB,GACpC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAM7D;AAED,OAAO,EAAE,YAAY,EAAE,CAAA"}
@@ -8,6 +8,7 @@ import { randomUUID } from 'node:crypto';
8
8
  import { createDebugFn, isObserverOnly } from '../data/db/instrumentation.js';
9
9
  import { markObservedConnection } from '../data/query/postgres-js/driver-error-boundary.js';
10
10
  import { collapseTransactionsToSavepoints } from './savepoints.js';
11
+ import { createSystemHandle } from './system-channel.js';
11
12
  const contextConnections = new Map();
12
13
  export async function beginTestIsolation(instance) {
13
14
  const dbConnections = {};
@@ -18,12 +19,13 @@ export async function beginTestIsolation(instance) {
18
19
  if (!testDb) {
19
20
  throw new Error(`[pipework] Test database not set up for "${name}". Did setupTestDatabases() run?`);
20
21
  }
21
- const conn = await createIsolatedConnection(testDb, connections, name, instance.config.observability);
22
+ const conn = await createIsolatedConnection(testDb, connections, name, instance.config.observability, instance.config.database(name).rls !== undefined);
22
23
  dbConnections[name] = conn;
23
24
  instance.pool.override(name, {
24
25
  name,
25
26
  client: connections.get(name).client,
26
27
  drizzle: conn,
28
+ ...(connections.get(name).system !== undefined ? { system: connections.get(name).system } : {}),
27
29
  async close() { },
28
30
  });
29
31
  }
@@ -55,15 +57,20 @@ export async function endTestIsolation(instance, ctx) {
55
57
  contextConnections.delete(ctx.id);
56
58
  instance.isolation.markEnd();
57
59
  }
58
- async function createIsolatedConnection(testDb, connections, name, observability) {
60
+ async function createIsolatedConnection(testDb, connections, name, observability, withSystem) {
59
61
  const debug = createDebugFn(observability);
60
62
  const client = postgres(testDb.url, { max: 1, onnotice: () => { }, ...(debug ? { debug } : {}) });
61
63
  if (isObserverOnly(observability))
62
64
  markObservedConnection(client);
63
65
  const db = drizzle(client);
64
66
  await db.execute(sql.raw('BEGIN'));
65
- collapseTransactionsToSavepoints(db, client);
66
- connections.set(name, { client, drizzle: db });
67
+ const join = collapseTransactionsToSavepoints(db, client);
68
+ let system;
69
+ if (withSystem) {
70
+ system = createSystemHandle(client);
71
+ join(system);
72
+ }
73
+ connections.set(name, { client, drizzle: db, ...(system !== undefined ? { system } : {}) });
67
74
  return db;
68
75
  }
69
76
  export function createTestContext(instance, testConnections, auth, tenant) {