@voyant-travel/action-ledger 0.104.10

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 (62) hide show
  1. package/LICENSE +201 -0
  2. package/dist/canary.d.ts +17 -0
  3. package/dist/canary.d.ts.map +1 -0
  4. package/dist/canary.js +77 -0
  5. package/dist/capability.d.ts +73 -0
  6. package/dist/capability.d.ts.map +1 -0
  7. package/dist/capability.js +206 -0
  8. package/dist/fingerprint.d.ts +26 -0
  9. package/dist/fingerprint.d.ts.map +1 -0
  10. package/dist/fingerprint.js +55 -0
  11. package/dist/index.d.ts +9 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +8 -0
  14. package/dist/request-context.d.ts +136 -0
  15. package/dist/request-context.d.ts.map +1 -0
  16. package/dist/request-context.js +237 -0
  17. package/dist/route-schemas.d.ts +745 -0
  18. package/dist/route-schemas.d.ts.map +1 -0
  19. package/dist/route-schemas.js +428 -0
  20. package/dist/routes.d.ts +1602 -0
  21. package/dist/routes.d.ts.map +1 -0
  22. package/dist/routes.js +271 -0
  23. package/dist/schema.d.ts +1759 -0
  24. package/dist/schema.d.ts.map +1 -0
  25. package/dist/schema.js +237 -0
  26. package/dist/service/approval-status.d.ts +3 -0
  27. package/dist/service/approval-status.d.ts.map +1 -0
  28. package/dist/service/approval-status.js +14 -0
  29. package/dist/service/cursors.d.ts +22 -0
  30. package/dist/service/cursors.d.ts.map +1 -0
  31. package/dist/service/cursors.js +48 -0
  32. package/dist/service/entries.d.ts +9 -0
  33. package/dist/service/entries.d.ts.map +1 -0
  34. package/dist/service/entries.js +75 -0
  35. package/dist/service/errors.d.ts +20 -0
  36. package/dist/service/errors.d.ts.map +1 -0
  37. package/dist/service/errors.js +36 -0
  38. package/dist/service/listing.d.ts +7 -0
  39. package/dist/service/listing.d.ts.map +1 -0
  40. package/dist/service/listing.js +77 -0
  41. package/dist/service/predicates.d.ts +8 -0
  42. package/dist/service/predicates.d.ts.map +1 -0
  43. package/dist/service/predicates.js +368 -0
  44. package/dist/service/records.d.ts +6 -0
  45. package/dist/service/records.d.ts.map +1 -0
  46. package/dist/service/records.js +51 -0
  47. package/dist/service/relay-lifecycle.d.ts +7 -0
  48. package/dist/service/relay-lifecycle.d.ts.map +1 -0
  49. package/dist/service/relay-lifecycle.js +78 -0
  50. package/dist/service/relay-outbox.d.ts +15 -0
  51. package/dist/service/relay-outbox.d.ts.map +1 -0
  52. package/dist/service/relay-outbox.js +15 -0
  53. package/dist/service/types.d.ts +249 -0
  54. package/dist/service/types.d.ts.map +1 -0
  55. package/dist/service/types.js +1 -0
  56. package/dist/service.d.ts +40 -0
  57. package/dist/service.d.ts.map +1 -0
  58. package/dist/service.js +283 -0
  59. package/dist/timeline.d.ts +67 -0
  60. package/dist/timeline.d.ts.map +1 -0
  61. package/dist/timeline.js +79 -0
  62. package/package.json +93 -0
@@ -0,0 +1,368 @@
1
+ import { and, eq, gt, gte, inArray, lt, lte, or, sql } from "drizzle-orm";
2
+ import { actionApprovals, actionDelegations, actionLedgerEntries, actionLedgerRelayOutbox, actionMutationDetails, actionSensitiveReadDetails, } from "../schema.js";
3
+ import { parseCursorDate } from "./cursors.js";
4
+ function riskCondition(value) {
5
+ if (value === undefined)
6
+ return undefined;
7
+ if (Array.isArray(value)) {
8
+ if (value.length === 0)
9
+ return undefined;
10
+ return inArray(actionLedgerEntries.evaluatedRisk, value);
11
+ }
12
+ return eq(actionLedgerEntries.evaluatedRisk, value);
13
+ }
14
+ function statusCondition(value) {
15
+ if (value === undefined)
16
+ return undefined;
17
+ if (Array.isArray(value)) {
18
+ if (value.length === 0)
19
+ return undefined;
20
+ return inArray(actionLedgerEntries.status, value);
21
+ }
22
+ return eq(actionLedgerEntries.status, value);
23
+ }
24
+ function approvalStatusCondition(value) {
25
+ if (value === undefined)
26
+ return undefined;
27
+ if (Array.isArray(value)) {
28
+ if (value.length === 0)
29
+ return undefined;
30
+ return inArray(actionApprovals.status, value);
31
+ }
32
+ return eq(actionApprovals.status, value);
33
+ }
34
+ function approvalRiskCondition(value) {
35
+ if (value === undefined)
36
+ return undefined;
37
+ if (Array.isArray(value)) {
38
+ if (value.length === 0)
39
+ return undefined;
40
+ return inArray(actionApprovals.riskSnapshot, value);
41
+ }
42
+ return eq(actionApprovals.riskSnapshot, value);
43
+ }
44
+ function reversalKindCondition(value) {
45
+ if (value === undefined)
46
+ return undefined;
47
+ if (Array.isArray(value)) {
48
+ if (value.length === 0)
49
+ return undefined;
50
+ return inArray(actionMutationDetails.reversalKind, value);
51
+ }
52
+ return eq(actionMutationDetails.reversalKind, value);
53
+ }
54
+ function reversalStateCondition(value) {
55
+ if (value === undefined)
56
+ return undefined;
57
+ if (Array.isArray(value)) {
58
+ if (value.length === 0)
59
+ return undefined;
60
+ return inArray(actionMutationDetails.reversalStateProjection, value);
61
+ }
62
+ return eq(actionMutationDetails.reversalStateProjection, value);
63
+ }
64
+ function reversalOutcomeCondition(value) {
65
+ if (value === undefined)
66
+ return undefined;
67
+ if (Array.isArray(value)) {
68
+ if (value.length === 0)
69
+ return undefined;
70
+ return inArray(actionMutationDetails.reversalOutcomeProjection, value);
71
+ }
72
+ return eq(actionMutationDetails.reversalOutcomeProjection, value);
73
+ }
74
+ function relayStatusCondition(value) {
75
+ if (value === undefined)
76
+ return undefined;
77
+ if (Array.isArray(value)) {
78
+ if (value.length === 0)
79
+ return undefined;
80
+ return inArray(actionLedgerRelayOutbox.relayStatus, value);
81
+ }
82
+ return eq(actionLedgerRelayOutbox.relayStatus, value);
83
+ }
84
+ function mutationDetailExists(condition) {
85
+ return sql `EXISTS (
86
+ SELECT 1
87
+ FROM ${actionMutationDetails}
88
+ WHERE ${actionMutationDetails.actionId} = ${actionLedgerEntries.id}
89
+ AND ${condition}
90
+ )`;
91
+ }
92
+ function sensitiveReadDetailExists(condition) {
93
+ return sql `EXISTS (
94
+ SELECT 1
95
+ FROM ${actionSensitiveReadDetails}
96
+ WHERE ${actionSensitiveReadDetails.actionId} = ${actionLedgerEntries.id}
97
+ AND ${condition}
98
+ )`;
99
+ }
100
+ function buildCursorCondition(cursor, sortDir = "desc") {
101
+ const occurredAt = parseCursorDate(cursor.occurredAt);
102
+ const compare = sortDir === "asc" ? gt : lt;
103
+ const tieBreaker = and(eq(actionLedgerEntries.occurredAt, occurredAt), compare(actionLedgerEntries.id, cursor.id));
104
+ return or(compare(actionLedgerEntries.occurredAt, occurredAt), tieBreaker);
105
+ }
106
+ function buildRelayOutboxCursorCondition(cursor) {
107
+ const createdAt = parseCursorDate(cursor.createdAt);
108
+ const tieBreaker = and(eq(actionLedgerRelayOutbox.createdAt, createdAt), lt(actionLedgerRelayOutbox.id, cursor.id));
109
+ return or(lt(actionLedgerRelayOutbox.createdAt, createdAt), tieBreaker);
110
+ }
111
+ function buildApprovalCursorCondition(cursor) {
112
+ const createdAt = parseCursorDate(cursor.createdAt);
113
+ const tieBreaker = and(eq(actionApprovals.createdAt, createdAt), lt(actionApprovals.id, cursor.id));
114
+ return or(lt(actionApprovals.createdAt, createdAt), tieBreaker);
115
+ }
116
+ function buildDelegationCursorCondition(cursor) {
117
+ const createdAt = parseCursorDate(cursor.createdAt);
118
+ const tieBreaker = and(eq(actionDelegations.createdAt, createdAt), lt(actionDelegations.id, cursor.id));
119
+ return or(lt(actionDelegations.createdAt, createdAt), tieBreaker);
120
+ }
121
+ function buildActionDelegationsPredicate(input) {
122
+ const conditions = [];
123
+ if (input.rootPrincipalType) {
124
+ conditions.push(eq(actionDelegations.rootPrincipalType, input.rootPrincipalType));
125
+ }
126
+ if (input.rootPrincipalId) {
127
+ conditions.push(eq(actionDelegations.rootPrincipalId, input.rootPrincipalId));
128
+ }
129
+ if (input.parentPrincipalType) {
130
+ conditions.push(eq(actionDelegations.parentPrincipalType, input.parentPrincipalType));
131
+ }
132
+ if (input.parentPrincipalId) {
133
+ conditions.push(eq(actionDelegations.parentPrincipalId, input.parentPrincipalId));
134
+ }
135
+ if (input.childPrincipalType) {
136
+ conditions.push(eq(actionDelegations.childPrincipalType, input.childPrincipalType));
137
+ }
138
+ if (input.childPrincipalId) {
139
+ conditions.push(eq(actionDelegations.childPrincipalId, input.childPrincipalId));
140
+ }
141
+ if (input.grantSource)
142
+ conditions.push(eq(actionDelegations.grantSource, input.grantSource));
143
+ if (input.capabilityScopeRef) {
144
+ conditions.push(eq(actionDelegations.capabilityScopeRef, input.capabilityScopeRef));
145
+ }
146
+ if (input.budgetScopeRef) {
147
+ conditions.push(eq(actionDelegations.budgetScopeRef, input.budgetScopeRef));
148
+ }
149
+ if (input.expiresAtFrom) {
150
+ conditions.push(gte(actionDelegations.expiresAt, parseCursorDate(input.expiresAtFrom)));
151
+ }
152
+ if (input.expiresAtTo) {
153
+ conditions.push(lte(actionDelegations.expiresAt, parseCursorDate(input.expiresAtTo)));
154
+ }
155
+ if (input.createdAtFrom) {
156
+ conditions.push(gte(actionDelegations.createdAt, parseCursorDate(input.createdAtFrom)));
157
+ }
158
+ if (input.createdAtTo) {
159
+ conditions.push(lte(actionDelegations.createdAt, parseCursorDate(input.createdAtTo)));
160
+ }
161
+ if (input.cursor) {
162
+ conditions.push(buildDelegationCursorCondition(input.cursor));
163
+ }
164
+ if (conditions.length === 0)
165
+ return undefined;
166
+ if (conditions.length === 1)
167
+ return conditions[0];
168
+ return and(...conditions);
169
+ }
170
+ function buildActionApprovalsPredicate(input) {
171
+ const conditions = [];
172
+ if (input.requestedActionId) {
173
+ conditions.push(eq(actionApprovals.requestedActionId, input.requestedActionId));
174
+ }
175
+ const entryStatusCondition = approvalStatusCondition(input.status);
176
+ if (entryStatusCondition)
177
+ conditions.push(entryStatusCondition);
178
+ if (input.requestedByPrincipalId) {
179
+ conditions.push(eq(actionApprovals.requestedByPrincipalId, input.requestedByPrincipalId));
180
+ }
181
+ if (input.assignedToPrincipalId) {
182
+ conditions.push(eq(actionApprovals.assignedToPrincipalId, input.assignedToPrincipalId));
183
+ }
184
+ if (input.decidedByPrincipalId) {
185
+ conditions.push(eq(actionApprovals.decidedByPrincipalId, input.decidedByPrincipalId));
186
+ }
187
+ if (input.delegatedFromPrincipalId) {
188
+ conditions.push(eq(actionApprovals.delegatedFromPrincipalId, input.delegatedFromPrincipalId));
189
+ }
190
+ if (input.policyName)
191
+ conditions.push(eq(actionApprovals.policyName, input.policyName));
192
+ if (input.policyVersion)
193
+ conditions.push(eq(actionApprovals.policyVersion, input.policyVersion));
194
+ const riskSnapshotCondition = approvalRiskCondition(input.riskSnapshot);
195
+ if (riskSnapshotCondition)
196
+ conditions.push(riskSnapshotCondition);
197
+ if (input.reasonCode)
198
+ conditions.push(eq(actionApprovals.reasonCode, input.reasonCode));
199
+ if (input.expiresAtFrom) {
200
+ conditions.push(gte(actionApprovals.expiresAt, parseCursorDate(input.expiresAtFrom)));
201
+ }
202
+ if (input.expiresAtTo) {
203
+ conditions.push(lte(actionApprovals.expiresAt, parseCursorDate(input.expiresAtTo)));
204
+ }
205
+ if (input.decidedAtFrom) {
206
+ conditions.push(gte(actionApprovals.decidedAt, parseCursorDate(input.decidedAtFrom)));
207
+ }
208
+ if (input.decidedAtTo) {
209
+ conditions.push(lte(actionApprovals.decidedAt, parseCursorDate(input.decidedAtTo)));
210
+ }
211
+ if (input.createdAtFrom) {
212
+ conditions.push(gte(actionApprovals.createdAt, parseCursorDate(input.createdAtFrom)));
213
+ }
214
+ if (input.createdAtTo) {
215
+ conditions.push(lte(actionApprovals.createdAt, parseCursorDate(input.createdAtTo)));
216
+ }
217
+ if (input.cursor) {
218
+ conditions.push(buildApprovalCursorCondition(input.cursor));
219
+ }
220
+ if (conditions.length === 0)
221
+ return undefined;
222
+ if (conditions.length === 1)
223
+ return conditions[0];
224
+ return and(...conditions);
225
+ }
226
+ function buildActionLedgerRelayOutboxPredicate(input) {
227
+ const conditions = [];
228
+ if (input.actionId)
229
+ conditions.push(eq(actionLedgerRelayOutbox.actionId, input.actionId));
230
+ if (input.organizationId) {
231
+ conditions.push(eq(actionLedgerRelayOutbox.organizationId, input.organizationId));
232
+ }
233
+ const entryRelayStatusCondition = relayStatusCondition(input.relayStatus);
234
+ if (entryRelayStatusCondition)
235
+ conditions.push(entryRelayStatusCondition);
236
+ if (input.dueBefore) {
237
+ conditions.push(lte(actionLedgerRelayOutbox.nextRetryAt, parseCursorDate(input.dueBefore)));
238
+ }
239
+ if (input.createdAtFrom) {
240
+ conditions.push(gte(actionLedgerRelayOutbox.createdAt, parseCursorDate(input.createdAtFrom)));
241
+ }
242
+ if (input.createdAtTo) {
243
+ conditions.push(lte(actionLedgerRelayOutbox.createdAt, parseCursorDate(input.createdAtTo)));
244
+ }
245
+ if (input.processedAtFrom) {
246
+ conditions.push(gte(actionLedgerRelayOutbox.processedAt, parseCursorDate(input.processedAtFrom)));
247
+ }
248
+ if (input.processedAtTo) {
249
+ conditions.push(lte(actionLedgerRelayOutbox.processedAt, parseCursorDate(input.processedAtTo)));
250
+ }
251
+ if (input.cursor) {
252
+ conditions.push(buildRelayOutboxCursorCondition(input.cursor));
253
+ }
254
+ if (conditions.length === 0)
255
+ return undefined;
256
+ if (conditions.length === 1)
257
+ return conditions[0];
258
+ return and(...conditions);
259
+ }
260
+ function buildActionLedgerEntriesPredicate(input) {
261
+ const conditions = [];
262
+ if (input.actionName)
263
+ conditions.push(eq(actionLedgerEntries.actionName, input.actionName));
264
+ if (input.actionKind)
265
+ conditions.push(eq(actionLedgerEntries.actionKind, input.actionKind));
266
+ if (input.actorType)
267
+ conditions.push(eq(actionLedgerEntries.actorType, input.actorType));
268
+ if (input.principalType) {
269
+ conditions.push(eq(actionLedgerEntries.principalType, input.principalType));
270
+ }
271
+ if (input.principalId)
272
+ conditions.push(eq(actionLedgerEntries.principalId, input.principalId));
273
+ if (input.apiTokenId)
274
+ conditions.push(eq(actionLedgerEntries.apiTokenId, input.apiTokenId));
275
+ if (input.sessionId)
276
+ conditions.push(eq(actionLedgerEntries.sessionId, input.sessionId));
277
+ if (input.callerType)
278
+ conditions.push(eq(actionLedgerEntries.callerType, input.callerType));
279
+ if (input.organizationId) {
280
+ conditions.push(eq(actionLedgerEntries.organizationId, input.organizationId));
281
+ }
282
+ if (input.targetType)
283
+ conditions.push(eq(actionLedgerEntries.targetType, input.targetType));
284
+ if (input.targetId)
285
+ conditions.push(eq(actionLedgerEntries.targetId, input.targetId));
286
+ if (input.targetIds && input.targetIds.length > 0) {
287
+ conditions.push(inArray(actionLedgerEntries.targetId, input.targetIds));
288
+ }
289
+ if (input.routeOrToolName) {
290
+ conditions.push(eq(actionLedgerEntries.routeOrToolName, input.routeOrToolName));
291
+ }
292
+ if (input.workflowRunId) {
293
+ conditions.push(eq(actionLedgerEntries.workflowRunId, input.workflowRunId));
294
+ }
295
+ if (input.workflowStepId) {
296
+ conditions.push(eq(actionLedgerEntries.workflowStepId, input.workflowStepId));
297
+ }
298
+ if (input.correlationId) {
299
+ conditions.push(eq(actionLedgerEntries.correlationId, input.correlationId));
300
+ }
301
+ if (input.causationActionId) {
302
+ conditions.push(eq(actionLedgerEntries.causationActionId, input.causationActionId));
303
+ }
304
+ if (input.capabilityId)
305
+ conditions.push(eq(actionLedgerEntries.capabilityId, input.capabilityId));
306
+ if (input.capabilityVersion) {
307
+ conditions.push(eq(actionLedgerEntries.capabilityVersion, input.capabilityVersion));
308
+ }
309
+ if (input.authorizationSource) {
310
+ conditions.push(eq(actionLedgerEntries.authorizationSource, input.authorizationSource));
311
+ }
312
+ if (input.approvalId)
313
+ conditions.push(eq(actionLedgerEntries.approvalId, input.approvalId));
314
+ if (input.amendsActionId) {
315
+ conditions.push(eq(actionLedgerEntries.amendsActionId, input.amendsActionId));
316
+ }
317
+ if (input.idempotencyScope) {
318
+ conditions.push(eq(actionLedgerEntries.idempotencyScope, input.idempotencyScope));
319
+ }
320
+ if (input.idempotencyKey) {
321
+ conditions.push(eq(actionLedgerEntries.idempotencyKey, input.idempotencyKey));
322
+ }
323
+ const evaluatedRiskCondition = riskCondition(input.evaluatedRisk);
324
+ if (evaluatedRiskCondition)
325
+ conditions.push(evaluatedRiskCondition);
326
+ const entryStatusCondition = statusCondition(input.status);
327
+ if (entryStatusCondition)
328
+ conditions.push(entryStatusCondition);
329
+ const entryReversalKindCondition = reversalKindCondition(input.reversalKind);
330
+ if (entryReversalKindCondition) {
331
+ conditions.push(mutationDetailExists(entryReversalKindCondition));
332
+ }
333
+ const entryReversalStateCondition = reversalStateCondition(input.reversalState);
334
+ if (entryReversalStateCondition) {
335
+ conditions.push(mutationDetailExists(entryReversalStateCondition));
336
+ }
337
+ const entryReversalOutcomeCondition = reversalOutcomeCondition(input.reversalOutcome);
338
+ if (entryReversalOutcomeCondition) {
339
+ conditions.push(mutationDetailExists(entryReversalOutcomeCondition));
340
+ }
341
+ if (input.reversesActionId) {
342
+ conditions.push(mutationDetailExists(eq(actionMutationDetails.reversesActionId, input.reversesActionId)));
343
+ }
344
+ if (input.reversedByActionId) {
345
+ conditions.push(mutationDetailExists(eq(actionMutationDetails.reversedByActionIdProjection, input.reversedByActionId)));
346
+ }
347
+ if (input.sensitiveReasonCode) {
348
+ conditions.push(sensitiveReadDetailExists(eq(actionSensitiveReadDetails.reasonCode, input.sensitiveReasonCode)));
349
+ }
350
+ if (input.decisionPolicy) {
351
+ conditions.push(sensitiveReadDetailExists(eq(actionSensitiveReadDetails.decisionPolicy, input.decisionPolicy)));
352
+ }
353
+ if (input.occurredAtFrom) {
354
+ conditions.push(gte(actionLedgerEntries.occurredAt, parseCursorDate(input.occurredAtFrom)));
355
+ }
356
+ if (input.occurredAtTo) {
357
+ conditions.push(lte(actionLedgerEntries.occurredAt, parseCursorDate(input.occurredAtTo)));
358
+ }
359
+ if (input.cursor) {
360
+ conditions.push(buildCursorCondition(input.cursor, input.sortDir));
361
+ }
362
+ if (conditions.length === 0)
363
+ return undefined;
364
+ if (conditions.length === 1)
365
+ return conditions[0];
366
+ return and(...conditions);
367
+ }
368
+ export { buildActionApprovalsPredicate, buildActionDelegationsPredicate, buildActionLedgerEntriesPredicate, buildActionLedgerRelayOutboxPredicate, };
@@ -0,0 +1,6 @@
1
+ import type { AnyDrizzleDb } from "@voyant-travel/db";
2
+ import type { GetActionApprovalResult, GetActionDelegationResult, GetActionLedgerEntryResult } from "./types.js";
3
+ export declare function getEntry(db: AnyDrizzleDb, id: string): Promise<GetActionLedgerEntryResult | null>;
4
+ export declare function getApproval(db: AnyDrizzleDb, id: string): Promise<GetActionApprovalResult | null>;
5
+ export declare function getDelegation(db: AnyDrizzleDb, id: string): Promise<GetActionDelegationResult | null>;
6
+ //# sourceMappingURL=records.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../src/service/records.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAYrD,OAAO,KAAK,EACV,uBAAuB,EACvB,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,YAAY,CAAA;AAEnB,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CA2B5C;AAED,wBAAsB,WAAW,CAC/B,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAazC;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAS3C"}
@@ -0,0 +1,51 @@
1
+ import { eq } from "drizzle-orm";
2
+ import { actionApprovals, actionDelegations, actionLedgerEntries, actionLedgerPayloads, actionLedgerRelayOutbox, actionMutationDetails, actionSensitiveReadDetails, } from "../schema.js";
3
+ export async function getEntry(db, id) {
4
+ const [entry] = await db
5
+ .select()
6
+ .from(actionLedgerEntries)
7
+ .where(eq(actionLedgerEntries.id, id))
8
+ .limit(1);
9
+ if (!entry)
10
+ return null;
11
+ const [[mutationDetail], [sensitiveReadDetail], payloads, relayOutbox] = await Promise.all([
12
+ db.select().from(actionMutationDetails).where(eq(actionMutationDetails.actionId, id)).limit(1),
13
+ db
14
+ .select()
15
+ .from(actionSensitiveReadDetails)
16
+ .where(eq(actionSensitiveReadDetails.actionId, id))
17
+ .limit(1),
18
+ db.select().from(actionLedgerPayloads).where(eq(actionLedgerPayloads.actionId, id)),
19
+ db.select().from(actionLedgerRelayOutbox).where(eq(actionLedgerRelayOutbox.actionId, id)),
20
+ ]);
21
+ return {
22
+ entry,
23
+ mutationDetail: mutationDetail ?? null,
24
+ sensitiveReadDetail: sensitiveReadDetail ?? null,
25
+ payloads,
26
+ relayOutbox,
27
+ };
28
+ }
29
+ export async function getApproval(db, id) {
30
+ const [approval] = await db
31
+ .select()
32
+ .from(actionApprovals)
33
+ .where(eq(actionApprovals.id, id))
34
+ .limit(1);
35
+ if (!approval)
36
+ return null;
37
+ return {
38
+ approval,
39
+ requestedAction: await getEntry(db, approval.requestedActionId),
40
+ };
41
+ }
42
+ export async function getDelegation(db, id) {
43
+ const [delegation] = await db
44
+ .select()
45
+ .from(actionDelegations)
46
+ .where(eq(actionDelegations.id, id))
47
+ .limit(1);
48
+ if (!delegation)
49
+ return null;
50
+ return { delegation };
51
+ }
@@ -0,0 +1,7 @@
1
+ import type { AnyDrizzleDb } from "@voyant-travel/db";
2
+ import { type ActionLedgerRelayOutbox } from "../schema.js";
3
+ import type { ClaimActionLedgerRelayOutboxInput, ClaimActionLedgerRelayOutboxResult, MarkActionLedgerRelayOutboxFailedInput, MarkActionLedgerRelayOutboxSucceededInput } from "./types.js";
4
+ export declare function claimRelayOutbox(db: AnyDrizzleDb, input?: ClaimActionLedgerRelayOutboxInput): Promise<ClaimActionLedgerRelayOutboxResult>;
5
+ export declare function markRelayOutboxSucceeded(db: AnyDrizzleDb, input: MarkActionLedgerRelayOutboxSucceededInput): Promise<ActionLedgerRelayOutbox | null>;
6
+ export declare function markRelayOutboxFailed(db: AnyDrizzleDb, input: MarkActionLedgerRelayOutboxFailedInput): Promise<ActionLedgerRelayOutbox | null>;
7
+ //# sourceMappingURL=relay-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-lifecycle.d.ts","sourceRoot":"","sources":["../../src/service/relay-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrD,OAAO,EAAE,KAAK,uBAAuB,EAA2B,MAAM,cAAc,CAAA;AAMpF,OAAO,KAAK,EACV,iCAAiC,EACjC,kCAAkC,EAClC,sCAAsC,EACtC,yCAAyC,EAC1C,MAAM,YAAY,CAAA;AAEnB,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,YAAY,EAChB,KAAK,GAAE,iCAAsC,GAC5C,OAAO,CAAC,kCAAkC,CAAC,CAuC7C;AAED,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,yCAAyC,GAC/C,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAkBzC;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,sCAAsC,GAC5C,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CA2BzC"}
@@ -0,0 +1,78 @@
1
+ import { and, eq, sql } from "drizzle-orm";
2
+ import { actionLedgerRelayOutbox } from "../schema.js";
3
+ import { normalizeListLimit, parseCursorDate } from "./cursors.js";
4
+ import { actionLedgerRelayOutboxFromSqlRow, } from "./relay-outbox.js";
5
+ export async function claimRelayOutbox(db, input = {}) {
6
+ const limit = normalizeListLimit(input.limit);
7
+ const dueAt = input.dueAt ? parseCursorDate(input.dueAt) : new Date();
8
+ const organizationId = input.organizationId ?? null;
9
+ const result = await db.execute(sql `
10
+ WITH due AS (
11
+ SELECT id
12
+ FROM action_ledger_outbox
13
+ WHERE relay_status IN ('pending', 'failed')
14
+ AND (${organizationId}::text IS NULL OR organization_id = ${organizationId})
15
+ AND (next_retry_at IS NULL OR next_retry_at <= ${dueAt})
16
+ ORDER BY created_at ASC, id ASC
17
+ LIMIT ${limit}
18
+ FOR UPDATE SKIP LOCKED
19
+ )
20
+ UPDATE action_ledger_outbox AS outbox
21
+ SET relay_status = 'processing',
22
+ attempt_count = outbox.attempt_count + 1,
23
+ last_error = NULL,
24
+ processed_at = NULL
25
+ FROM due
26
+ WHERE outbox.id = due.id
27
+ RETURNING
28
+ outbox.id,
29
+ outbox.action_id,
30
+ outbox.organization_id,
31
+ outbox.relay_status,
32
+ outbox.payload_ref,
33
+ outbox.attempt_count,
34
+ outbox.next_retry_at,
35
+ outbox.last_error,
36
+ outbox.created_at,
37
+ outbox.processed_at
38
+ `);
39
+ const rows = ("rows" in result ? result.rows : result);
40
+ return {
41
+ rows: rows.map(actionLedgerRelayOutboxFromSqlRow),
42
+ };
43
+ }
44
+ export async function markRelayOutboxSucceeded(db, input) {
45
+ const [row] = await db
46
+ .update(actionLedgerRelayOutbox)
47
+ .set({
48
+ relayStatus: "succeeded",
49
+ nextRetryAt: null,
50
+ lastError: null,
51
+ processedAt: input.processedAt ? parseCursorDate(input.processedAt) : new Date(),
52
+ })
53
+ .where(and(eq(actionLedgerRelayOutbox.id, input.id), eq(actionLedgerRelayOutbox.relayStatus, "processing")))
54
+ .returning();
55
+ return row ?? null;
56
+ }
57
+ export async function markRelayOutboxFailed(db, input) {
58
+ const deadLetter = input.deadLetter ?? false;
59
+ const [row] = await db
60
+ .update(actionLedgerRelayOutbox)
61
+ .set({
62
+ relayStatus: deadLetter ? "dead_letter" : "failed",
63
+ nextRetryAt: deadLetter
64
+ ? null
65
+ : input.nextRetryAt
66
+ ? parseCursorDate(input.nextRetryAt)
67
+ : null,
68
+ lastError: input.lastError,
69
+ processedAt: deadLetter
70
+ ? input.processedAt
71
+ ? parseCursorDate(input.processedAt)
72
+ : new Date()
73
+ : null,
74
+ })
75
+ .where(and(eq(actionLedgerRelayOutbox.id, input.id), eq(actionLedgerRelayOutbox.relayStatus, "processing")))
76
+ .returning();
77
+ return row ?? null;
78
+ }
@@ -0,0 +1,15 @@
1
+ import type { ActionLedgerRelayOutbox } from "../schema.js";
2
+ export type ActionLedgerRelayOutboxSqlRow = {
3
+ id: string;
4
+ action_id: string;
5
+ organization_id: string | null;
6
+ relay_status: ActionLedgerRelayOutbox["relayStatus"];
7
+ payload_ref: string | null;
8
+ attempt_count: number | string;
9
+ next_retry_at: Date | string | null;
10
+ last_error: string | null;
11
+ created_at: Date | string;
12
+ processed_at: Date | string | null;
13
+ };
14
+ export declare function actionLedgerRelayOutboxFromSqlRow(row: ActionLedgerRelayOutboxSqlRow): ActionLedgerRelayOutbox;
15
+ //# sourceMappingURL=relay-outbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-outbox.d.ts","sourceRoot":"","sources":["../../src/service/relay-outbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAA;AAG3D,MAAM,MAAM,6BAA6B,GAAG;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,YAAY,EAAE,uBAAuB,CAAC,aAAa,CAAC,CAAA;IACpD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,aAAa,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,aAAa,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,EAAE,IAAI,GAAG,MAAM,CAAA;IACzB,YAAY,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAAA;CACnC,CAAA;AAED,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,6BAA6B,GACjC,uBAAuB,CAazB"}
@@ -0,0 +1,15 @@
1
+ import { parseCursorDate } from "./cursors.js";
2
+ export function actionLedgerRelayOutboxFromSqlRow(row) {
3
+ return {
4
+ id: row.id,
5
+ actionId: row.action_id,
6
+ organizationId: row.organization_id,
7
+ relayStatus: row.relay_status,
8
+ payloadRef: row.payload_ref,
9
+ attemptCount: Number(row.attempt_count),
10
+ nextRetryAt: row.next_retry_at ? parseCursorDate(row.next_retry_at) : null,
11
+ lastError: row.last_error,
12
+ createdAt: parseCursorDate(row.created_at),
13
+ processedAt: row.processed_at ? parseCursorDate(row.processed_at) : null,
14
+ };
15
+ }