@dossier-wiki/os-sdk 0.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +488 -7
- package/dist/alert-workflow-types.d.ts +113 -0
- package/dist/alert-workflow-types.d.ts.map +1 -0
- package/dist/alert-workflow-types.js +2 -0
- package/dist/alert-workflow-types.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/service.d.ts +660 -10
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +962 -79
- package/dist/service.js.map +1 -1
- package/dist/types.d.ts +2760 -132
- package/dist/types.d.ts.map +1 -1
- package/docs/REFERENCE.md +488 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ const os = new DossiersOSAPIService({
|
|
|
22
22
|
|
|
23
23
|
const customer = await os.individuals.get('cus_123', { isExternal: true });
|
|
24
24
|
|
|
25
|
-
await os.individuals.identificationDocuments.
|
|
25
|
+
await os.individuals.identificationDocuments.create(customer.id, {
|
|
26
26
|
type: 'passport',
|
|
27
27
|
number: 'X1234567',
|
|
28
28
|
country: 'USA',
|
|
@@ -42,21 +42,463 @@ The service composes resource namespaces — call them off the root client:
|
|
|
42
42
|
| Namespace | Covers |
|
|
43
43
|
| --- | --- |
|
|
44
44
|
| `os.auth` | Invitations, session tokens, API keys, admin password reset |
|
|
45
|
+
| `os.sessions` | Read and manage transaction-monitoring sessions resolved during ingestion |
|
|
46
|
+
| `os.channelEndpoints` | Read and manage POS terminal, page, API client, and other endpoint identities resolved during ingestion |
|
|
45
47
|
| `os.individuals` | Individual customers + nested `identificationDocuments`, `faceImages` |
|
|
46
48
|
| `os.entities` | Entity customers + nested `stakeholders` |
|
|
47
|
-
| `os.customers` | Cross-cutting per-customer: `notes`, `files`, `screening`, `riskRating`, `
|
|
49
|
+
| `os.customers` | Cross-cutting per-customer: `notes`, `files`, `screening`, `riskRating`, `riskAssessments`, `expectedActivity`, `devices`, `assignment` (assign / unassign / assignMany) |
|
|
50
|
+
| `os.teams` | Domain teams: list/get/create/update/archive/delete, plus `addMembers` / `removeMembers`. Teams carry catalogue-governed `team.tags`, and `list({ tags })` filters on them |
|
|
48
51
|
| `os.accounts` | Per-customer accounts, including `freeze` / `unfreeze` |
|
|
49
52
|
| `os.counterparties` | Counterparties + nested `riskAssessments`, `files` |
|
|
50
|
-
| `os.
|
|
51
|
-
| `os.
|
|
52
|
-
| `os.
|
|
53
|
+
| `os.partyRelationships` | Define, list, create, and end audited named relationships between Customers and Counterparties |
|
|
54
|
+
| `os.devices` | Safe canonical Device lookup and audited merge; raw fingerprint/IP identity material is never returned |
|
|
55
|
+
| `os.paymentInstruments` | Explicit Payment Instrument CRUD and temporal Account/Customer relationships |
|
|
56
|
+
| `os.transactions` | Ingest transactions with canonical Payment Instrument, channel endpoint, device, and session context (the response carries the resolved `transaction`; optionally with catalogue-governed `tags`, e.g. `['top-up']`, readable by rules as `txn.tags` and filterable inside aggregates); patch terminal status; `get(reference)` to read one back (by your reference, or `{ by: 'id' }` for the internal UUID) |
|
|
57
|
+
| `os.transactionAttempts` | Ingest, filter, paginate, and read failed, blocked, or unknown payment-operation attempts |
|
|
58
|
+
| `os.behaviorSettings` | Attempt retention and ingestion coverage |
|
|
59
|
+
| `os.events` | Event ingestion — every event names the single `resource` it is about |
|
|
60
|
+
| `os.riskSignals` | Add time-decaying risk evidence to a resource; read a resource's signals and their aggregate effective weight |
|
|
61
|
+
| `os.employees` | People acting inside the institution's ecosystem — list/get/create/update |
|
|
62
|
+
| `os.branches` | The institution's own physical or organizational units — list/get/create/update |
|
|
53
63
|
| `os.exchangeRates` | Push exchange rates |
|
|
54
|
-
| `os.
|
|
64
|
+
| `os.states` | Read and atomically set, increment, or decrement resource state; read immutable change history |
|
|
65
|
+
| `os.alerts` | Raise alerts by hand (`create` — free-form, or against an optional custom alert type; org-scoped `externalRequestId` idempotency), read any alert (`get`), edit markdown `notes` (`updateNotes`), link records (`resources.list/add/remove`), plus `comments` and `attemptEvidence`. Needs the `alerts:read` / `alerts:write` API-key permissions |
|
|
66
|
+
| `os.config` | `rules` (incl. `rules.backtest` — dry-run simulation over historical or synthetic transactions), `constants`, `states`, `alertWorkflows` (one per alert type — `SCREENING`, `RULE_TRIGGER`, `CUSTOM`: list/get/save), `assignmentPolicies` (read-only legacy archive), `products`, `currencies`, `eventDefinitions`, `customAlertTypes` (org-defined alert types with a typed-field schema), `webhooks`, `tagCatalogue`, `sync`, plus org-wide `reset` |
|
|
55
67
|
| `os.setup` | Org setup status + initialization |
|
|
56
|
-
| `os.settings` | Sync
|
|
68
|
+
| `os.settings` | Sync snapshots + drift |
|
|
69
|
+
| `os.reports` | On-demand PDF reports: `alert`, `customerProfile`, `counterpartyProfile`, `resourceProfile` — each resolves to the PDF bytes (`Uint8Array`); needs the `report:read` grant |
|
|
70
|
+
| `os.customLists` | Custom screening lists: list/entry CRUD, ≤500-row bulk import (per-row rejection + `externalRef` upsert), enable/disable, archive/unarchive. Enabled LIVE lists are checked by every screening run alongside external providers. |
|
|
57
71
|
|
|
58
72
|
See [docs/REFERENCE.md](./docs/REFERENCE.md) for the full method list and endpoint mapping.
|
|
59
73
|
|
|
74
|
+
### Transaction attempts
|
|
75
|
+
|
|
76
|
+
Use a transaction attempt when an operation did not become a transaction in
|
|
77
|
+
the source/core system. Attempts are idempotent behavioural records; ingesting
|
|
78
|
+
one does not run rules and does not contribute to transaction financial totals.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
await os.transactionAttempts.ingest({
|
|
82
|
+
attemptId: 'auth-20260828-0042',
|
|
83
|
+
timestamp: '2026-08-28T10:30:00Z',
|
|
84
|
+
operation: 'CARD_AUTHORIZATION',
|
|
85
|
+
outcome: {
|
|
86
|
+
type: 'FAILED',
|
|
87
|
+
code: 'DO_NOT_HONOUR',
|
|
88
|
+
retryable: true,
|
|
89
|
+
final: true,
|
|
90
|
+
},
|
|
91
|
+
amount: { amountMinor: 12500, currency: 'FIAT:USD', precision: 2 },
|
|
92
|
+
paymentInstrument: {
|
|
93
|
+
type: 'CARD',
|
|
94
|
+
iin: '424242',
|
|
95
|
+
last4: '4242',
|
|
96
|
+
// A fingerprint lookup miss is retained as an unresolved attempt;
|
|
97
|
+
// it never creates a Payment Instrument.
|
|
98
|
+
fingerprint: { type: 'CARD_PAN', value: '4242424242424242' },
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const failedAuthorizations = await os.transactionAttempts.list({
|
|
103
|
+
outcomes: ['FAILED', 'BLOCKED'],
|
|
104
|
+
operation: 'CARD_AUTHORIZATION',
|
|
105
|
+
limit: 50,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
await os.behaviorSettings.update({
|
|
109
|
+
attemptRetentionDays: 180,
|
|
110
|
+
attemptCoverage: 'ALL',
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Raw fingerprint values are accepted only in the typed `fingerprint` field and
|
|
115
|
+
are protected in memory for lookup; they are never retained in the attempt.
|
|
116
|
+
Other snapshot objects must contain safe descriptors only.
|
|
117
|
+
|
|
118
|
+
For a resolved transaction, `paymentInstrument` uses the same identity shape
|
|
119
|
+
and creates the Payment Instrument on a deterministic lookup miss.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
await os.transactions.ingest({
|
|
123
|
+
transactionId: 'txn-20260828-0043',
|
|
124
|
+
timestamp: '2026-08-28T10:31:00Z',
|
|
125
|
+
transaction,
|
|
126
|
+
paymentInstrument: {
|
|
127
|
+
type: 'CARD',
|
|
128
|
+
fingerprint: { type: 'CARD_PAN', value: '4242424242424242' },
|
|
129
|
+
},
|
|
130
|
+
device: {
|
|
131
|
+
fingerprint: 'visitor-91f2',
|
|
132
|
+
ipSessions: [{ ipAddress: '203.0.113.8', seenAt: '2026-08-28T10:31:00Z' }],
|
|
133
|
+
location: { latitude: 6.9271, longitude: 79.8612, accuracyMeters: 25, source: 'GEOLOCATION' },
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Events and Risk Signals
|
|
139
|
+
|
|
140
|
+
### Every event names its resource
|
|
141
|
+
|
|
142
|
+
An Event is about exactly one resource, named explicitly:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
const { id, resource, riskSignalIds } = await os.events.ingest({
|
|
146
|
+
eventId: 'evt-20260829-teller-001',
|
|
147
|
+
type: 'security.pin_reset',
|
|
148
|
+
timestamp: '2026-08-29T02:14:33.000Z',
|
|
149
|
+
resource: { type: 'EMPLOYEE', id: 'emp_9f21' },
|
|
150
|
+
fields: [{ key: 'channel', type: 'TEXT', value: 'BRANCH_TERMINAL' }],
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`resource.type` is one of `CUSTOMER`, `ACCOUNT`, `COUNTERPARTY`, `EMPLOYEE`,
|
|
155
|
+
`BRANCH`, `PAYMENT_INSTRUMENT` — the closed set of attachable resources. There
|
|
156
|
+
is no `INSTRUMENT` spelling; `PAYMENT_INSTRUMENT` is the only instrument
|
|
157
|
+
concept.
|
|
158
|
+
|
|
159
|
+
A bare top-level `customerId` is still accepted as the **legacy spelling** of
|
|
160
|
+
`resource: { type: 'CUSTOMER', id }`, so existing integrations keep working:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
// legacy — still accepted, equivalent to resource: { type: 'CUSTOMER', id }
|
|
164
|
+
await os.events.ingest({ type: 'customer.failed_login', timestamp, customerId: 'cus_123' });
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`resource` wins when both are sent, and alongside a non-customer `resource` the
|
|
168
|
+
`customerId` is context that customer-scoped event aggregates read. An event
|
|
169
|
+
naming neither is rejected with 400. Prefer `resource` in new integrations —
|
|
170
|
+
it is the only way to attach an event to an account, counterparty, employee,
|
|
171
|
+
branch, or payment instrument.
|
|
172
|
+
|
|
173
|
+
The response echoes the resolved `resource` and the `riskSignalIds` the event
|
|
174
|
+
emitted. `deviceId` and `sessionId` may still qualify an event but never
|
|
175
|
+
substitute for its primary resource.
|
|
176
|
+
|
|
177
|
+
### Risk Signals — evidence, not alerts
|
|
178
|
+
|
|
179
|
+
A Risk Signal is a piece of time-decaying evidence attached to one resource.
|
|
180
|
+
Adding one creates **no** alert, notification, assignment or task, and does not
|
|
181
|
+
change the resource's Risk Rating. Rules read the aggregate and decide.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
await os.riskSignals.create({
|
|
185
|
+
externalId: 'case-note:2026-08-29:customer-2847:1',
|
|
186
|
+
type: 'analyst.concerning_account_behaviour',
|
|
187
|
+
resourceType: 'CUSTOMER',
|
|
188
|
+
resourceId: 'cus_2847',
|
|
189
|
+
weight: 35,
|
|
190
|
+
halfLife: 'P14D',
|
|
191
|
+
note: 'Third unexplained cash deposit this month.',
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const signals = await os.riskSignals.list({
|
|
195
|
+
resourceType: 'CUSTOMER',
|
|
196
|
+
resourceId: 'cus_2847',
|
|
197
|
+
asOf: '2026-09-12T00:00:00Z',
|
|
198
|
+
type: ['analyst.concerning_account_behaviour'],
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
signals.aggregateEffectiveWeight; // decayed sum at `asOf`
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The signal records the strength it had at `occurredAt` and how fast that
|
|
205
|
+
strength halves:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
effectiveWeight = weight * 2 ^ (-ageSeconds / halfLifeSeconds)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
So weight 40 with half-life `P7D` reads 20 after seven days and 10 after
|
|
212
|
+
fourteen. The aggregate is computed on read as of `asOf` (defaulting to server
|
|
213
|
+
time) — it is never a cached score column, so a historical `asOf` returns what
|
|
214
|
+
the resource looked like at that moment. `type` / `sourceType` filter which
|
|
215
|
+
records contribute; they never change how far a contributing signal has
|
|
216
|
+
decayed.
|
|
217
|
+
|
|
218
|
+
`externalId` makes retries safe. The server always sets the source to `MANUAL`
|
|
219
|
+
and captures the authenticated actor — a caller cannot claim a signal came from
|
|
220
|
+
an Event or a Rule. Half-lives are positive ISO 8601 durations; calendar units
|
|
221
|
+
(Y/M) are rejected because they have no fixed length.
|
|
222
|
+
|
|
223
|
+
### Emitting signals from event definitions
|
|
224
|
+
|
|
225
|
+
An event definition can declare the signals every valid occurrence emits. This
|
|
226
|
+
is tenant configuration — an integration pushing an event cannot add, change,
|
|
227
|
+
or suppress an effect.
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
await os.config.eventDefinitions.create({
|
|
231
|
+
name: 'security.pin_reset',
|
|
232
|
+
category: 'AUTHENTICATION',
|
|
233
|
+
riskSignalEffects: [
|
|
234
|
+
{ type: 'authentication.pin_reset', weight: 20, halfLife: 'P3D' },
|
|
235
|
+
],
|
|
236
|
+
});
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
`target` defaults to `EVENT_RESOURCE` — the signal attaches to the event's own
|
|
240
|
+
primary resource. The event and its signals are written in one transaction, and
|
|
241
|
+
the event's idempotency covers them: replaying an `eventId` echoes the original
|
|
242
|
+
`riskSignalIds` rather than emitting a second set.
|
|
243
|
+
|
|
244
|
+
### Emitting signals from rules
|
|
245
|
+
|
|
246
|
+
`ADD_RISK_SIGNAL` records evidence when a rule fires:
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
await os.config.rules.create({
|
|
250
|
+
name: 'Rapid counterparty fan-out',
|
|
251
|
+
subject: 'TRANSACTION',
|
|
252
|
+
severity: 'MEDIUM',
|
|
253
|
+
actions: [
|
|
254
|
+
{
|
|
255
|
+
type: 'ADD_RISK_SIGNAL',
|
|
256
|
+
signalType: 'behaviour.counterparty_fan_out',
|
|
257
|
+
weight: 25,
|
|
258
|
+
halfLife: 'P7D',
|
|
259
|
+
target: { resource: 'counterparty' },
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
`target.resource` is a closed selector over the evaluation, never a field
|
|
266
|
+
expression: `customer`, `account`, `counterparty`, or `paymentInstrument`.
|
|
267
|
+
`employee` and `branch` are **not** accepted — no evaluation envelope resolves
|
|
268
|
+
either slot yet, so such a rule could never fire; both are rejected at save
|
|
269
|
+
time with a 400 explaining why.
|
|
270
|
+
|
|
271
|
+
Unlike other action types, `ADD_RISK_SIGNAL` may appear more than once on a
|
|
272
|
+
rule (one rule can record several kinds of evidence, or the same evidence
|
|
273
|
+
against several resources). What is rejected is the same `signalType` on the
|
|
274
|
+
same `target.resource` twice — that would double-count in every aggregate.
|
|
275
|
+
|
|
276
|
+
### Employees and Branches
|
|
277
|
+
|
|
278
|
+
Employees and Branches are monitored domain data describing the institution's
|
|
279
|
+
own operating structure, and are attachable resources for Events and Risk
|
|
280
|
+
Signals. An Employee is deliberately **not** a Dossiers organization member: an
|
|
281
|
+
Employee need not have a Dossiers login, and an Employee id is never an
|
|
282
|
+
org-member id. `orgMemberId` is an optional link for the case where the two
|
|
283
|
+
happen to be the same person.
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
const branch = await os.branches.create({ name: 'Colombo Fort', externalBranchId: 'BR-014', country: 'LK' });
|
|
287
|
+
|
|
288
|
+
const teller = await os.employees.create({
|
|
289
|
+
fullName: 'Aruni Fernando',
|
|
290
|
+
externalEmployeeId: 'STAFF-10982',
|
|
291
|
+
jobTitle: 'Branch Teller',
|
|
292
|
+
branchId: branch.id,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
await os.riskSignals.create({
|
|
296
|
+
type: 'staff.override_pattern',
|
|
297
|
+
resourceType: 'EMPLOYEE',
|
|
298
|
+
resourceId: teller.id,
|
|
299
|
+
weight: 15,
|
|
300
|
+
halfLife: 'P30D',
|
|
301
|
+
});
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
`externalEmployeeId` / `externalBranchId` are unique within the organization
|
|
305
|
+
and let ingestion resolve a record without a Dossiers UUID round-trip.
|
|
306
|
+
|
|
307
|
+
## Customer creation (BREAKING)
|
|
308
|
+
|
|
309
|
+
`individuals.create` and `entities.create` now use the same canonical inputs as
|
|
310
|
+
GraphQL. The SDK exports `CreateIndividualInput` and `CreateEntityInput`;
|
|
311
|
+
the former `*Dto` names remain deprecated aliases.
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
await os.individuals.create({
|
|
315
|
+
externalId: 'USR-10042',
|
|
316
|
+
fullName: 'Ahmed Al-Rashidi',
|
|
317
|
+
status: 'ONBOARDING',
|
|
318
|
+
aliases: ['Ahmed Rashidi'],
|
|
319
|
+
nationality: ['KWT'],
|
|
320
|
+
countryOfResidence: ['USA'],
|
|
321
|
+
emails: [{ value: 'ahmed@example.com', primary: true }],
|
|
322
|
+
phones: [{ value: '+1-555-0142', primary: true }],
|
|
323
|
+
addresses: [{ category: 'HOME', line1: '4521 Maple Drive', country: 'USA' }],
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
await os.entities.create({
|
|
327
|
+
externalId: 'ENT-30021',
|
|
328
|
+
legalName: 'Meridian Holdings Ltd',
|
|
329
|
+
tradingNames: ['Meridian Holdings'],
|
|
330
|
+
websites: ['https://meridian.example'],
|
|
331
|
+
locations: [{ category: 'REGISTERED', line1: '42 Makarios III Avenue', country: 'CYP' }],
|
|
332
|
+
stakeholders: [{ name: 'Viktor Petrov', role: 'UBO', ownershipPercentage: 45 }],
|
|
333
|
+
});
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Synchronous initial screening
|
|
337
|
+
|
|
338
|
+
By default `create` queues the customer's INITIAL screening and returns at
|
|
339
|
+
once. Pass `{ screening: 'sync' }` to run it before the call returns; the
|
|
340
|
+
outcome and every match it surfaced arrive under `screening`, so an onboarding
|
|
341
|
+
flow can branch without polling `screening.history` or waiting for a webhook.
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
const created = await os.individuals.create(
|
|
345
|
+
{ externalId: 'USR-10043', fullName: 'Ahmed Al-Rashidi', nationality: ['KWT'] },
|
|
346
|
+
{ screening: 'sync' },
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
if (created.screening?.status === 'FAILED') {
|
|
350
|
+
// No provider configured or every provider failed. The customer exists;
|
|
351
|
+
// rerun with os.customers.screening.trigger(created.id).
|
|
352
|
+
} else if (created.screening?.alertId) {
|
|
353
|
+
// Matches found: created.screening.matches holds each hit and its
|
|
354
|
+
// disposition; auto-dismissed hits arrive as FALSE_POSITIVE.
|
|
355
|
+
} else {
|
|
356
|
+
// Clear run — no matches, no alert.
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
The same option works on `os.entities.create`. Screening failure never rolls
|
|
361
|
+
back the customer, and the response without the option is unchanged.
|
|
362
|
+
|
|
363
|
+
Migration:
|
|
364
|
+
|
|
365
|
+
- Individual names are one required `fullName`; remove `firstName`/`lastName`.
|
|
366
|
+
- Prefer `emails`/`phones` contact-entry arrays over the scalar `email`/`phone`.
|
|
367
|
+
- `nationality` and `countryOfResidence` are arrays of alpha-3 country codes.
|
|
368
|
+
- Entities use `tradingNames[]` and `locations[]` (not `tradingName`/`addresses`).
|
|
369
|
+
- On an identification document, prefer `country` over `issuingCountry`.
|
|
370
|
+
- The older spellings — scalar `email`/`phone`, `issuingCountry`, create-time
|
|
371
|
+
`createdAt`, entity `addresses`, and entity `parentEntityId` — are still
|
|
372
|
+
accepted as deprecated aliases; the canonical field wins when both are sent.
|
|
373
|
+
- Use `status` for the initial customer lifecycle state. New records default to
|
|
374
|
+
`ONBOARDING`; `monitoringStatus` and `riskRating` are not create inputs.
|
|
375
|
+
|
|
376
|
+
## Tenant sync — config-as-code (BREAKING in v0.7.0)
|
|
377
|
+
|
|
378
|
+
`os.config.sync` drives declarative tenant config (products, constants, event
|
|
379
|
+
definitions, webhooks, rules, currencies, and tenant behaviour settings). You build a `SyncConfig` and the
|
|
380
|
+
**server** validates, diffs, and applies it — clients hold no diff/apply logic.
|
|
381
|
+
This backs the `dossiers-sync` CLI.
|
|
382
|
+
|
|
383
|
+
```ts
|
|
384
|
+
import type { SyncConfig } from '@dossier-wiki/os-sdk';
|
|
385
|
+
|
|
386
|
+
const config: SyncConfig = JSON.parse(await readFile('tenant.sync.json', 'utf8'));
|
|
387
|
+
|
|
388
|
+
const { errors, warnings } = await os.config.sync.validate(config);
|
|
389
|
+
const { plan } = await os.config.sync.plan(config); // advisory preview, no writes
|
|
390
|
+
const result = await os.config.sync.apply(config); // validate → diff → apply
|
|
391
|
+
const live = await os.config.sync.export({ includeUnsynced: true }); // → SyncConfig
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
`behaviorSettings` is an optional, singleton section. Omit it to leave the
|
|
395
|
+
target tenant unmanaged; supplied fields update partially. Exports and sync
|
|
396
|
+
snapshots include the full effective policy.
|
|
397
|
+
|
|
398
|
+
**Breaking:** `os.settings.getSyncExport()` (opaque zip) was **removed** — use
|
|
399
|
+
`os.config.sync.export()`, which returns a typed `SyncConfig`. The `SyncExportDto`
|
|
400
|
+
type was removed accordingly. Snapshot/drift methods on `os.settings` are
|
|
401
|
+
unchanged; use `os.settings.downloadSyncSnapshot(id)` for audit-grade zips.
|
|
402
|
+
|
|
403
|
+
## Tag catalogue & resource tags (BREAKING)
|
|
404
|
+
|
|
405
|
+
Every resource tag field — `riskTags`, `dispositionTags`, and the `tags` on
|
|
406
|
+
addresses, rules, identification documents, customers, and counterparties — is
|
|
407
|
+
now `TagValue[]` (`{ value, label }`) instead of `string[]`. On writes you pass
|
|
408
|
+
`TagValueInput[]`; supplying `label` only lets the server derive the slug `value`:
|
|
409
|
+
|
|
410
|
+
```ts
|
|
411
|
+
await os.config.rules.create({
|
|
412
|
+
name: 'High-value wires',
|
|
413
|
+
// was: tags: ['aml', 'wire']
|
|
414
|
+
tags: [{ label: 'AML' }, { label: 'Wire' }],
|
|
415
|
+
// ...
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
A per-org **tag catalogue** defines the available vocabulary per field-key. The
|
|
420
|
+
catalogue is **closed**: a write whose value is not in the catalogue is rejected,
|
|
421
|
+
always. There is no enforcement setting to relax — register the tag first.
|
|
422
|
+
|
|
423
|
+
```ts
|
|
424
|
+
await os.config.tagCatalogue.create({ fieldKey: 'rule.tags', label: 'AML' });
|
|
425
|
+
const entries = await os.config.tagCatalogue.list({ fieldKey: 'rule.tags' });
|
|
426
|
+
const { tokens } = await os.config.tagCatalogue.palette(); // valid `color` values
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
> **Breaking change:** `setEnforcement()` / `enforcement()` and the
|
|
430
|
+
> `TagCatalogueEnforcement`, `TagFieldEnforcement`, and `SetTagEnforcementInput`
|
|
431
|
+
> types are removed. Tag vocabulary is now managed exclusively through catalogue
|
|
432
|
+
> entries and tenant config. Ad-hoc, per-record detail belongs in notes.
|
|
433
|
+
|
|
434
|
+
## Typed Fields (v0.2.0+)
|
|
435
|
+
|
|
436
|
+
> **v0.3.0 breaking change:** `IngestEventDto.data` has been removed in
|
|
437
|
+
> favour of `IngestEventDto.fields: TypedFieldValueInput[]`. Callers must
|
|
438
|
+
> pass the typed-input shape; the legacy untyped record is no longer
|
|
439
|
+
> accepted. Product DTOs no longer carry `metadata` — use `otherProperties`
|
|
440
|
+
> instead.
|
|
441
|
+
|
|
442
|
+
Accounts, products, and event ingestion accept the platform's Typed Fields
|
|
443
|
+
primitive — a typed key/value bag (`fields`) plus an untyped escape hatch
|
|
444
|
+
(`otherProperties`). Collection fields are explicit: `LIST` is open-ended,
|
|
445
|
+
while `SINGLE_SELECT` and `MULTI_SELECT` are constrained by the declared
|
|
446
|
+
`options` on the parent schema (`Product.accountFieldConfig` or
|
|
447
|
+
`EventDefinition.properties`). Legacy `SET` remains supported but is deprecated.
|
|
448
|
+
|
|
449
|
+
```ts
|
|
450
|
+
import type { TypedFieldValueInput } from '@dossier-wiki/os-sdk';
|
|
451
|
+
|
|
452
|
+
// Tier B — caller declares the type per value via the `{key, type, value}` shape.
|
|
453
|
+
await os.accounts.create('cus_123', {
|
|
454
|
+
productId: 'prod_checking_v1',
|
|
455
|
+
label: 'Primary Checking',
|
|
456
|
+
fields: [
|
|
457
|
+
{ key: 'iban', type: 'TEXT', value: 'LK39ABCD' },
|
|
458
|
+
{ key: 'rate', type: 'NUMBER', value: 0.045 },
|
|
459
|
+
{ key: 'opened', type: 'DATE', value: '2026-03-01' },
|
|
460
|
+
{ key: 'limit', type: 'MONETARY', value: '5000.00@FIAT:USD' }, // denominated literal
|
|
461
|
+
{ key: 'aliases', type: 'LIST', value: ['everyday', 'current'] },
|
|
462
|
+
],
|
|
463
|
+
otherProperties: [
|
|
464
|
+
{ key: 'sourceImportBatch', value: { id: 'batch-42', source: 'csv' } },
|
|
465
|
+
],
|
|
466
|
+
});
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
When a product declares an `accountFieldConfig` template (Tier A), the
|
|
470
|
+
runtime validator enforces type match, required keys, and unknown-key
|
|
471
|
+
rejection. Otherwise the same input shape passes through self-declaring
|
|
472
|
+
validation (Tier B) — same semantics as `txn.metadata`.
|
|
473
|
+
`typedAccountFieldConfig` remains as a deprecated API alias.
|
|
474
|
+
|
|
475
|
+
Updates apply with **merge semantics**: each supplied key overwrites; absent
|
|
476
|
+
keys preserved. Pass an empty array to clear.
|
|
477
|
+
|
|
478
|
+
Read shape on responses is the same array form. Monetary entries carry
|
|
479
|
+
pre-resolved `amountMinor` + `currency` + `precision`.
|
|
480
|
+
|
|
481
|
+
Spec: [`docs/specs/typed-fields/README.md`](../../docs/specs/typed-fields/README.md).
|
|
482
|
+
|
|
483
|
+
### Party relationships
|
|
484
|
+
|
|
485
|
+
```ts
|
|
486
|
+
const employer = await os.partyRelationships.createType({
|
|
487
|
+
key: 'employer',
|
|
488
|
+
label: 'Employer',
|
|
489
|
+
direction: 'DIRECTED',
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
await os.partyRelationships.create({
|
|
493
|
+
typeId: employer.id,
|
|
494
|
+
sourceType: 'CUSTOMER',
|
|
495
|
+
sourceId: customerId,
|
|
496
|
+
targetType: 'COUNTERPARTY',
|
|
497
|
+
targetId: employerCounterpartyId,
|
|
498
|
+
description: 'Declared during onboarding',
|
|
499
|
+
});
|
|
500
|
+
```
|
|
501
|
+
|
|
60
502
|
## Configuration
|
|
61
503
|
|
|
62
504
|
```ts
|
|
@@ -85,3 +527,42 @@ try {
|
|
|
85
527
|
## License
|
|
86
528
|
|
|
87
529
|
MIT
|
|
530
|
+
|
|
531
|
+
Screening-result dispositions stay `PENDING | CONFIRMED | FALSE_POSITIVE`. A match a workflow reviewer marked inconclusive is still undecided, so the REST API reports and filters it as `PENDING`; the inconclusive state itself is visible only in the app and GraphQL.
|
|
532
|
+
|
|
533
|
+
### Alert workflows
|
|
534
|
+
|
|
535
|
+
The application uses the same disposition cards, reason field, and optional catalogue tags for closing Simple alerts and resolving workflow alerts. Workflow resolution still requires a disposition and respects the pinned stage’s comment requirement. The GraphQL `transitionAlertReview` input accepts optional `tags: [{ value, label }]` for `RESOLVE`; tags are validated against the tenant’s `alert.dispositionTags` catalogue, stored with the disposition, and cleared on reopening.
|
|
536
|
+
|
|
537
|
+
New workflow saves require one shared **Resolved** stage. Set its `next` to a router or an automatic `action` node for follow-ups. Routers can combine `resolution.outcome` with alert, customer, screening or rule fields; after resolution, `$end` means no further action. Action nodes support `CREATE_TASK` (linked to the alert) and `NOTIFY` (in-app notification), with current alert owners or specific members/teams as recipients. Follow-ups run atomically with closure using the saved verdict and leave the alert resolved. Reopen remains a separate review action. Reopening and resolving again can run follow-ups again; retrying the same transition cannot duplicate them. Existing alerts retain their pinned definition.
|
|
538
|
+
|
|
539
|
+
Each organization has one workflow per alert type: `SCREENING` and `RULE_TRIGGER`. Initial assignment and later handovers are stage settings; routers provide ordered conditions and a fallback. Router branches may have an optional `name`, and the router may have a `fallbackName` (nonblank, up to 200 characters). These names appear in the workflow graph and routing history; they do not change branch IDs, order, or destinations. Omitting them preserves the numbered condition and fallback labels. Read the current revision before saving:
|
|
540
|
+
|
|
541
|
+
```ts
|
|
542
|
+
const workflow = await client.config.alertWorkflows.get('SCREENING');
|
|
543
|
+
await client.config.alertWorkflows.save('SCREENING', {
|
|
544
|
+
id: workflow.id,
|
|
545
|
+
name: workflow.name,
|
|
546
|
+
expectedRevision: workflow.revision,
|
|
547
|
+
definition: workflow.draft,
|
|
548
|
+
publish: false, // true publishes for future alerts
|
|
549
|
+
});
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Requires `config:read` / `config:write`. Stale saves return HTTP 409. Existing alerts keep their published version. `config.assignmentPolicies` remains available to inspect archived rules, but its write methods now return HTTP 410. The `assignmentPolicies` tenant-sync section is retired; use `config.alertWorkflows` instead. Existing assignment rules are converted automatically to the initial workflow graph.
|
|
553
|
+
|
|
554
|
+
Set `definition.restrictEditingToOwners` to `true` to make alerts read-only for everyone except currently assigned people and members of active assigned teams, including administrators. This covers assignments, match decisions, alert comments and attachments, task links, and every stage transition (including return and reopen), overriding the progression-only policy. Omitting it or setting it to `false` preserves existing editing permissions. The policy is pinned when the alert is created; publishing does not change older alerts or Simple alerts. Linked tasks retain their own editing permissions. Organization admins and owners can explicitly add themselves through the application’s **Assign to me** action (`takeOverAlert` in GraphQL). This administrative recovery preserves all other assignees, status and pinned workflow settings, and is recorded in activity history; it also supports resolved alerts so an administrator can assume ownership before reopening.
|
|
555
|
+
|
|
556
|
+
Set `definition.restrictProgressionToOwners` to `true` to limit forward progression (including resolution) to currently assigned people and members of active assigned teams. Administrators must also be assigned. Set it to `false` to allow other organization members with `alert:update` permission to progress alerts. Stage requirements still apply. Return and reopen permissions are unchanged. Omitting the field preserves the original current-reviewers-or-administrators behavior for older API clients and stored definitions. The builder defaults the policy to enabled when editing; publishing affects new alerts only.
|
|
557
|
+
|
|
558
|
+
For Screening workflows, `definition.matchAssessment` sets shared `{ note, attachment }` booleans for `CONFIRMED`, `INCONCLUSIVE`, and `FALSE_POSITIVE`. These apply to every Initial Review stage; set each stage's legacy `screening` field to `null`. Rule Trigger workflows must omit `matchAssessment`. Older definitions that omit it retain their stage-specific requirements. The builder's General policy tab consolidates older stage requirements into a shared draft, preserving the strictest requirement where they differ. Publishing never updates existing alerts.
|
|
559
|
+
|
|
560
|
+
### Linking comments to screening matches
|
|
561
|
+
|
|
562
|
+
Attach screening matches explicitly with `links: { matchIds: ["<match UUID>"] }` when creating or updating an alert comment. A comment can attach multiple matches belonging to that alert. Comment responses include `matchReferences` with each match's ID, category and saved display name. Editing the body preserves attachments unless `links` is supplied; `links: { matchIds: [] }` detaches all matches. Mentions in the body do not create associations. Existing saved associations and historical match labels are preserved.
|
|
563
|
+
|
|
564
|
+
### Alert experience
|
|
565
|
+
|
|
566
|
+
Use `client.config.alertWorkflows.getExperience()` to read the tenant's choice and revision. `saveExperience({ experience: 'SIMPLE' | 'DEFINED', expectedRevision })` changes only newly created alerts, across both supported alert types. Simple uses direct assignment and Open/Closed resolution; Defined uses the published workflow for the alert type. Existing alerts retain their process and policy version. Saved definitions are retained in Simple mode, and publishing a definition does not enable Defined mode. The initial default is Simple. Select Defined explicitly to enable the published workflow for new alerts. Existing saved choices are preserved when upgrading.
|
|
567
|
+
|
|
568
|
+
Published workflow history is available through `config.alertWorkflows.versions(alertType)` (newest first, with publisher and date). `config.alertWorkflows.restore(alertType, { version, expectedRevision })` copies a version into the draft without changing the published workflow or existing alerts. Review the returned draft, then call `save` with `publish: true` and its updated revision to publish it as a new version. Old versions with no recoverable definition return `definition: null` and cannot be restored. Both operations are organization-scoped and require `config:read` / `config:write` respectively.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/** Shared JSON wire contract. The backend validates this structure before saving. */
|
|
2
|
+
export type WorkflowAlertType = "SCREENING" | "RULE_TRIGGER" | "CUSTOM";
|
|
3
|
+
export type WorkflowStageGroup = "INITIAL_REVIEW" | "SECONDARY_REVIEW" | "RESOLVED";
|
|
4
|
+
export interface WorkflowCondition {
|
|
5
|
+
field: string;
|
|
6
|
+
operator: string;
|
|
7
|
+
value: string;
|
|
8
|
+
/** Compare to another available field instead of a literal. */
|
|
9
|
+
valueField?: string;
|
|
10
|
+
whenMissing?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface WorkflowConditions {
|
|
13
|
+
logic: "AND" | "OR";
|
|
14
|
+
conditions: WorkflowCondition[];
|
|
15
|
+
}
|
|
16
|
+
export interface WorkflowAssignment {
|
|
17
|
+
mode: "KEEP" | "HANDOVER" | "ADD";
|
|
18
|
+
source: "SPECIFIC" | "CUSTOMER_MEMBERS" | "CUSTOMER_TEAMS" | "CUSTOMER_OWNERS" | "ORIGINAL";
|
|
19
|
+
userIds: string[];
|
|
20
|
+
teamIds: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface ScreeningDecisionPolicy {
|
|
23
|
+
note: boolean;
|
|
24
|
+
attachment: boolean;
|
|
25
|
+
}
|
|
26
|
+
export type MatchAssessmentPolicy = Record<"CONFIRMED" | "FALSE_POSITIVE" | "INCONCLUSIVE", ScreeningDecisionPolicy>;
|
|
27
|
+
export interface WorkflowStage {
|
|
28
|
+
id: string;
|
|
29
|
+
kind: "stage";
|
|
30
|
+
name: string;
|
|
31
|
+
group: WorkflowStageGroup;
|
|
32
|
+
next: string | null;
|
|
33
|
+
actionLabel: string;
|
|
34
|
+
assignment: WorkflowAssignment;
|
|
35
|
+
conditions: WorkflowConditions;
|
|
36
|
+
requireComment: boolean;
|
|
37
|
+
requiredReviews: ("CUSTOMER_RISK" | "COUNTERPARTY_RISK")[];
|
|
38
|
+
/** Legacy stage policy. New definitions use matchAssessment and set this to null. */
|
|
39
|
+
screening: MatchAssessmentPolicy | null;
|
|
40
|
+
}
|
|
41
|
+
export interface WorkflowRouter {
|
|
42
|
+
id: string;
|
|
43
|
+
kind: "router";
|
|
44
|
+
name: string;
|
|
45
|
+
branches: {
|
|
46
|
+
id: string;
|
|
47
|
+
/** Optional display name (1–200 characters). Omission uses the condition number. */
|
|
48
|
+
name?: string;
|
|
49
|
+
conditions: WorkflowConditions;
|
|
50
|
+
target: string;
|
|
51
|
+
}[];
|
|
52
|
+
fallback: string;
|
|
53
|
+
/** Optional display name (1–200 characters). Omission displays Fallback. */
|
|
54
|
+
fallbackName?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Automatic follow-up after resolution. It never changes the alert's stage or owners. */
|
|
57
|
+
export interface WorkflowAction {
|
|
58
|
+
id: string;
|
|
59
|
+
kind: "action";
|
|
60
|
+
name: string;
|
|
61
|
+
action: "CREATE_TASK" | "NOTIFY";
|
|
62
|
+
next: string | null;
|
|
63
|
+
title: string;
|
|
64
|
+
body: string;
|
|
65
|
+
recipients: {
|
|
66
|
+
source: "ALERT_OWNERS" | "SPECIFIC";
|
|
67
|
+
userIds: string[];
|
|
68
|
+
teamIds: string[];
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export type WorkflowNode = WorkflowStage | WorkflowRouter | WorkflowAction;
|
|
72
|
+
export interface WorkflowDefinition {
|
|
73
|
+
schemaVersion: 1;
|
|
74
|
+
alertType: WorkflowAlertType;
|
|
75
|
+
/** Forward progression only. True requires a current assigned person or active-team member, including admins; false allows any organization member with alert:update. Omission preserves the original reviewers-or-admins policy. */
|
|
76
|
+
restrictProgressionToOwners?: boolean;
|
|
77
|
+
/** All alert editing requires current ownership, including administrators. Organization admins/owners may explicitly take over by adding themselves as an assignee. Overrides progression permissions. Omission/false preserves existing editing permissions. */
|
|
78
|
+
restrictEditingToOwners?: boolean;
|
|
79
|
+
/** Screening-only requirements shared by all Initial Review stages. Omission preserves legacy stage policies. */
|
|
80
|
+
matchAssessment?: MatchAssessmentPolicy;
|
|
81
|
+
entry: string;
|
|
82
|
+
/** Exactly one Resolved stage. Its optional next step runs automatically after closure.
|
|
83
|
+
* Routers and actions after resolution may use "$end" to finish without another action. */
|
|
84
|
+
nodes: WorkflowNode[];
|
|
85
|
+
}
|
|
86
|
+
export interface WorkflowPublication extends WorkflowDefinition {
|
|
87
|
+
publication?: {
|
|
88
|
+
name: string;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export interface WorkflowField {
|
|
92
|
+
key: string;
|
|
93
|
+
label: string;
|
|
94
|
+
type: "enum" | "number" | "boolean" | "set" | "string";
|
|
95
|
+
values?: string[];
|
|
96
|
+
operators: string[];
|
|
97
|
+
creation: boolean;
|
|
98
|
+
}
|
|
99
|
+
export interface WorkflowExecution {
|
|
100
|
+
version: 2;
|
|
101
|
+
workflowId: string;
|
|
102
|
+
workflowName: string;
|
|
103
|
+
publishedVersion: number;
|
|
104
|
+
definition: WorkflowDefinition;
|
|
105
|
+
stage: WorkflowStageGroup;
|
|
106
|
+
nodeId: string;
|
|
107
|
+
revision: number;
|
|
108
|
+
history: string[];
|
|
109
|
+
enteredAt: string;
|
|
110
|
+
initialUserIds: string[];
|
|
111
|
+
initialTeamIds: string[];
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=alert-workflow-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-workflow-types.d.ts","sourceRoot":"","sources":["../src/alert-workflow-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alert-workflow-types.js","sourceRoot":"","sources":["../src/alert-workflow-types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
export { DossiersOSAPIService, DossiersOSAPIError } from './service';
|
|
3
|
-
export type { DossiersOSAPIServiceOptions } from './service';
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export { DossiersOSAPIService, DossiersOSAPIError } from './service.js';
|
|
3
|
+
export type { DossiersOSAPIServiceOptions } from './service.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACxE,YAAY,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC"}
|