@aletheia-dev/core 0.1.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/CHANGELOG.md +10 -0
- package/LICENSE +202 -0
- package/README.md +18 -0
- package/dist/index.cjs +1635 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2691 -0
- package/dist/index.d.ts +2691 -0
- package/dist/index.js +1442 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-DFA8nkvG.d.cts +15 -0
- package/dist/logger-DFA8nkvG.d.ts +15 -0
- package/dist/node.cjs +179 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +86 -0
- package/dist/node.d.ts +86 -0
- package/dist/node.js +138 -0
- package/dist/node.js.map +1 -0
- package/package.json +61 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1442 @@
|
|
|
1
|
+
// src/base.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var Id = z.guid();
|
|
4
|
+
var JsonObject = z.record(z.string(), z.unknown());
|
|
5
|
+
var Timestamps = z.object({
|
|
6
|
+
createdAt: z.coerce.date(),
|
|
7
|
+
updatedAt: z.coerce.date()
|
|
8
|
+
});
|
|
9
|
+
var BaseEntity = z.object({ id: Id, tenantId: Id, ...Timestamps.shape });
|
|
10
|
+
var DefinitionStatus = z.enum(["draft", "pending_approval", "published", "archived"]);
|
|
11
|
+
var DefinitionKey = z.string().min(1).max(100).regex(/^[a-z0-9][a-z0-9_-]*$/, 'keys are lowercase letters, digits, "_" or "-"');
|
|
12
|
+
|
|
13
|
+
// src/tenant.ts
|
|
14
|
+
import { z as z2 } from "zod";
|
|
15
|
+
var ActorType = z2.enum(["user", "service", "applicant", "system", "plugin", "workflow"]);
|
|
16
|
+
var Actor = z2.object({ type: ActorType, id: z2.string().min(1) });
|
|
17
|
+
var TenantContext = z2.object({ tenantId: Id, actor: Actor });
|
|
18
|
+
var SYSTEM_ACTOR = { type: "system", id: "system" };
|
|
19
|
+
var DEV_TENANT_ID = "00000000-0000-0000-0000-000000000001";
|
|
20
|
+
var WebOrigin = z2.string().regex(/^https?:\/\/[a-z0-9.-]+(:\d{1,5})?$/i, "must be an origin like https://merchant.example");
|
|
21
|
+
var CaseSettings = z2.object({
|
|
22
|
+
/** SLA applied to cases whose `create_case` step sets no `slaHours`. */
|
|
23
|
+
defaultSlaHours: z2.number().positive().max(24 * 90).optional()
|
|
24
|
+
});
|
|
25
|
+
var ApprovalSettings = z2.object({
|
|
26
|
+
/** When true, drafts are published only through an approval. */
|
|
27
|
+
required: z2.boolean().default(false),
|
|
28
|
+
/** When approvals are required, the requester may not approve their own change. */
|
|
29
|
+
fourEyes: z2.boolean().default(true)
|
|
30
|
+
});
|
|
31
|
+
var TenantSettings = z2.object({
|
|
32
|
+
/** Merchant origins allowed to embed this tenant's collection flows in an iframe. */
|
|
33
|
+
embedOrigins: z2.array(WebOrigin).max(20).default([]),
|
|
34
|
+
cases: CaseSettings.default({}),
|
|
35
|
+
approvals: ApprovalSettings.default({ required: false, fourEyes: true })
|
|
36
|
+
});
|
|
37
|
+
var Tenant = z2.object({
|
|
38
|
+
id: Id,
|
|
39
|
+
name: z2.string().min(1),
|
|
40
|
+
settings: TenantSettings.default({
|
|
41
|
+
embedOrigins: [],
|
|
42
|
+
cases: {},
|
|
43
|
+
approvals: { required: false, fourEyes: true }
|
|
44
|
+
}),
|
|
45
|
+
createdAt: z2.coerce.date()
|
|
46
|
+
});
|
|
47
|
+
function systemContext(tenantId) {
|
|
48
|
+
return { tenantId, actor: SYSTEM_ACTOR };
|
|
49
|
+
}
|
|
50
|
+
var DirectoryUser = z2.object({
|
|
51
|
+
id: z2.string().min(1),
|
|
52
|
+
name: z2.string().min(1),
|
|
53
|
+
email: z2.string().optional(),
|
|
54
|
+
/** Project roles the user holds, e.g. `analyst`. */
|
|
55
|
+
roles: z2.array(z2.string())
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// src/condition.ts
|
|
59
|
+
import { z as z3 } from "zod";
|
|
60
|
+
var ConditionOp = z3.enum(["eq", "neq", "gt", "gte", "lt", "lte", "in", "exists"]);
|
|
61
|
+
var Condition = z3.object({
|
|
62
|
+
path: z3.string().min(1),
|
|
63
|
+
op: ConditionOp,
|
|
64
|
+
value: z3.unknown().optional()
|
|
65
|
+
});
|
|
66
|
+
function getPath(source, path) {
|
|
67
|
+
let current = source;
|
|
68
|
+
for (const segment of path.split(".")) {
|
|
69
|
+
if (current === null || typeof current !== "object") return void 0;
|
|
70
|
+
current = current[segment];
|
|
71
|
+
}
|
|
72
|
+
return current;
|
|
73
|
+
}
|
|
74
|
+
function compareNumbers(actual, expected, op) {
|
|
75
|
+
const a = typeof actual === "number" ? actual : Number(actual);
|
|
76
|
+
const b = typeof expected === "number" ? expected : Number(expected);
|
|
77
|
+
if (Number.isNaN(a) || Number.isNaN(b)) return false;
|
|
78
|
+
switch (op) {
|
|
79
|
+
case "gt":
|
|
80
|
+
return a > b;
|
|
81
|
+
case "gte":
|
|
82
|
+
return a >= b;
|
|
83
|
+
case "lt":
|
|
84
|
+
return a < b;
|
|
85
|
+
case "lte":
|
|
86
|
+
return a <= b;
|
|
87
|
+
default:
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function evaluateCondition(condition, data) {
|
|
92
|
+
const actual = getPath(data, condition.path);
|
|
93
|
+
switch (condition.op) {
|
|
94
|
+
case "exists":
|
|
95
|
+
return actual !== void 0 && actual !== null;
|
|
96
|
+
case "eq":
|
|
97
|
+
return actual === condition.value;
|
|
98
|
+
case "neq":
|
|
99
|
+
return actual !== condition.value;
|
|
100
|
+
case "in":
|
|
101
|
+
return Array.isArray(condition.value) && condition.value.includes(actual);
|
|
102
|
+
case "gt":
|
|
103
|
+
case "gte":
|
|
104
|
+
case "lt":
|
|
105
|
+
case "lte":
|
|
106
|
+
return compareNumbers(actual, condition.value, condition.op);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/subject.ts
|
|
111
|
+
import { z as z4 } from "zod";
|
|
112
|
+
var SubjectKind = z4.enum(["merchant", "seller", "user"]);
|
|
113
|
+
var SubjectStatus = z4.enum(["active", "blocked", "closed"]);
|
|
114
|
+
var Subject = BaseEntity.extend({
|
|
115
|
+
kind: SubjectKind,
|
|
116
|
+
externalId: z4.string().nullish(),
|
|
117
|
+
status: SubjectStatus,
|
|
118
|
+
data: JsonObject,
|
|
119
|
+
riskScore: z4.number().nullish(),
|
|
120
|
+
tags: z4.array(z4.string())
|
|
121
|
+
});
|
|
122
|
+
var CreateSubjectInput = z4.object({
|
|
123
|
+
kind: SubjectKind,
|
|
124
|
+
externalId: z4.string().min(1).optional(),
|
|
125
|
+
data: JsonObject.default({}),
|
|
126
|
+
tags: z4.array(z4.string()).default([])
|
|
127
|
+
});
|
|
128
|
+
var SubjectListQuery = z4.object({
|
|
129
|
+
search: z4.string().min(1).max(200).optional(),
|
|
130
|
+
kind: SubjectKind.optional(),
|
|
131
|
+
status: SubjectStatus.optional(),
|
|
132
|
+
riskScoreMin: z4.coerce.number().min(0).max(100).optional(),
|
|
133
|
+
riskScoreMax: z4.coerce.number().min(0).max(100).optional(),
|
|
134
|
+
limit: z4.coerce.number().int().positive().optional(),
|
|
135
|
+
offset: z4.coerce.number().int().nonnegative().optional()
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// src/rule.ts
|
|
139
|
+
import { z as z5 } from "zod";
|
|
140
|
+
var RuleType = z5.enum([
|
|
141
|
+
"comparison",
|
|
142
|
+
"list_lookup",
|
|
143
|
+
"score_threshold",
|
|
144
|
+
"expression",
|
|
145
|
+
"plugin",
|
|
146
|
+
"velocity"
|
|
147
|
+
]);
|
|
148
|
+
var RuleSeverity = z5.enum(["info", "warn", "block"]);
|
|
149
|
+
var RuleDefinition = BaseEntity.extend({
|
|
150
|
+
/** Actor id that created this version; null for rows older than PR 19. */
|
|
151
|
+
createdBy: z5.string().nullish(),
|
|
152
|
+
key: DefinitionKey,
|
|
153
|
+
version: z5.number().int().positive(),
|
|
154
|
+
name: z5.string().min(1),
|
|
155
|
+
description: z5.string().nullish(),
|
|
156
|
+
type: RuleType,
|
|
157
|
+
config: z5.unknown(),
|
|
158
|
+
severity: RuleSeverity,
|
|
159
|
+
weight: z5.number().nullish(),
|
|
160
|
+
enabled: z5.boolean(),
|
|
161
|
+
tags: z5.array(z5.string()),
|
|
162
|
+
status: DefinitionStatus
|
|
163
|
+
});
|
|
164
|
+
var UpsertRuleDefinitionInput = z5.object({
|
|
165
|
+
name: z5.string().min(1),
|
|
166
|
+
description: z5.string().optional(),
|
|
167
|
+
type: RuleType,
|
|
168
|
+
config: z5.unknown(),
|
|
169
|
+
severity: RuleSeverity.default("block"),
|
|
170
|
+
weight: z5.number().optional(),
|
|
171
|
+
enabled: z5.boolean().default(true),
|
|
172
|
+
tags: z5.array(z5.string()).default([])
|
|
173
|
+
});
|
|
174
|
+
var RuleOutcome = z5.enum(["pass", "fail", "error", "skipped"]);
|
|
175
|
+
var RuleEvaluationResult = z5.object({
|
|
176
|
+
ruleId: z5.string(),
|
|
177
|
+
ruleKey: z5.string(),
|
|
178
|
+
ruleVersion: z5.number().int(),
|
|
179
|
+
severity: RuleSeverity,
|
|
180
|
+
weight: z5.number().nullish(),
|
|
181
|
+
outcome: RuleOutcome,
|
|
182
|
+
score: z5.number().nullish(),
|
|
183
|
+
reasons: z5.array(z5.string()),
|
|
184
|
+
details: z5.unknown().optional(),
|
|
185
|
+
durationMs: z5.number().nonnegative(),
|
|
186
|
+
/** Evaluated as a shadow rule of a rule set: recorded, but excluded from aggregation. */
|
|
187
|
+
shadow: z5.boolean().optional()
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// src/decision.ts
|
|
191
|
+
import { z as z6 } from "zod";
|
|
192
|
+
var DecisionOutcome = z6.enum(["approve", "reject", "manual_review"]);
|
|
193
|
+
var DecisionReason = z6.object({
|
|
194
|
+
code: z6.string().min(1),
|
|
195
|
+
message: z6.string(),
|
|
196
|
+
ruleKey: z6.string().optional()
|
|
197
|
+
});
|
|
198
|
+
var DecisionSource = z6.enum(["automated", "manual"]);
|
|
199
|
+
var Decision = z6.object({
|
|
200
|
+
id: Id,
|
|
201
|
+
tenantId: Id,
|
|
202
|
+
subjectId: Id,
|
|
203
|
+
workflowRunId: Id.nullish(),
|
|
204
|
+
caseId: Id.nullish(),
|
|
205
|
+
outcome: DecisionOutcome,
|
|
206
|
+
riskScore: z6.number().nullish(),
|
|
207
|
+
reasons: z6.array(DecisionReason),
|
|
208
|
+
source: DecisionSource,
|
|
209
|
+
decidedBy: z6.string().nullish(),
|
|
210
|
+
ruleResults: z6.array(RuleEvaluationResult),
|
|
211
|
+
/** The rule set that produced an automated decision, when one was used. */
|
|
212
|
+
ruleSetKey: z6.string().nullish(),
|
|
213
|
+
ruleSetVersion: z6.number().int().nullish(),
|
|
214
|
+
createdAt: z6.coerce.date()
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// src/case.ts
|
|
218
|
+
import { z as z7 } from "zod";
|
|
219
|
+
var CaseStatus = z7.enum(["open", "in_review", "decided", "closed"]);
|
|
220
|
+
var CasePriority = z7.enum(["low", "medium", "high", "critical"]);
|
|
221
|
+
var CaseSlaState = z7.enum(["none", "ok", "due_soon", "breached"]);
|
|
222
|
+
var Case = BaseEntity.extend({
|
|
223
|
+
subjectId: Id,
|
|
224
|
+
workflowRunId: Id.nullish(),
|
|
225
|
+
type: z7.string().min(1),
|
|
226
|
+
status: CaseStatus,
|
|
227
|
+
priority: CasePriority,
|
|
228
|
+
assigneeId: z7.string().nullish(),
|
|
229
|
+
decisionId: Id.nullish(),
|
|
230
|
+
context: JsonObject,
|
|
231
|
+
/** SLA deadline, set from the step's `slaHours` or the tenant default. */
|
|
232
|
+
dueAt: z7.coerce.date().nullish(),
|
|
233
|
+
/** Set once by the workflow when the SLA timer fires before a decision. */
|
|
234
|
+
slaBreachedAt: z7.coerce.date().nullish(),
|
|
235
|
+
/** First assignment or note: the moment someone picked the case up. */
|
|
236
|
+
firstResponseAt: z7.coerce.date().nullish(),
|
|
237
|
+
decidedAt: z7.coerce.date().nullish(),
|
|
238
|
+
closedAt: z7.coerce.date().nullish(),
|
|
239
|
+
closedReason: z7.string().nullish()
|
|
240
|
+
});
|
|
241
|
+
var CaseView = Case.extend({ slaState: CaseSlaState });
|
|
242
|
+
function caseSlaState(c, now = /* @__PURE__ */ new Date()) {
|
|
243
|
+
if (!c.dueAt) return "none";
|
|
244
|
+
if (c.slaBreachedAt) return "breached";
|
|
245
|
+
if (c.status === "decided" || c.status === "closed") return "ok";
|
|
246
|
+
const remaining = c.dueAt.getTime() - now.getTime();
|
|
247
|
+
if (remaining <= 0) return "breached";
|
|
248
|
+
const window = c.dueAt.getTime() - c.createdAt.getTime();
|
|
249
|
+
const soon = Math.min(window * 0.5, Math.max(window * 0.2, 2 * 3600 * 1e3));
|
|
250
|
+
return remaining <= soon ? "due_soon" : "ok";
|
|
251
|
+
}
|
|
252
|
+
var AssignCaseInput = z7.object({
|
|
253
|
+
/** Reviewer id from the user directory; `null` unassigns. */
|
|
254
|
+
assigneeId: z7.string().min(1).nullable()
|
|
255
|
+
});
|
|
256
|
+
var CloseCaseInput = z7.object({ reason: z7.string().max(500).optional() });
|
|
257
|
+
var CaseNote = BaseEntity.extend({
|
|
258
|
+
caseId: Id,
|
|
259
|
+
authorId: z7.string().min(1),
|
|
260
|
+
body: z7.string().min(1).max(1e4),
|
|
261
|
+
editedAt: z7.coerce.date().nullish()
|
|
262
|
+
});
|
|
263
|
+
var CaseNoteInput = z7.object({ body: z7.string().min(1).max(1e4) });
|
|
264
|
+
var CaseSort = z7.enum(["createdAt", "dueAt", "priority"]);
|
|
265
|
+
var SortOrder = z7.enum(["asc", "desc"]);
|
|
266
|
+
var CaseFilter = z7.object({
|
|
267
|
+
status: z7.array(CaseStatus).optional(),
|
|
268
|
+
priority: z7.array(CasePriority).optional(),
|
|
269
|
+
/** A reviewer id, `me` (resolved to the caller) or `unassigned`. */
|
|
270
|
+
assignee: z7.string().min(1).optional(),
|
|
271
|
+
type: z7.string().min(1).optional(),
|
|
272
|
+
subjectId: Id.optional(),
|
|
273
|
+
slaState: z7.array(CaseSlaState).optional(),
|
|
274
|
+
dueBefore: z7.coerce.date().optional(),
|
|
275
|
+
/** Case-insensitive match on `context.subjectName` and the case type. */
|
|
276
|
+
search: z7.string().min(1).max(200).optional()
|
|
277
|
+
});
|
|
278
|
+
var CaseQueue = BaseEntity.extend({
|
|
279
|
+
name: z7.string().min(1).max(80),
|
|
280
|
+
filter: CaseFilter,
|
|
281
|
+
sort: CaseSort,
|
|
282
|
+
order: SortOrder,
|
|
283
|
+
position: z7.number().int().nonnegative(),
|
|
284
|
+
createdBy: z7.string().min(1)
|
|
285
|
+
});
|
|
286
|
+
var UpsertCaseQueueInput = z7.object({
|
|
287
|
+
name: z7.string().min(1).max(80),
|
|
288
|
+
filter: CaseFilter.default({}),
|
|
289
|
+
sort: CaseSort.default("createdAt"),
|
|
290
|
+
order: SortOrder.default("desc"),
|
|
291
|
+
position: z7.number().int().nonnegative().default(0)
|
|
292
|
+
});
|
|
293
|
+
var DecideCaseInput = z7.object({
|
|
294
|
+
outcome: DecisionOutcome,
|
|
295
|
+
reasons: z7.array(DecisionReason).default([]),
|
|
296
|
+
note: z7.string().optional()
|
|
297
|
+
});
|
|
298
|
+
var ManualDecision = z7.object({
|
|
299
|
+
caseId: Id,
|
|
300
|
+
decisionId: Id,
|
|
301
|
+
outcome: DecisionOutcome,
|
|
302
|
+
reasons: z7.array(DecisionReason),
|
|
303
|
+
decidedBy: z7.string()
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// src/workflow.ts
|
|
307
|
+
import { z as z8 } from "zod";
|
|
308
|
+
var StepBase = z8.object({
|
|
309
|
+
id: z8.string().min(1),
|
|
310
|
+
name: z8.string().optional(),
|
|
311
|
+
/** Next step id. Omitted on terminal steps. */
|
|
312
|
+
next: z8.string().optional()
|
|
313
|
+
});
|
|
314
|
+
var EvaluateRulesStep = StepBase.extend({
|
|
315
|
+
type: z8.literal("evaluate_rules"),
|
|
316
|
+
/** Ad-hoc list evaluated with the default policy; mutually exclusive with `ruleSetKey`. */
|
|
317
|
+
ruleKeys: z8.array(DefinitionKey).min(1).optional(),
|
|
318
|
+
/** A published rule set: its rules, order, overrides and aggregation policy. */
|
|
319
|
+
ruleSetKey: DefinitionKey.optional(),
|
|
320
|
+
outputKey: z8.string().default("rules")
|
|
321
|
+
}).refine((step) => step.ruleKeys === void 0 !== (step.ruleSetKey === void 0), {
|
|
322
|
+
message: "evaluate_rules needs exactly one of ruleKeys or ruleSetKey",
|
|
323
|
+
path: ["ruleKeys"]
|
|
324
|
+
});
|
|
325
|
+
var CallPluginStep = StepBase.extend({
|
|
326
|
+
type: z8.literal("call_plugin"),
|
|
327
|
+
plugin: z8.string().min(1),
|
|
328
|
+
action: z8.string().min(1),
|
|
329
|
+
/** Literal input values (e.g. `{ type: "Person", topics: ["role.pep"] }`); `inputMapping` entries override them. */
|
|
330
|
+
input: z8.record(z8.string(), z8.unknown()).default({}),
|
|
331
|
+
/** input field -> dot path into the run context (e.g. `{ name: "submission.data.legalName" }`). */
|
|
332
|
+
inputMapping: z8.record(z8.string(), z8.string()).default({}),
|
|
333
|
+
outputKey: z8.string().min(1),
|
|
334
|
+
/** Overrides the worker's default retry policy for this plugin call. */
|
|
335
|
+
retry: z8.object({
|
|
336
|
+
maximumAttempts: z8.number().int().min(1).max(10).optional(),
|
|
337
|
+
initialIntervalSeconds: z8.number().positive().optional()
|
|
338
|
+
}).optional()
|
|
339
|
+
});
|
|
340
|
+
var WaitForCollectionStep = StepBase.extend({
|
|
341
|
+
type: z8.literal("wait_for_collection"),
|
|
342
|
+
flowKey: DefinitionKey,
|
|
343
|
+
timeoutSeconds: z8.number().int().positive().optional(),
|
|
344
|
+
outputKey: z8.string().default("submission")
|
|
345
|
+
});
|
|
346
|
+
var CreateCaseStep = StepBase.extend({
|
|
347
|
+
type: z8.literal("create_case"),
|
|
348
|
+
caseType: z8.string().min(1),
|
|
349
|
+
priority: CasePriority.default("medium"),
|
|
350
|
+
/** Hours until the case's SLA deadline; the tenant default applies when omitted. */
|
|
351
|
+
slaHours: z8.number().positive().max(24 * 90).optional(),
|
|
352
|
+
outputKey: z8.string().default("manualDecision")
|
|
353
|
+
});
|
|
354
|
+
var EmitDecisionStep = StepBase.extend({
|
|
355
|
+
type: z8.literal("emit_decision"),
|
|
356
|
+
mode: z8.enum(["from_rules", "fixed"]).default("from_rules"),
|
|
357
|
+
/** Context key holding rule results when mode is `from_rules`. */
|
|
358
|
+
rulesKey: z8.string().default("rules"),
|
|
359
|
+
/** Context key holding a manual decision; takes precedence when present. */
|
|
360
|
+
manualDecisionKey: z8.string().default("manualDecision"),
|
|
361
|
+
outcome: DecisionOutcome.optional()
|
|
362
|
+
});
|
|
363
|
+
var BranchStep = StepBase.extend({
|
|
364
|
+
type: z8.literal("branch"),
|
|
365
|
+
conditions: z8.array(z8.object({ when: Condition, next: z8.string().min(1) })).min(1),
|
|
366
|
+
default: z8.string().min(1)
|
|
367
|
+
});
|
|
368
|
+
var WorkflowStep = z8.discriminatedUnion("type", [
|
|
369
|
+
EvaluateRulesStep,
|
|
370
|
+
CallPluginStep,
|
|
371
|
+
WaitForCollectionStep,
|
|
372
|
+
CreateCaseStep,
|
|
373
|
+
EmitDecisionStep,
|
|
374
|
+
BranchStep
|
|
375
|
+
]);
|
|
376
|
+
function stepTargets(step) {
|
|
377
|
+
const targets = step.next ? [step.next] : [];
|
|
378
|
+
if (step.type === "branch") {
|
|
379
|
+
targets.push(...step.conditions.map((c) => c.next), step.default);
|
|
380
|
+
}
|
|
381
|
+
return targets;
|
|
382
|
+
}
|
|
383
|
+
var WorkflowUi = z8.object({
|
|
384
|
+
positions: z8.record(z8.string(), z8.object({ x: z8.number(), y: z8.number() })).default({})
|
|
385
|
+
});
|
|
386
|
+
var WorkflowDefinitionBody = z8.object({
|
|
387
|
+
entryStepId: z8.string().min(1),
|
|
388
|
+
steps: z8.array(WorkflowStep).min(1),
|
|
389
|
+
ui: WorkflowUi.optional()
|
|
390
|
+
}).superRefine((body, ctx) => {
|
|
391
|
+
const ids = /* @__PURE__ */ new Set();
|
|
392
|
+
body.steps.forEach((step, index) => {
|
|
393
|
+
if (ids.has(step.id)) {
|
|
394
|
+
ctx.addIssue({
|
|
395
|
+
code: "custom",
|
|
396
|
+
path: ["steps", index, "id"],
|
|
397
|
+
message: `duplicate step id "${step.id}"`
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
ids.add(step.id);
|
|
401
|
+
});
|
|
402
|
+
if (!ids.has(body.entryStepId)) {
|
|
403
|
+
ctx.addIssue({
|
|
404
|
+
code: "custom",
|
|
405
|
+
path: ["entryStepId"],
|
|
406
|
+
message: `unknown entry step "${body.entryStepId}"`
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
body.steps.forEach((step, index) => {
|
|
410
|
+
for (const target of stepTargets(step)) {
|
|
411
|
+
if (!ids.has(target)) {
|
|
412
|
+
ctx.addIssue({
|
|
413
|
+
code: "custom",
|
|
414
|
+
path: ["steps", index],
|
|
415
|
+
message: `step "${step.id}" points to unknown step "${target}"`
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
});
|
|
421
|
+
var WorkflowTrigger = z8.enum(["manual", "subject.created", "event"]);
|
|
422
|
+
var WorkflowDefinition = BaseEntity.extend({
|
|
423
|
+
/** Actor id that created this version; null for rows older than PR 19. */
|
|
424
|
+
createdBy: z8.string().nullish(),
|
|
425
|
+
key: DefinitionKey,
|
|
426
|
+
version: z8.number().int().positive(),
|
|
427
|
+
name: z8.string().min(1),
|
|
428
|
+
description: z8.string().nullish(),
|
|
429
|
+
trigger: WorkflowTrigger,
|
|
430
|
+
status: DefinitionStatus,
|
|
431
|
+
definition: WorkflowDefinitionBody
|
|
432
|
+
});
|
|
433
|
+
var UpsertWorkflowDefinitionInput = z8.object({
|
|
434
|
+
name: z8.string().min(1),
|
|
435
|
+
description: z8.string().optional(),
|
|
436
|
+
trigger: WorkflowTrigger.default("manual"),
|
|
437
|
+
definition: WorkflowDefinitionBody
|
|
438
|
+
});
|
|
439
|
+
var WorkflowRunStatus = z8.enum([
|
|
440
|
+
"running",
|
|
441
|
+
"waiting_collection",
|
|
442
|
+
"waiting_manual",
|
|
443
|
+
"waiting_callback",
|
|
444
|
+
"completed",
|
|
445
|
+
"failed",
|
|
446
|
+
"cancelled"
|
|
447
|
+
]);
|
|
448
|
+
var WorkflowRun = BaseEntity.extend({
|
|
449
|
+
definitionId: Id,
|
|
450
|
+
definitionKey: DefinitionKey,
|
|
451
|
+
definitionVersion: z8.number().int().positive(),
|
|
452
|
+
subjectId: Id,
|
|
453
|
+
temporalWorkflowId: z8.string(),
|
|
454
|
+
temporalRunId: z8.string().nullish(),
|
|
455
|
+
status: WorkflowRunStatus,
|
|
456
|
+
currentStepId: z8.string().nullish(),
|
|
457
|
+
/** Accumulated step outputs keyed by each step's `outputKey`. */
|
|
458
|
+
context: JsonObject,
|
|
459
|
+
decisionId: Id.nullish(),
|
|
460
|
+
error: z8.string().nullish(),
|
|
461
|
+
startedAt: z8.coerce.date(),
|
|
462
|
+
finishedAt: z8.coerce.date().nullish()
|
|
463
|
+
});
|
|
464
|
+
var StartWorkflowRunInput = z8.object({
|
|
465
|
+
definitionKey: DefinitionKey,
|
|
466
|
+
subjectId: Id
|
|
467
|
+
});
|
|
468
|
+
var RunDefinitionInput = z8.object({
|
|
469
|
+
tenantId: Id,
|
|
470
|
+
runId: Id,
|
|
471
|
+
definitionId: Id,
|
|
472
|
+
definitionVersion: z8.number().int().positive(),
|
|
473
|
+
subjectId: Id
|
|
474
|
+
});
|
|
475
|
+
function temporalWorkflowId(tenantId, runId) {
|
|
476
|
+
return `wf:${tenantId}:${runId}`;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// src/plugin.ts
|
|
480
|
+
import { z as z9 } from "zod";
|
|
481
|
+
var PluginDefinition = BaseEntity.extend({
|
|
482
|
+
name: z9.string().min(1),
|
|
483
|
+
version: z9.string().min(1),
|
|
484
|
+
capabilities: z9.array(z9.string()),
|
|
485
|
+
enabled: z9.boolean(),
|
|
486
|
+
config: JsonObject,
|
|
487
|
+
/** secret name -> reference understood by the SecretProvider (e.g. env var name). */
|
|
488
|
+
secretRefs: z9.record(z9.string(), z9.string())
|
|
489
|
+
});
|
|
490
|
+
var PluginInvocationStatus = z9.enum(["success", "error", "timeout", "pending"]);
|
|
491
|
+
var PluginInvocation = z9.object({
|
|
492
|
+
id: Id,
|
|
493
|
+
tenantId: Id,
|
|
494
|
+
pluginName: z9.string(),
|
|
495
|
+
action: z9.string(),
|
|
496
|
+
subjectId: Id.nullish(),
|
|
497
|
+
workflowRunId: Id.nullish(),
|
|
498
|
+
input: z9.unknown(),
|
|
499
|
+
output: z9.unknown().nullish(),
|
|
500
|
+
status: PluginInvocationStatus,
|
|
501
|
+
error: z9.string().nullish(),
|
|
502
|
+
durationMs: z9.number().nonnegative(),
|
|
503
|
+
invokedAt: z9.coerce.date(),
|
|
504
|
+
/** Caller-provided key identifying the logical call across retries. */
|
|
505
|
+
idempotencyKey: z9.string().nullish(),
|
|
506
|
+
/** 1 for the first attempt of a logical call, incremented by runtime retries. */
|
|
507
|
+
attempt: z9.number().int().positive().default(1)
|
|
508
|
+
});
|
|
509
|
+
var ConfigurePluginInput = z9.object({
|
|
510
|
+
enabled: z9.boolean().default(true),
|
|
511
|
+
config: JsonObject.default({}),
|
|
512
|
+
secretRefs: z9.record(z9.string(), z9.string()).default({})
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// src/collection.ts
|
|
516
|
+
import { z as z10 } from "zod";
|
|
517
|
+
var FieldType = z10.enum(["text", "email", "number", "select", "date", "boolean", "file"]);
|
|
518
|
+
var FieldOption = z10.object({ value: z10.string(), label: z10.string() });
|
|
519
|
+
var FieldValidation = z10.object({
|
|
520
|
+
min: z10.number().optional(),
|
|
521
|
+
max: z10.number().optional(),
|
|
522
|
+
pattern: z10.string().optional()
|
|
523
|
+
});
|
|
524
|
+
var Field = z10.object({
|
|
525
|
+
key: z10.string().regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, "field keys are identifiers"),
|
|
526
|
+
label: z10.string().min(1),
|
|
527
|
+
type: FieldType,
|
|
528
|
+
required: z10.boolean().default(false),
|
|
529
|
+
placeholder: z10.string().optional(),
|
|
530
|
+
help: z10.string().optional(),
|
|
531
|
+
options: z10.array(FieldOption).optional(),
|
|
532
|
+
validation: FieldValidation.optional(),
|
|
533
|
+
/** Field is rendered and validated only when the condition holds against the submission data. */
|
|
534
|
+
visibleWhen: Condition.optional()
|
|
535
|
+
});
|
|
536
|
+
var FlowStep = z10.object({
|
|
537
|
+
id: z10.string().min(1),
|
|
538
|
+
title: z10.string().min(1),
|
|
539
|
+
description: z10.string().optional(),
|
|
540
|
+
fields: z10.array(Field),
|
|
541
|
+
next: z10.string().optional(),
|
|
542
|
+
branches: z10.array(z10.object({ when: Condition, next: z10.string().min(1) })).optional()
|
|
543
|
+
});
|
|
544
|
+
var DEFAULT_LINK_TTL_SECONDS = 7 * 24 * 3600;
|
|
545
|
+
var MAX_LINK_TTL_SECONDS = 30 * 24 * 3600;
|
|
546
|
+
var CollectionFlowBody = z10.object({
|
|
547
|
+
entryStepId: z10.string().min(1),
|
|
548
|
+
steps: z10.array(FlowStep).min(1),
|
|
549
|
+
/** Lifetime of the signed submission link issued for this flow (60 s to 30 days). */
|
|
550
|
+
linkTtlSeconds: z10.number().int().min(60).max(MAX_LINK_TTL_SECONDS).default(DEFAULT_LINK_TTL_SECONDS)
|
|
551
|
+
}).superRefine((body, ctx) => {
|
|
552
|
+
const ids = new Set(body.steps.map((s) => s.id));
|
|
553
|
+
if (ids.size !== body.steps.length) {
|
|
554
|
+
ctx.addIssue({ code: "custom", path: ["steps"], message: "duplicate step ids" });
|
|
555
|
+
}
|
|
556
|
+
if (!ids.has(body.entryStepId)) {
|
|
557
|
+
ctx.addIssue({
|
|
558
|
+
code: "custom",
|
|
559
|
+
path: ["entryStepId"],
|
|
560
|
+
message: `unknown entry step "${body.entryStepId}"`
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
body.steps.forEach((step, index) => {
|
|
564
|
+
const targets = [
|
|
565
|
+
...step.next ? [step.next] : [],
|
|
566
|
+
...(step.branches ?? []).map((b) => b.next)
|
|
567
|
+
];
|
|
568
|
+
for (const target of targets) {
|
|
569
|
+
if (!ids.has(target)) {
|
|
570
|
+
ctx.addIssue({
|
|
571
|
+
code: "custom",
|
|
572
|
+
path: ["steps", index],
|
|
573
|
+
message: `step "${step.id}" points to unknown step "${target}"`
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
});
|
|
578
|
+
});
|
|
579
|
+
var CollectionFlowDefinition = BaseEntity.extend({
|
|
580
|
+
/** Actor id that created this version; null for rows older than PR 19. */
|
|
581
|
+
createdBy: z10.string().nullish(),
|
|
582
|
+
key: DefinitionKey,
|
|
583
|
+
version: z10.number().int().positive(),
|
|
584
|
+
name: z10.string().min(1),
|
|
585
|
+
description: z10.string().nullish(),
|
|
586
|
+
status: DefinitionStatus,
|
|
587
|
+
definition: CollectionFlowBody
|
|
588
|
+
});
|
|
589
|
+
var UpsertCollectionFlowInput = z10.object({
|
|
590
|
+
name: z10.string().min(1),
|
|
591
|
+
description: z10.string().optional(),
|
|
592
|
+
definition: CollectionFlowBody
|
|
593
|
+
});
|
|
594
|
+
var SubmissionStatus = z10.enum(["in_progress", "submitted"]);
|
|
595
|
+
var CollectionSubmission = BaseEntity.extend({
|
|
596
|
+
flowDefinitionId: Id,
|
|
597
|
+
flowKey: DefinitionKey,
|
|
598
|
+
flowVersion: z10.number().int().positive(),
|
|
599
|
+
subjectId: Id,
|
|
600
|
+
workflowRunId: Id.nullish(),
|
|
601
|
+
status: SubmissionStatus,
|
|
602
|
+
data: JsonObject,
|
|
603
|
+
currentStepId: z10.string().nullish(),
|
|
604
|
+
submittedAt: z10.coerce.date().nullish()
|
|
605
|
+
});
|
|
606
|
+
var CreateSubmissionInput = z10.object({
|
|
607
|
+
flowKey: DefinitionKey,
|
|
608
|
+
subjectId: Id,
|
|
609
|
+
workflowRunId: Id.optional()
|
|
610
|
+
});
|
|
611
|
+
var SaveSubmissionInput = z10.object({
|
|
612
|
+
data: JsonObject,
|
|
613
|
+
currentStepId: z10.string().optional()
|
|
614
|
+
});
|
|
615
|
+
var CollectionSubmitted = z10.object({
|
|
616
|
+
submissionId: Id,
|
|
617
|
+
flowKey: DefinitionKey,
|
|
618
|
+
data: JsonObject,
|
|
619
|
+
submittedAt: z10.coerce.date()
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
// src/audit.ts
|
|
623
|
+
import { z as z11 } from "zod";
|
|
624
|
+
var AuditEvent = z11.object({
|
|
625
|
+
id: Id,
|
|
626
|
+
tenantId: Id,
|
|
627
|
+
actorType: ActorType,
|
|
628
|
+
actorId: z11.string(),
|
|
629
|
+
/** Dotted verb, e.g. `case.decided`, `workflow.step.completed`. */
|
|
630
|
+
action: z11.string().regex(/^[a-z_]+(\.[a-z_]+)+$/),
|
|
631
|
+
resourceType: z11.string().min(1),
|
|
632
|
+
resourceId: z11.string().min(1),
|
|
633
|
+
payload: z11.unknown(),
|
|
634
|
+
occurredAt: z11.coerce.date()
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
// src/list.ts
|
|
638
|
+
import { z as z12 } from "zod";
|
|
639
|
+
var ListKind = z12.enum(["string", "email", "country", "ip_cidr", "number"]);
|
|
640
|
+
var List = BaseEntity.extend({
|
|
641
|
+
key: DefinitionKey,
|
|
642
|
+
name: z12.string().min(1),
|
|
643
|
+
description: z12.string().nullish(),
|
|
644
|
+
kind: ListKind,
|
|
645
|
+
/** String matching ignores case (default). Ignored for `ip_cidr` and `number`. */
|
|
646
|
+
caseInsensitive: z12.boolean(),
|
|
647
|
+
entryCount: z12.number().int().nonnegative()
|
|
648
|
+
});
|
|
649
|
+
var UpsertListInput = z12.object({
|
|
650
|
+
name: z12.string().min(1),
|
|
651
|
+
description: z12.string().optional(),
|
|
652
|
+
kind: ListKind,
|
|
653
|
+
caseInsensitive: z12.boolean().default(true)
|
|
654
|
+
});
|
|
655
|
+
var ListEntry = z12.object({
|
|
656
|
+
id: Id,
|
|
657
|
+
tenantId: Id,
|
|
658
|
+
listId: Id,
|
|
659
|
+
/** The value as entered (trimmed). Matching uses a normalised form. */
|
|
660
|
+
value: z12.string().min(1),
|
|
661
|
+
reason: z12.string().nullish(),
|
|
662
|
+
expiresAt: z12.coerce.date().nullish(),
|
|
663
|
+
addedBy: z12.string(),
|
|
664
|
+
createdAt: z12.coerce.date()
|
|
665
|
+
});
|
|
666
|
+
var NewListEntry = z12.object({
|
|
667
|
+
value: z12.string().trim().min(1).max(512),
|
|
668
|
+
reason: z12.string().max(1e3).optional(),
|
|
669
|
+
expiresAt: z12.coerce.date().optional()
|
|
670
|
+
});
|
|
671
|
+
var AddListEntriesInput = z12.object({
|
|
672
|
+
entries: z12.array(NewListEntry).min(1).max(1e4)
|
|
673
|
+
});
|
|
674
|
+
var RemoveListEntriesInput = z12.object({
|
|
675
|
+
ids: z12.array(Id).min(1).max(1e4)
|
|
676
|
+
});
|
|
677
|
+
var ListImportResult = z12.object({
|
|
678
|
+
added: z12.number().int().nonnegative(),
|
|
679
|
+
skipped: z12.number().int().nonnegative(),
|
|
680
|
+
invalid: z12.array(
|
|
681
|
+
z12.object({ line: z12.number().int().positive(), value: z12.string(), reason: z12.string() })
|
|
682
|
+
)
|
|
683
|
+
});
|
|
684
|
+
var IPV4 = /^(\d{1,3})(\.\d{1,3}){3}(\/\d{1,2})?$/;
|
|
685
|
+
var IPV6 = /^[0-9a-f:]+(\/\d{1,3})?$/i;
|
|
686
|
+
var COUNTRY = /^[A-Z]{2}$/;
|
|
687
|
+
function normalizeListValue(kind, raw, caseInsensitive = true) {
|
|
688
|
+
const value = raw.trim();
|
|
689
|
+
if (!value) return { ok: false, reason: "empty value" };
|
|
690
|
+
switch (kind) {
|
|
691
|
+
case "string":
|
|
692
|
+
return { ok: true, value: caseInsensitive ? value.toLowerCase() : value };
|
|
693
|
+
case "email": {
|
|
694
|
+
const lower = value.toLowerCase();
|
|
695
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(lower))
|
|
696
|
+
return { ok: false, reason: "not an email address" };
|
|
697
|
+
return { ok: true, value: lower };
|
|
698
|
+
}
|
|
699
|
+
case "country": {
|
|
700
|
+
const upper = value.toUpperCase();
|
|
701
|
+
if (!COUNTRY.test(upper)) return { ok: false, reason: "not an ISO 3166-1 alpha-2 code" };
|
|
702
|
+
return { ok: true, value: upper };
|
|
703
|
+
}
|
|
704
|
+
case "number": {
|
|
705
|
+
const n = Number(value);
|
|
706
|
+
if (!Number.isFinite(n)) return { ok: false, reason: "not a number" };
|
|
707
|
+
return { ok: true, value: String(n) };
|
|
708
|
+
}
|
|
709
|
+
case "ip_cidr": {
|
|
710
|
+
if (IPV4.test(value)) {
|
|
711
|
+
const [addr, prefix] = value.split("/");
|
|
712
|
+
const octets = addr.split(".").map(Number);
|
|
713
|
+
if (octets.some((o) => o > 255)) return { ok: false, reason: "invalid IPv4 address" };
|
|
714
|
+
if (prefix !== void 0 && Number(prefix) > 32)
|
|
715
|
+
return { ok: false, reason: "invalid prefix" };
|
|
716
|
+
return { ok: true, value: prefix === void 0 ? `${addr}/32` : value };
|
|
717
|
+
}
|
|
718
|
+
if (IPV6.test(value) && value.includes(":")) {
|
|
719
|
+
const [addr, prefix] = value.split("/");
|
|
720
|
+
if (prefix !== void 0 && Number(prefix) > 128)
|
|
721
|
+
return { ok: false, reason: "invalid prefix" };
|
|
722
|
+
return {
|
|
723
|
+
ok: true,
|
|
724
|
+
value: prefix === void 0 ? `${addr.toLowerCase()}/128` : value.toLowerCase()
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
return { ok: false, reason: "not an IP address or CIDR range" };
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// src/event.ts
|
|
733
|
+
import { z as z13 } from "zod";
|
|
734
|
+
var EventKey = z13.enum(["ip", "device_id", "card_fingerprint", "email"]);
|
|
735
|
+
var Event = z13.object({
|
|
736
|
+
id: z13.string(),
|
|
737
|
+
tenantId: Id,
|
|
738
|
+
subjectId: Id,
|
|
739
|
+
type: z13.string().min(1),
|
|
740
|
+
amount: z13.number().nullish(),
|
|
741
|
+
currency: z13.string().length(3).nullish(),
|
|
742
|
+
occurredAt: z13.coerce.date(),
|
|
743
|
+
ingestedAt: z13.coerce.date(),
|
|
744
|
+
attributes: JsonObject,
|
|
745
|
+
idempotencyKey: z13.string(),
|
|
746
|
+
ip: z13.string().nullish(),
|
|
747
|
+
deviceId: z13.string().nullish(),
|
|
748
|
+
cardFingerprint: z13.string().nullish(),
|
|
749
|
+
email: z13.string().nullish()
|
|
750
|
+
});
|
|
751
|
+
var NewEvent = z13.object({
|
|
752
|
+
subjectId: Id,
|
|
753
|
+
type: z13.string().min(1).max(100).regex(/^[a-z0-9][a-z0-9_.-]*$/, "event types are lowercase identifiers"),
|
|
754
|
+
amount: z13.number().finite().optional(),
|
|
755
|
+
currency: z13.string().length(3).toUpperCase().optional(),
|
|
756
|
+
occurredAt: z13.coerce.date(),
|
|
757
|
+
attributes: JsonObject.default({}),
|
|
758
|
+
/** Caller-chosen key; re-sending the same key is a no-op. */
|
|
759
|
+
idempotencyKey: z13.string().min(1).max(255),
|
|
760
|
+
ip: z13.string().max(45).optional(),
|
|
761
|
+
deviceId: z13.string().max(255).optional(),
|
|
762
|
+
cardFingerprint: z13.string().max(255).optional(),
|
|
763
|
+
email: z13.string().max(320).toLowerCase().optional()
|
|
764
|
+
});
|
|
765
|
+
var IngestEventsInput = z13.object({
|
|
766
|
+
events: z13.array(NewEvent).min(1).max(1e3)
|
|
767
|
+
});
|
|
768
|
+
var IngestEventsResult = z13.object({
|
|
769
|
+
accepted: z13.number().int().nonnegative(),
|
|
770
|
+
duplicates: z13.number().int().nonnegative()
|
|
771
|
+
});
|
|
772
|
+
|
|
773
|
+
// src/rule-set.ts
|
|
774
|
+
import { z as z14 } from "zod";
|
|
775
|
+
var RuleSetUseCase = z14.enum(["onboarding", "underwriting", "monitoring", "custom"]);
|
|
776
|
+
var ScoreBand = z14.object({
|
|
777
|
+
min: z14.number(),
|
|
778
|
+
max: z14.number(),
|
|
779
|
+
outcome: DecisionOutcome
|
|
780
|
+
});
|
|
781
|
+
var ScoreClamp = z14.object({ min: z14.number().default(0), max: z14.number().default(100) });
|
|
782
|
+
var AggregationPolicy = z14.discriminatedUnion("mode", [
|
|
783
|
+
/** Failed block -> reject; failed warn -> manual review; else approve (the original policy). */
|
|
784
|
+
z14.object({ mode: z14.literal("max_severity") }),
|
|
785
|
+
/** Score = sum of weights on failed rules plus reported scores, clamped, mapped through bands. */
|
|
786
|
+
z14.object({
|
|
787
|
+
mode: z14.literal("sum_weights"),
|
|
788
|
+
clamp: ScoreClamp.default({ min: 0, max: 100 }),
|
|
789
|
+
bands: z14.array(ScoreBand).min(1)
|
|
790
|
+
}),
|
|
791
|
+
/** Rules in set order; the first failed rule's severity decides, `info` continues. */
|
|
792
|
+
z14.object({ mode: z14.literal("first_match"), default: DecisionOutcome.default("approve") })
|
|
793
|
+
]);
|
|
794
|
+
var RuleSetRule = z14.object({
|
|
795
|
+
ruleKey: DefinitionKey,
|
|
796
|
+
enabled: z14.boolean().default(true),
|
|
797
|
+
/** Replaces the rule's own weight inside this set. */
|
|
798
|
+
weightOverride: z14.number().optional(),
|
|
799
|
+
/** Evaluated and recorded but excluded from aggregation. */
|
|
800
|
+
shadow: z14.boolean().default(false)
|
|
801
|
+
});
|
|
802
|
+
var RuleSetBody = z14.object({
|
|
803
|
+
rules: z14.array(RuleSetRule).min(1),
|
|
804
|
+
policy: AggregationPolicy
|
|
805
|
+
}).superRefine((body, ctx) => {
|
|
806
|
+
const seen = /* @__PURE__ */ new Set();
|
|
807
|
+
body.rules.forEach((rule, index) => {
|
|
808
|
+
if (seen.has(rule.ruleKey)) {
|
|
809
|
+
ctx.addIssue({
|
|
810
|
+
code: "custom",
|
|
811
|
+
path: ["rules", index, "ruleKey"],
|
|
812
|
+
message: `duplicate rule "${rule.ruleKey}"`
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
seen.add(rule.ruleKey);
|
|
816
|
+
});
|
|
817
|
+
if (body.policy.mode !== "sum_weights") return;
|
|
818
|
+
const { clamp, bands } = body.policy;
|
|
819
|
+
if (clamp.min >= clamp.max) {
|
|
820
|
+
ctx.addIssue({
|
|
821
|
+
code: "custom",
|
|
822
|
+
path: ["policy", "clamp"],
|
|
823
|
+
message: "clamp.min must be below clamp.max"
|
|
824
|
+
});
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
const sorted = [...bands].sort((a, b) => a.min - b.min);
|
|
828
|
+
let expected = clamp.min;
|
|
829
|
+
sorted.forEach((band, index) => {
|
|
830
|
+
if (band.min >= band.max) {
|
|
831
|
+
ctx.addIssue({
|
|
832
|
+
code: "custom",
|
|
833
|
+
path: ["policy", "bands", index],
|
|
834
|
+
message: "band.min must be below band.max"
|
|
835
|
+
});
|
|
836
|
+
}
|
|
837
|
+
if (band.min !== expected) {
|
|
838
|
+
ctx.addIssue({
|
|
839
|
+
code: "custom",
|
|
840
|
+
path: ["policy", "bands", index],
|
|
841
|
+
message: `bands must be contiguous and start at ${clamp.min}; expected min ${expected}, got ${band.min}`
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
expected = band.max;
|
|
845
|
+
});
|
|
846
|
+
if (expected !== clamp.max) {
|
|
847
|
+
ctx.addIssue({
|
|
848
|
+
code: "custom",
|
|
849
|
+
path: ["policy", "bands"],
|
|
850
|
+
message: `bands must end at clamp.max (${clamp.max}), got ${expected}`
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
var RuleSetDefinition = BaseEntity.extend({
|
|
855
|
+
/** Actor id that created this version; null for rows older than PR 19. */
|
|
856
|
+
createdBy: z14.string().nullish(),
|
|
857
|
+
key: DefinitionKey,
|
|
858
|
+
version: z14.number().int().positive(),
|
|
859
|
+
name: z14.string().min(1),
|
|
860
|
+
description: z14.string().nullish(),
|
|
861
|
+
useCase: RuleSetUseCase,
|
|
862
|
+
status: DefinitionStatus,
|
|
863
|
+
definition: RuleSetBody
|
|
864
|
+
});
|
|
865
|
+
var UpsertRuleSetInput = z14.object({
|
|
866
|
+
name: z14.string().min(1),
|
|
867
|
+
description: z14.string().optional(),
|
|
868
|
+
useCase: RuleSetUseCase.default("custom"),
|
|
869
|
+
definition: RuleSetBody
|
|
870
|
+
});
|
|
871
|
+
function bandFor(bands, score) {
|
|
872
|
+
const sorted = [...bands].sort((a, b) => a.min - b.min);
|
|
873
|
+
const last = sorted[sorted.length - 1];
|
|
874
|
+
for (const band of sorted) {
|
|
875
|
+
if (score >= band.min && (score < band.max || band === last && score <= band.max))
|
|
876
|
+
return band;
|
|
877
|
+
}
|
|
878
|
+
return void 0;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// src/evaluation.ts
|
|
882
|
+
import { z as z15 } from "zod";
|
|
883
|
+
var RuleEvaluation = z15.object({
|
|
884
|
+
id: Id,
|
|
885
|
+
tenantId: Id,
|
|
886
|
+
workflowRunId: Id,
|
|
887
|
+
stepId: z15.string(),
|
|
888
|
+
subjectId: Id,
|
|
889
|
+
ruleSetKey: z15.string().nullish(),
|
|
890
|
+
ruleSetVersion: z15.number().int().nullish(),
|
|
891
|
+
ruleKeys: z15.array(z15.string()),
|
|
892
|
+
/** The full `RuleContext.data` at evaluation time. */
|
|
893
|
+
data: JsonObject,
|
|
894
|
+
results: z15.array(RuleEvaluationResult),
|
|
895
|
+
outcome: DecisionOutcome,
|
|
896
|
+
riskScore: z15.number(),
|
|
897
|
+
evaluatedAt: z15.coerce.date()
|
|
898
|
+
});
|
|
899
|
+
|
|
900
|
+
// src/backtest.ts
|
|
901
|
+
import { z as z16 } from "zod";
|
|
902
|
+
var BacktestStatus = z16.enum(["queued", "running", "completed", "failed"]);
|
|
903
|
+
var BacktestSample = z16.object({
|
|
904
|
+
/** Replay evaluations recorded in the last N days (at most 180). */
|
|
905
|
+
lastDays: z16.number().int().min(1).max(180).default(30),
|
|
906
|
+
/** Newest evaluation per subject, up to this many subjects. */
|
|
907
|
+
limit: z16.number().int().min(1).max(5e3).default(1e3)
|
|
908
|
+
});
|
|
909
|
+
var StartBacktestInput = z16.object({
|
|
910
|
+
ruleKey: DefinitionKey,
|
|
911
|
+
/** Defaults to the latest version (drafts included). */
|
|
912
|
+
version: z16.number().int().positive().optional(),
|
|
913
|
+
sample: BacktestSample.default({ lastDays: 30, limit: 1e3 }),
|
|
914
|
+
/**
|
|
915
|
+
* Re-aggregate each stored evaluation with the draft rule's result substituted (or added) under
|
|
916
|
+
* this rule set's policy, to report how outcomes would change.
|
|
917
|
+
*/
|
|
918
|
+
compareWithRuleSetKey: DefinitionKey.optional()
|
|
919
|
+
});
|
|
920
|
+
var BacktestProgress = z16.object({
|
|
921
|
+
done: z16.number().int().nonnegative(),
|
|
922
|
+
total: z16.number().int().nonnegative()
|
|
923
|
+
});
|
|
924
|
+
var BacktestSampleFailure = z16.object({
|
|
925
|
+
evaluationId: Id,
|
|
926
|
+
subjectId: Id,
|
|
927
|
+
evaluatedAt: z16.coerce.date(),
|
|
928
|
+
reasons: z16.array(z16.string())
|
|
929
|
+
});
|
|
930
|
+
var BacktestSummary = z16.object({
|
|
931
|
+
evaluated: z16.number().int().nonnegative(),
|
|
932
|
+
outcomes: z16.record(RuleOutcome, z16.number().int().nonnegative()),
|
|
933
|
+
/** Counts keyed `"<before>-><after>"` for evaluations whose aggregate outcome would change. */
|
|
934
|
+
wouldChange: z16.record(z16.string(), z16.number().int().nonnegative()),
|
|
935
|
+
/** Per existing rule key: evaluations where both that rule and the draft failed. */
|
|
936
|
+
overlap: z16.record(z16.string(), z16.number().int().nonnegative()),
|
|
937
|
+
/** First 50 evaluations the draft failed on. */
|
|
938
|
+
sampleFailures: z16.array(BacktestSampleFailure),
|
|
939
|
+
durationMs: z16.number().nonnegative()
|
|
940
|
+
});
|
|
941
|
+
var Backtest = z16.object({
|
|
942
|
+
id: Id,
|
|
943
|
+
tenantId: Id,
|
|
944
|
+
ruleKey: DefinitionKey,
|
|
945
|
+
ruleVersion: z16.number().int().positive(),
|
|
946
|
+
ruleSetKey: z16.string().nullish(),
|
|
947
|
+
sample: BacktestSample,
|
|
948
|
+
status: BacktestStatus,
|
|
949
|
+
progress: BacktestProgress,
|
|
950
|
+
summary: BacktestSummary.nullish(),
|
|
951
|
+
error: z16.string().nullish(),
|
|
952
|
+
temporalWorkflowId: z16.string().nullish(),
|
|
953
|
+
requestedBy: z16.string(),
|
|
954
|
+
createdAt: z16.coerce.date(),
|
|
955
|
+
finishedAt: z16.coerce.date().nullish()
|
|
956
|
+
});
|
|
957
|
+
var OutcomeChange = z16.object({ before: DecisionOutcome, after: DecisionOutcome });
|
|
958
|
+
|
|
959
|
+
// src/plugin-callback.ts
|
|
960
|
+
import { z as z17 } from "zod";
|
|
961
|
+
var PluginCallbackStatus = z17.enum(["pending", "completed", "failed", "timed_out"]);
|
|
962
|
+
var PluginCallback = z17.object({
|
|
963
|
+
id: Id,
|
|
964
|
+
tenantId: Id,
|
|
965
|
+
pluginName: z17.string(),
|
|
966
|
+
action: z17.string(),
|
|
967
|
+
externalId: z17.string(),
|
|
968
|
+
workflowRunId: Id.nullish(),
|
|
969
|
+
stepId: z17.string().nullish(),
|
|
970
|
+
status: PluginCallbackStatus,
|
|
971
|
+
output: z17.unknown().nullish(),
|
|
972
|
+
error: z17.string().nullish(),
|
|
973
|
+
createdAt: z17.coerce.date(),
|
|
974
|
+
completedAt: z17.coerce.date().nullish()
|
|
975
|
+
});
|
|
976
|
+
var PluginCallbackSignal = z17.object({
|
|
977
|
+
externalId: z17.string(),
|
|
978
|
+
status: z17.enum(["completed", "failed"]),
|
|
979
|
+
output: z17.unknown().optional(),
|
|
980
|
+
error: z17.string().optional()
|
|
981
|
+
});
|
|
982
|
+
var WebhookEventRecord = z17.object({
|
|
983
|
+
id: Id,
|
|
984
|
+
tenantId: Id,
|
|
985
|
+
pluginName: z17.string(),
|
|
986
|
+
eventId: z17.string(),
|
|
987
|
+
externalId: z17.string(),
|
|
988
|
+
receivedAt: z17.coerce.date()
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
// src/document.ts
|
|
992
|
+
import { z as z18 } from "zod";
|
|
993
|
+
var DOCUMENT_MAX_BYTES = 20 * 1024 * 1024;
|
|
994
|
+
var DOCUMENT_CONTENT_TYPES = [
|
|
995
|
+
"image/jpeg",
|
|
996
|
+
"image/png",
|
|
997
|
+
"image/webp",
|
|
998
|
+
"application/pdf"
|
|
999
|
+
];
|
|
1000
|
+
var DocumentContentType = z18.enum(DOCUMENT_CONTENT_TYPES);
|
|
1001
|
+
var DocumentStatus = z18.enum([
|
|
1002
|
+
"pending",
|
|
1003
|
+
"uploaded",
|
|
1004
|
+
"scanning",
|
|
1005
|
+
"clean",
|
|
1006
|
+
"infected",
|
|
1007
|
+
"rejected"
|
|
1008
|
+
]);
|
|
1009
|
+
var DOCUMENT_OPEN_STATUSES = [
|
|
1010
|
+
"pending",
|
|
1011
|
+
"uploaded",
|
|
1012
|
+
"scanning"
|
|
1013
|
+
];
|
|
1014
|
+
var DocumentScan = z18.object({
|
|
1015
|
+
/** Scanner that produced the verdict, e.g. `none`, `clamav`. */
|
|
1016
|
+
engine: z18.string().min(1),
|
|
1017
|
+
/** Malware signature name when infected. */
|
|
1018
|
+
signature: z18.string().optional(),
|
|
1019
|
+
scannedAt: z18.coerce.date()
|
|
1020
|
+
});
|
|
1021
|
+
var Document = BaseEntity.extend({
|
|
1022
|
+
subjectId: Id,
|
|
1023
|
+
submissionId: Id.nullish(),
|
|
1024
|
+
caseId: Id.nullish(),
|
|
1025
|
+
/** Collection-flow field the file was uploaded for. */
|
|
1026
|
+
fieldKey: z18.string().nullish(),
|
|
1027
|
+
fileName: z18.string().min(1).max(255),
|
|
1028
|
+
/** Declared on creation; replaced by the sniffed type on finalize. */
|
|
1029
|
+
contentType: z18.string().min(1),
|
|
1030
|
+
sizeBytes: z18.number().int().nonnegative(),
|
|
1031
|
+
/** Hex digest, set on finalize. */
|
|
1032
|
+
sha256: z18.string().nullish(),
|
|
1033
|
+
/** Server-chosen object key: `${tenantId}/${subjectId}/${documentId}`. */
|
|
1034
|
+
storageKey: z18.string().min(1),
|
|
1035
|
+
status: DocumentStatus,
|
|
1036
|
+
scan: DocumentScan.nullish(),
|
|
1037
|
+
/** Why the document was `rejected`, for operators and applicants. */
|
|
1038
|
+
rejectionReason: z18.string().nullish(),
|
|
1039
|
+
/** Actor id of the uploader (user id, machine id or submission id). */
|
|
1040
|
+
uploadedBy: z18.string().min(1)
|
|
1041
|
+
});
|
|
1042
|
+
var CreateDocumentInput = z18.object({
|
|
1043
|
+
fileName: z18.string().min(1).max(255),
|
|
1044
|
+
contentType: DocumentContentType,
|
|
1045
|
+
sizeBytes: z18.number().int().positive().max(DOCUMENT_MAX_BYTES),
|
|
1046
|
+
/** Operators and integrations name the subject; applicants' subject comes from the submission. */
|
|
1047
|
+
subjectId: Id.optional(),
|
|
1048
|
+
submissionId: Id.optional(),
|
|
1049
|
+
caseId: Id.optional(),
|
|
1050
|
+
fieldKey: z18.string().optional()
|
|
1051
|
+
});
|
|
1052
|
+
var DocumentUploadTicket = z18.object({
|
|
1053
|
+
documentId: Id,
|
|
1054
|
+
upload: z18.object({
|
|
1055
|
+
url: z18.url(),
|
|
1056
|
+
/** Form fields to send with the file (policy, signature, key); the file field goes last. */
|
|
1057
|
+
fields: z18.record(z18.string(), z18.string()),
|
|
1058
|
+
expiresAt: z18.coerce.date(),
|
|
1059
|
+
maxBytes: z18.number().int().positive()
|
|
1060
|
+
})
|
|
1061
|
+
});
|
|
1062
|
+
var DocumentDownload = z18.object({
|
|
1063
|
+
url: z18.url(),
|
|
1064
|
+
expiresAt: z18.coerce.date(),
|
|
1065
|
+
fileName: z18.string(),
|
|
1066
|
+
contentType: z18.string()
|
|
1067
|
+
});
|
|
1068
|
+
var FileFieldValue = z18.object({ fileId: Id, name: z18.string().optional() });
|
|
1069
|
+
|
|
1070
|
+
// src/timeline.ts
|
|
1071
|
+
import { z as z19 } from "zod";
|
|
1072
|
+
var TimelineKind = z19.enum([
|
|
1073
|
+
"decision",
|
|
1074
|
+
"case",
|
|
1075
|
+
"run",
|
|
1076
|
+
"submission",
|
|
1077
|
+
"document",
|
|
1078
|
+
"event",
|
|
1079
|
+
"note",
|
|
1080
|
+
"audit"
|
|
1081
|
+
]);
|
|
1082
|
+
var TimelineEntry = z19.object({
|
|
1083
|
+
/** Stable per entry: `<kind>:<resourceId>[:<suffix>]`. */
|
|
1084
|
+
id: z19.string().min(1),
|
|
1085
|
+
kind: TimelineKind,
|
|
1086
|
+
at: z19.coerce.date(),
|
|
1087
|
+
title: z19.string().min(1),
|
|
1088
|
+
summary: z19.string().optional(),
|
|
1089
|
+
resourceType: z19.string().min(1),
|
|
1090
|
+
resourceId: z19.string().min(1),
|
|
1091
|
+
actor: Actor.optional(),
|
|
1092
|
+
data: z19.unknown().optional()
|
|
1093
|
+
});
|
|
1094
|
+
var TimelineQuery = z19.object({
|
|
1095
|
+
from: z19.coerce.date().optional(),
|
|
1096
|
+
to: z19.coerce.date().optional(),
|
|
1097
|
+
kinds: z19.array(TimelineKind).optional(),
|
|
1098
|
+
limit: z19.coerce.number().int().positive().max(500).optional(),
|
|
1099
|
+
offset: z19.coerce.number().int().nonnegative().optional()
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
// src/builder.ts
|
|
1103
|
+
import { z as z20 } from "zod";
|
|
1104
|
+
var FormUiHints = z20.object({
|
|
1105
|
+
/** Fields in display order; unlisted fields follow in schema order. */
|
|
1106
|
+
fieldOrder: z20.array(z20.string()).optional(),
|
|
1107
|
+
labels: z20.record(z20.string(), z20.string()).optional(),
|
|
1108
|
+
help: z20.record(z20.string(), z20.string()).optional(),
|
|
1109
|
+
/**
|
|
1110
|
+
* Fields rendered with a picker instead of a free input. Values: `list`, `rule`, `ruleSet`,
|
|
1111
|
+
* `flow`, `plugin`, `pluginAction`, `step`, `path`, `condition`, `cel`.
|
|
1112
|
+
*/
|
|
1113
|
+
pickers: z20.record(z20.string(), z20.string()).optional()
|
|
1114
|
+
});
|
|
1115
|
+
var StepTypeDescription = z20.object({
|
|
1116
|
+
type: z20.string().min(1),
|
|
1117
|
+
title: z20.string().min(1),
|
|
1118
|
+
description: z20.string(),
|
|
1119
|
+
/** JSON Schema of the step's own fields (`id`, `name`, `next` excluded). */
|
|
1120
|
+
configSchema: z20.unknown(),
|
|
1121
|
+
/** Dot-path namespaces the step may read from the run context, e.g. `submission.<field>`. */
|
|
1122
|
+
dataPaths: z20.array(z20.string()).default([]),
|
|
1123
|
+
/** Context keys the step writes (`outputKey` conventions), for downstream path pickers. */
|
|
1124
|
+
outputs: z20.array(z20.string()).default([]),
|
|
1125
|
+
/** Whether the step ends the run (no `next`). */
|
|
1126
|
+
terminal: z20.boolean().default(false),
|
|
1127
|
+
uiHints: FormUiHints.optional()
|
|
1128
|
+
});
|
|
1129
|
+
var FieldTypeDescription = z20.object({
|
|
1130
|
+
type: z20.string().min(1),
|
|
1131
|
+
title: z20.string().min(1),
|
|
1132
|
+
description: z20.string(),
|
|
1133
|
+
/** JSON Schema of the field-type-specific options (select options, validation, file limits). */
|
|
1134
|
+
optionsSchema: z20.unknown(),
|
|
1135
|
+
/** Shape of the stored value, as JSON Schema, for previews and docs. */
|
|
1136
|
+
valueSchema: z20.unknown()
|
|
1137
|
+
});
|
|
1138
|
+
var IssueSeverity = z20.enum(["error", "warning"]);
|
|
1139
|
+
var DefinitionIssue = z20.object({
|
|
1140
|
+
severity: IssueSeverity,
|
|
1141
|
+
/** JSON pointer-ish path into the body, e.g. `steps.2.next`. */
|
|
1142
|
+
path: z20.string(),
|
|
1143
|
+
/** Step or field the issue belongs to, when it has one, so editors can mark it. */
|
|
1144
|
+
stepId: z20.string().optional(),
|
|
1145
|
+
fieldKey: z20.string().optional(),
|
|
1146
|
+
code: z20.string().min(1),
|
|
1147
|
+
message: z20.string().min(1)
|
|
1148
|
+
});
|
|
1149
|
+
var ValidationReport = z20.object({
|
|
1150
|
+
ok: z20.boolean(),
|
|
1151
|
+
issues: z20.array(DefinitionIssue)
|
|
1152
|
+
});
|
|
1153
|
+
|
|
1154
|
+
// src/governance.ts
|
|
1155
|
+
import { z as z21 } from "zod";
|
|
1156
|
+
var DefinitionKind = z21.enum(["workflow", "rule", "rule_set", "collection_flow"]);
|
|
1157
|
+
var DEFINITION_PATHS = {
|
|
1158
|
+
workflow: "/workflow-definitions",
|
|
1159
|
+
rule: "/rule-definitions",
|
|
1160
|
+
rule_set: "/rule-sets",
|
|
1161
|
+
collection_flow: "/collection-flows"
|
|
1162
|
+
};
|
|
1163
|
+
var ApprovalDecision = z21.enum(["approved", "rejected"]);
|
|
1164
|
+
var DefinitionApproval = z21.object({
|
|
1165
|
+
id: Id,
|
|
1166
|
+
tenantId: Id,
|
|
1167
|
+
kind: DefinitionKind,
|
|
1168
|
+
key: DefinitionKey,
|
|
1169
|
+
version: z21.number().int().positive(),
|
|
1170
|
+
requestedBy: z21.string().min(1),
|
|
1171
|
+
requestedAt: z21.coerce.date(),
|
|
1172
|
+
comment: z21.string().nullish(),
|
|
1173
|
+
decidedBy: z21.string().nullish(),
|
|
1174
|
+
decidedAt: z21.coerce.date().nullish(),
|
|
1175
|
+
decision: ApprovalDecision.nullish(),
|
|
1176
|
+
decisionComment: z21.string().nullish()
|
|
1177
|
+
});
|
|
1178
|
+
var ApprovalCommentInput = z21.object({ comment: z21.string().max(2e3).optional() });
|
|
1179
|
+
var DefinitionVersionSummary = z21.object({
|
|
1180
|
+
kind: DefinitionKind,
|
|
1181
|
+
key: DefinitionKey,
|
|
1182
|
+
version: z21.number().int().positive(),
|
|
1183
|
+
status: DefinitionStatus,
|
|
1184
|
+
name: z21.string(),
|
|
1185
|
+
createdBy: z21.string().nullish(),
|
|
1186
|
+
createdAt: z21.coerce.date(),
|
|
1187
|
+
updatedAt: z21.coerce.date(),
|
|
1188
|
+
/** The open or latest approval for this version, when any. */
|
|
1189
|
+
approval: DefinitionApproval.nullish()
|
|
1190
|
+
});
|
|
1191
|
+
var DiffOp = z21.enum(["added", "removed", "changed", "moved"]);
|
|
1192
|
+
var DiffChange = z21.object({
|
|
1193
|
+
op: DiffOp,
|
|
1194
|
+
/** Dotted path into the compared document, e.g. `definition.steps.idv.next`. */
|
|
1195
|
+
path: z21.string(),
|
|
1196
|
+
summary: z21.string().min(1),
|
|
1197
|
+
before: z21.unknown().optional(),
|
|
1198
|
+
after: z21.unknown().optional()
|
|
1199
|
+
});
|
|
1200
|
+
var DefinitionDiff = z21.object({
|
|
1201
|
+
kind: DefinitionKind,
|
|
1202
|
+
key: DefinitionKey,
|
|
1203
|
+
from: z21.number().int().positive(),
|
|
1204
|
+
to: z21.number().int().positive(),
|
|
1205
|
+
changes: z21.array(DiffChange),
|
|
1206
|
+
/** Raw jsondiffpatch delta, for renderers that show the full tree. */
|
|
1207
|
+
delta: z21.unknown()
|
|
1208
|
+
});
|
|
1209
|
+
var AuditExportFormat = z21.enum(["csv", "jsonl"]);
|
|
1210
|
+
var AuditFilter = z21.object({
|
|
1211
|
+
/** Prefix match on the dotted action, e.g. `case.` or `case.note.added`. */
|
|
1212
|
+
action: z21.string().min(1).max(200).optional(),
|
|
1213
|
+
actorId: z21.string().min(1).optional(),
|
|
1214
|
+
actorType: ActorType.optional(),
|
|
1215
|
+
resourceType: z21.string().min(1).optional(),
|
|
1216
|
+
resourceId: z21.string().min(1).optional(),
|
|
1217
|
+
from: z21.coerce.date().optional(),
|
|
1218
|
+
to: z21.coerce.date().optional()
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
// src/errors.ts
|
|
1222
|
+
var AletheiaError = class extends Error {
|
|
1223
|
+
constructor(message, code, status = 500, details) {
|
|
1224
|
+
super(message);
|
|
1225
|
+
this.code = code;
|
|
1226
|
+
this.status = status;
|
|
1227
|
+
this.details = details;
|
|
1228
|
+
this.name = new.target.name;
|
|
1229
|
+
}
|
|
1230
|
+
code;
|
|
1231
|
+
status;
|
|
1232
|
+
details;
|
|
1233
|
+
};
|
|
1234
|
+
var NotFoundError = class extends AletheiaError {
|
|
1235
|
+
constructor(resource, id) {
|
|
1236
|
+
super(`${resource} ${id} not found`, "not_found", 404);
|
|
1237
|
+
}
|
|
1238
|
+
};
|
|
1239
|
+
var ValidationError = class extends AletheiaError {
|
|
1240
|
+
constructor(message, details) {
|
|
1241
|
+
super(message, "validation_error", 400, details);
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
var ConflictError = class extends AletheiaError {
|
|
1245
|
+
constructor(message) {
|
|
1246
|
+
super(message, "conflict", 409);
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
var NotImplementedError = class extends AletheiaError {
|
|
1250
|
+
constructor(feature) {
|
|
1251
|
+
super(`${feature} is not implemented yet`, "not_implemented", 501);
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
var TimeoutError = class extends AletheiaError {
|
|
1255
|
+
constructor(operation, timeoutMs) {
|
|
1256
|
+
super(`${operation} timed out after ${timeoutMs}ms`, "timeout", 504);
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
// src/ids.ts
|
|
1261
|
+
function createId() {
|
|
1262
|
+
return globalThis.crypto.randomUUID();
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// src/logger.ts
|
|
1266
|
+
var noopLogger = {
|
|
1267
|
+
debug: () => void 0,
|
|
1268
|
+
info: () => void 0,
|
|
1269
|
+
warn: () => void 0,
|
|
1270
|
+
error: () => void 0,
|
|
1271
|
+
child: () => noopLogger
|
|
1272
|
+
};
|
|
1273
|
+
export {
|
|
1274
|
+
Actor,
|
|
1275
|
+
ActorType,
|
|
1276
|
+
AddListEntriesInput,
|
|
1277
|
+
AggregationPolicy,
|
|
1278
|
+
AletheiaError,
|
|
1279
|
+
ApprovalCommentInput,
|
|
1280
|
+
ApprovalDecision,
|
|
1281
|
+
ApprovalSettings,
|
|
1282
|
+
AssignCaseInput,
|
|
1283
|
+
AuditEvent,
|
|
1284
|
+
AuditExportFormat,
|
|
1285
|
+
AuditFilter,
|
|
1286
|
+
Backtest,
|
|
1287
|
+
BacktestProgress,
|
|
1288
|
+
BacktestSample,
|
|
1289
|
+
BacktestSampleFailure,
|
|
1290
|
+
BacktestStatus,
|
|
1291
|
+
BacktestSummary,
|
|
1292
|
+
BaseEntity,
|
|
1293
|
+
BranchStep,
|
|
1294
|
+
CallPluginStep,
|
|
1295
|
+
Case,
|
|
1296
|
+
CaseFilter,
|
|
1297
|
+
CaseNote,
|
|
1298
|
+
CaseNoteInput,
|
|
1299
|
+
CasePriority,
|
|
1300
|
+
CaseQueue,
|
|
1301
|
+
CaseSettings,
|
|
1302
|
+
CaseSlaState,
|
|
1303
|
+
CaseSort,
|
|
1304
|
+
CaseStatus,
|
|
1305
|
+
CaseView,
|
|
1306
|
+
CloseCaseInput,
|
|
1307
|
+
CollectionFlowBody,
|
|
1308
|
+
CollectionFlowDefinition,
|
|
1309
|
+
CollectionSubmission,
|
|
1310
|
+
CollectionSubmitted,
|
|
1311
|
+
Condition,
|
|
1312
|
+
ConditionOp,
|
|
1313
|
+
ConfigurePluginInput,
|
|
1314
|
+
ConflictError,
|
|
1315
|
+
CreateCaseStep,
|
|
1316
|
+
CreateDocumentInput,
|
|
1317
|
+
CreateSubjectInput,
|
|
1318
|
+
CreateSubmissionInput,
|
|
1319
|
+
DEFAULT_LINK_TTL_SECONDS,
|
|
1320
|
+
DEFINITION_PATHS,
|
|
1321
|
+
DEV_TENANT_ID,
|
|
1322
|
+
DOCUMENT_CONTENT_TYPES,
|
|
1323
|
+
DOCUMENT_MAX_BYTES,
|
|
1324
|
+
DOCUMENT_OPEN_STATUSES,
|
|
1325
|
+
DecideCaseInput,
|
|
1326
|
+
Decision,
|
|
1327
|
+
DecisionOutcome,
|
|
1328
|
+
DecisionReason,
|
|
1329
|
+
DecisionSource,
|
|
1330
|
+
DefinitionApproval,
|
|
1331
|
+
DefinitionDiff,
|
|
1332
|
+
DefinitionIssue,
|
|
1333
|
+
DefinitionKey,
|
|
1334
|
+
DefinitionKind,
|
|
1335
|
+
DefinitionStatus,
|
|
1336
|
+
DefinitionVersionSummary,
|
|
1337
|
+
DiffChange,
|
|
1338
|
+
DiffOp,
|
|
1339
|
+
DirectoryUser,
|
|
1340
|
+
Document,
|
|
1341
|
+
DocumentContentType,
|
|
1342
|
+
DocumentDownload,
|
|
1343
|
+
DocumentScan,
|
|
1344
|
+
DocumentStatus,
|
|
1345
|
+
DocumentUploadTicket,
|
|
1346
|
+
EmitDecisionStep,
|
|
1347
|
+
EvaluateRulesStep,
|
|
1348
|
+
Event,
|
|
1349
|
+
EventKey,
|
|
1350
|
+
Field,
|
|
1351
|
+
FieldOption,
|
|
1352
|
+
FieldType,
|
|
1353
|
+
FieldTypeDescription,
|
|
1354
|
+
FieldValidation,
|
|
1355
|
+
FileFieldValue,
|
|
1356
|
+
FlowStep,
|
|
1357
|
+
FormUiHints,
|
|
1358
|
+
Id,
|
|
1359
|
+
IngestEventsInput,
|
|
1360
|
+
IngestEventsResult,
|
|
1361
|
+
IssueSeverity,
|
|
1362
|
+
JsonObject,
|
|
1363
|
+
List,
|
|
1364
|
+
ListEntry,
|
|
1365
|
+
ListImportResult,
|
|
1366
|
+
ListKind,
|
|
1367
|
+
MAX_LINK_TTL_SECONDS,
|
|
1368
|
+
ManualDecision,
|
|
1369
|
+
NewEvent,
|
|
1370
|
+
NewListEntry,
|
|
1371
|
+
NotFoundError,
|
|
1372
|
+
NotImplementedError,
|
|
1373
|
+
OutcomeChange,
|
|
1374
|
+
PluginCallback,
|
|
1375
|
+
PluginCallbackSignal,
|
|
1376
|
+
PluginCallbackStatus,
|
|
1377
|
+
PluginDefinition,
|
|
1378
|
+
PluginInvocation,
|
|
1379
|
+
PluginInvocationStatus,
|
|
1380
|
+
RemoveListEntriesInput,
|
|
1381
|
+
RuleDefinition,
|
|
1382
|
+
RuleEvaluation,
|
|
1383
|
+
RuleEvaluationResult,
|
|
1384
|
+
RuleOutcome,
|
|
1385
|
+
RuleSetBody,
|
|
1386
|
+
RuleSetDefinition,
|
|
1387
|
+
RuleSetRule,
|
|
1388
|
+
RuleSetUseCase,
|
|
1389
|
+
RuleSeverity,
|
|
1390
|
+
RuleType,
|
|
1391
|
+
RunDefinitionInput,
|
|
1392
|
+
SYSTEM_ACTOR,
|
|
1393
|
+
SaveSubmissionInput,
|
|
1394
|
+
ScoreBand,
|
|
1395
|
+
ScoreClamp,
|
|
1396
|
+
SortOrder,
|
|
1397
|
+
StartBacktestInput,
|
|
1398
|
+
StartWorkflowRunInput,
|
|
1399
|
+
StepTypeDescription,
|
|
1400
|
+
Subject,
|
|
1401
|
+
SubjectKind,
|
|
1402
|
+
SubjectListQuery,
|
|
1403
|
+
SubjectStatus,
|
|
1404
|
+
SubmissionStatus,
|
|
1405
|
+
Tenant,
|
|
1406
|
+
TenantContext,
|
|
1407
|
+
TenantSettings,
|
|
1408
|
+
TimelineEntry,
|
|
1409
|
+
TimelineKind,
|
|
1410
|
+
TimelineQuery,
|
|
1411
|
+
TimeoutError,
|
|
1412
|
+
Timestamps,
|
|
1413
|
+
UpsertCaseQueueInput,
|
|
1414
|
+
UpsertCollectionFlowInput,
|
|
1415
|
+
UpsertListInput,
|
|
1416
|
+
UpsertRuleDefinitionInput,
|
|
1417
|
+
UpsertRuleSetInput,
|
|
1418
|
+
UpsertWorkflowDefinitionInput,
|
|
1419
|
+
ValidationError,
|
|
1420
|
+
ValidationReport,
|
|
1421
|
+
WaitForCollectionStep,
|
|
1422
|
+
WebOrigin,
|
|
1423
|
+
WebhookEventRecord,
|
|
1424
|
+
WorkflowDefinition,
|
|
1425
|
+
WorkflowDefinitionBody,
|
|
1426
|
+
WorkflowRun,
|
|
1427
|
+
WorkflowRunStatus,
|
|
1428
|
+
WorkflowStep,
|
|
1429
|
+
WorkflowTrigger,
|
|
1430
|
+
WorkflowUi,
|
|
1431
|
+
bandFor,
|
|
1432
|
+
caseSlaState,
|
|
1433
|
+
createId,
|
|
1434
|
+
evaluateCondition,
|
|
1435
|
+
getPath,
|
|
1436
|
+
noopLogger,
|
|
1437
|
+
normalizeListValue,
|
|
1438
|
+
stepTargets,
|
|
1439
|
+
systemContext,
|
|
1440
|
+
temporalWorkflowId
|
|
1441
|
+
};
|
|
1442
|
+
//# sourceMappingURL=index.js.map
|