@ai-matrx/records 0.28.0 → 0.30.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 +28 -0
- package/dist/core/index.cjs +18 -7
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +4 -2
- package/dist/core/index.d.ts +4 -2
- package/dist/core/index.js +18 -7
- package/dist/core/index.js.map +1 -1
- package/dist/field-D08d_e7R.d.cts +3600 -0
- package/dist/field-D08d_e7R.d.ts +3600 -0
- package/dist/index.cjs +18 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3545
- package/dist/index.d.ts +3 -3545
- package/dist/index.js +18 -7
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +18 -7
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +61 -7
- package/dist/react/index.d.ts +61 -7
- package/dist/react/index.js +18 -7
- package/dist/react/index.js.map +1 -1
- package/dist/use-cases/index.cjs +2715 -0
- package/dist/use-cases/index.cjs.map +1 -0
- package/dist/use-cases/index.d.cts +447 -0
- package/dist/use-cases/index.d.ts +447 -0
- package/dist/use-cases/index.js +2699 -0
- package/dist/use-cases/index.js.map +1 -0
- package/package.json +11 -1
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { T as TableType, a as TableDisplay, S as StorageMode, F as FieldTypeWord, b as FieldSource, C as ComputeOn, c as FieldRule, d as FieldSensitivity, e as ContextPolicy, R as RelationFlavor, f as RelationCardinality, O as OnDelete } from '../field-D08d_e7R.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Who the data belongs to. A test organization is created under this name — the
|
|
5
|
+
* owner's law #4: every organization, table, record, form, portal, dashboard,
|
|
6
|
+
* document, checklist, booking page, capture sheet, subscription, pipeline and
|
|
7
|
+
* enrichment created for a test carries the use case's own name. Cleanup finds
|
|
8
|
+
* a test organization by `cleanupTag` in its settings, NEVER by a junk name.
|
|
9
|
+
*/
|
|
10
|
+
interface BusinessIdentity {
|
|
11
|
+
/** "Harbor Dental Group" — what goes on the organization, the invoice, the screenshot. */
|
|
12
|
+
name: string;
|
|
13
|
+
/** "Harbor Dental Group, PLLC" — used on documents that need the legal entity. */
|
|
14
|
+
legalName?: string;
|
|
15
|
+
/** One line a stranger would understand: "A six-chair family dental practice." */
|
|
16
|
+
describes: string;
|
|
17
|
+
/** Plausible and synthesized. Never a real business's real address. */
|
|
18
|
+
address: PostalAddress;
|
|
19
|
+
/** Synthesized, E.164-shaped or the local convention the document uses. */
|
|
20
|
+
phone: string;
|
|
21
|
+
/**
|
|
22
|
+
* Synthesized. NOT a `.example` domain — those read as fake on a screenshot.
|
|
23
|
+
* Optional, because the law welcomes personal-life use cases and a household
|
|
24
|
+
* renovation or a family recipe collection genuinely has no website.
|
|
25
|
+
*/
|
|
26
|
+
website?: string;
|
|
27
|
+
/** Synthesized mailbox on the same domain: "frontdesk@harbordentalgroup.com". */
|
|
28
|
+
email: string;
|
|
29
|
+
/** IANA zone, so dates in the rows make sense together. */
|
|
30
|
+
timezone: string;
|
|
31
|
+
}
|
|
32
|
+
interface PostalAddress {
|
|
33
|
+
line1: string;
|
|
34
|
+
line2?: string;
|
|
35
|
+
city: string;
|
|
36
|
+
/** State, province or region, in the country's own convention. */
|
|
37
|
+
region: string;
|
|
38
|
+
postalCode: string;
|
|
39
|
+
/** ISO 3166-1 alpha-2. */
|
|
40
|
+
country: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* One table of the business, in the words the practitioner uses. `token` is the
|
|
44
|
+
* slug the store addresses it by; `name` is what a person reads.
|
|
45
|
+
*/
|
|
46
|
+
interface UseCaseTable {
|
|
47
|
+
/** snake_case, singular, the practitioner's noun: "patient", "work_order". */
|
|
48
|
+
token: string;
|
|
49
|
+
/** "Patients", "Work orders". */
|
|
50
|
+
name: string;
|
|
51
|
+
labelSingular: string;
|
|
52
|
+
labelPlural: string;
|
|
53
|
+
/** REC-32. One of the seven, closed. Most business tables are `entity`. */
|
|
54
|
+
type: TableType;
|
|
55
|
+
display: TableDisplay;
|
|
56
|
+
/** REC-4. `light` is the whole document; `heavy` is indexed on write. */
|
|
57
|
+
weight: StorageMode;
|
|
58
|
+
ordered: boolean;
|
|
59
|
+
/** A lucide icon name, so the screen is not a wall of identical rows. */
|
|
60
|
+
icon?: string;
|
|
61
|
+
/** REC-2. The field key whose value titles a record. Must be a declared field. */
|
|
62
|
+
titleField: string;
|
|
63
|
+
/** What this table is FOR, in the practitioner's words. */
|
|
64
|
+
describes: string;
|
|
65
|
+
fields: UseCaseField[];
|
|
66
|
+
/** The seed rows. Enough that the screen looks like a working business. */
|
|
67
|
+
rows: UseCaseRow[];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* One field. `parityType` is the word a person picks in the UI and it must be
|
|
71
|
+
* one the store resolves — one of the thirteen parity types, one of the five
|
|
72
|
+
* behaviours, or one of the plain synonyms (see `FieldTypeWord`).
|
|
73
|
+
*/
|
|
74
|
+
interface UseCaseField {
|
|
75
|
+
/** snake_case, the practitioner's own name for it: "date_of_birth", "po_number". */
|
|
76
|
+
key: string;
|
|
77
|
+
/** "Date of birth", "PO number". Sentence case, the way the form reads. */
|
|
78
|
+
label: string;
|
|
79
|
+
parityType: FieldTypeWord;
|
|
80
|
+
/** FLD-2. The shape of the value, never a second behaviour. */
|
|
81
|
+
multi?: boolean;
|
|
82
|
+
/** FLD-2. The values carry their own dates. */
|
|
83
|
+
dated?: boolean;
|
|
84
|
+
required?: boolean;
|
|
85
|
+
/** FLD-N-1. The unit CHANGES THE MEANING and lives on the field: "USD", "lb", "mi". */
|
|
86
|
+
unit?: string | null;
|
|
87
|
+
/** "currency", "percent", "email", "phone", "url", "date". Never decoration. */
|
|
88
|
+
format?: string | null;
|
|
89
|
+
/** FLD-7. Where the values come from. Defaults to `manual`. */
|
|
90
|
+
source?: FieldSource;
|
|
91
|
+
/** FLD-9. A formula says whether it computes on read or on write. */
|
|
92
|
+
computeOn?: ComputeOn;
|
|
93
|
+
/** FLD-3. Validation rules the store will enforce. */
|
|
94
|
+
rules?: FieldRule[];
|
|
95
|
+
/**
|
|
96
|
+
* For `select` / `multi_select`: the REAL lifecycle words of this business,
|
|
97
|
+
* in the order they actually happen. "Scheduled, Confirmed, Seen, No-show" —
|
|
98
|
+
* never "Option A, Option B".
|
|
99
|
+
*/
|
|
100
|
+
choices?: string[];
|
|
101
|
+
/** For a relation field: the `token` of the table it points at. */
|
|
102
|
+
relationTarget?: string;
|
|
103
|
+
relationMax?: number;
|
|
104
|
+
/** AGT-7. The ceiling a merge field's delivery can never widen. */
|
|
105
|
+
sensitivity: FieldSensitivity;
|
|
106
|
+
/** FLD-12. Whether an agent may see this field's values at all. */
|
|
107
|
+
contextPolicy: ContextPolicy;
|
|
108
|
+
/** What the practitioner would be told about this field, if anything. */
|
|
109
|
+
help?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* One row of seed data.
|
|
113
|
+
*
|
|
114
|
+
* `key` is a stable LOCAL id (not a UUID): relationships across tables point at
|
|
115
|
+
* it, so a template is readable and a seeder can resolve the graph in one pass
|
|
116
|
+
* without inventing identifiers. Use a meaningful slug — "patient-rivera-m",
|
|
117
|
+
* not "row-7".
|
|
118
|
+
*/
|
|
119
|
+
interface UseCaseRow {
|
|
120
|
+
key: string;
|
|
121
|
+
/**
|
|
122
|
+
* Keyed by the table's field keys. A relation field's value is the `key` (or
|
|
123
|
+
* an array of keys) of rows in the target table.
|
|
124
|
+
*/
|
|
125
|
+
values: Record<string, unknown>;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* REL-1…REL-9. The domain truth, stated once: "an invoice belongs to the job it
|
|
129
|
+
* bills, and a job belongs to the client who asked for it."
|
|
130
|
+
*
|
|
131
|
+
* The field side carries `relationTarget`; this is the declaration a seeder
|
|
132
|
+
* reads, because it also carries the flavour, the cardinality, what happens to
|
|
133
|
+
* the far side on delete, and the reverse name.
|
|
134
|
+
*/
|
|
135
|
+
interface UseCaseRelationship {
|
|
136
|
+
/** One sentence of domain truth. Not "links A to B". */
|
|
137
|
+
describes: string;
|
|
138
|
+
/** The table that HOLDS the relation field. */
|
|
139
|
+
fromTable: string;
|
|
140
|
+
/** The field key on `fromTable`. Must be declared and must be a relation. */
|
|
141
|
+
fromField: string;
|
|
142
|
+
/** The `token` of the table it points at. */
|
|
143
|
+
toTable: string;
|
|
144
|
+
/** REL-1. Ownership is one fact, stored once, read from the field's side. */
|
|
145
|
+
flavor: RelationFlavor;
|
|
146
|
+
/** REL-7. */
|
|
147
|
+
cardinality: RelationCardinality;
|
|
148
|
+
/** REL-2. What happens to the far side, separate from flavour. */
|
|
149
|
+
onDelete: OnDelete;
|
|
150
|
+
/** REL-9. The reverse, visible from both ends, and NOT a second field. */
|
|
151
|
+
inverseKey: string;
|
|
152
|
+
}
|
|
153
|
+
/** Who is allowed to open a form. */
|
|
154
|
+
type FormAudience = "public" | "member" | "staff";
|
|
155
|
+
/**
|
|
156
|
+
* A form a practitioner in this business would actually put in front of someone
|
|
157
|
+
* — "the Harbor Dental new-patient intake", never "Test Form 1".
|
|
158
|
+
*/
|
|
159
|
+
interface UseCaseForm {
|
|
160
|
+
token: string;
|
|
161
|
+
name: string;
|
|
162
|
+
/** What it is for, and who fills it in. */
|
|
163
|
+
describes: string;
|
|
164
|
+
audience: FormAudience;
|
|
165
|
+
/** The table a submission becomes a record of. */
|
|
166
|
+
table: string;
|
|
167
|
+
fields: UseCaseFormField[];
|
|
168
|
+
submitLabel: string;
|
|
169
|
+
/** What the person sees after they submit. Real words, not "Success!". */
|
|
170
|
+
confirmation: string;
|
|
171
|
+
}
|
|
172
|
+
interface UseCaseFormField {
|
|
173
|
+
/** A field key on the form's table. */
|
|
174
|
+
fieldKey: string;
|
|
175
|
+
/** Override the field's own label when the form asks it differently. */
|
|
176
|
+
label?: string;
|
|
177
|
+
required?: boolean;
|
|
178
|
+
/** The helper line under the input, if a practitioner would want one. */
|
|
179
|
+
help?: string;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* The real lifecycle a record moves through in this business, in order. A
|
|
183
|
+
* pipeline's stages are the words the staff say out loud.
|
|
184
|
+
*/
|
|
185
|
+
interface UseCasePipeline {
|
|
186
|
+
token: string;
|
|
187
|
+
name: string;
|
|
188
|
+
describes: string;
|
|
189
|
+
/** The table whose records move through it. */
|
|
190
|
+
table: string;
|
|
191
|
+
/** The `select` field that holds the current stage. */
|
|
192
|
+
stageField: string;
|
|
193
|
+
stages: UseCasePipelineStage[];
|
|
194
|
+
}
|
|
195
|
+
interface UseCasePipelineStage {
|
|
196
|
+
/** Must appear in the stage field's `choices`. */
|
|
197
|
+
key: string;
|
|
198
|
+
label: string;
|
|
199
|
+
/** What is true of a record sitting here, and what moves it on. */
|
|
200
|
+
describes: string;
|
|
201
|
+
/** Roughly how long a record sits here, so a board looks believable. */
|
|
202
|
+
typicalDurationDays?: number;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The question the owner of this business actually asks a dashboard on Monday
|
|
206
|
+
* morning — "how much have we invoiced this month that hasn't been paid?" —
|
|
207
|
+
* plus how it is answered from the tables above.
|
|
208
|
+
*/
|
|
209
|
+
interface UseCaseDashboardQuestion {
|
|
210
|
+
/** The question in the practitioner's own words, ending in a question mark. */
|
|
211
|
+
question: string;
|
|
212
|
+
/** Why they care. What they DO differently depending on the answer. */
|
|
213
|
+
whyItMatters: string;
|
|
214
|
+
table: string;
|
|
215
|
+
aggregate: "count" | "sum" | "avg" | "min" | "max";
|
|
216
|
+
/** The field aggregated. Omitted only for `count`. */
|
|
217
|
+
of?: string;
|
|
218
|
+
groupBy?: string;
|
|
219
|
+
/** A plain-language filter: "status is Unpaid and due_date is before today". */
|
|
220
|
+
filter?: string;
|
|
221
|
+
/** What the number IS: "USD", "days", "appointments". */
|
|
222
|
+
answerUnit: string;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* A document this business really sends. The body carries merge fields in
|
|
226
|
+
* `{{double_brace}}` form; every one of them is declared below and resolves to a
|
|
227
|
+
* field on the document's table (or a stated literal).
|
|
228
|
+
*/
|
|
229
|
+
interface UseCaseDocumentTemplate {
|
|
230
|
+
token: string;
|
|
231
|
+
name: string;
|
|
232
|
+
describes: string;
|
|
233
|
+
table: string;
|
|
234
|
+
/** The subject or title line, merge fields allowed. */
|
|
235
|
+
title: string;
|
|
236
|
+
/** The body. Real prose this business would send, merge fields inline. */
|
|
237
|
+
body: string;
|
|
238
|
+
mergeFields: UseCaseMergeField[];
|
|
239
|
+
}
|
|
240
|
+
interface UseCaseMergeField {
|
|
241
|
+
/** The token inside `{{ }}` in the body. */
|
|
242
|
+
key: string;
|
|
243
|
+
/**
|
|
244
|
+
* The field key it reads, on the document's table — or, when it is not a
|
|
245
|
+
* field, the word `business` (from `BusinessIdentity`) or `today`.
|
|
246
|
+
*/
|
|
247
|
+
from: string;
|
|
248
|
+
describes: string;
|
|
249
|
+
}
|
|
250
|
+
/** How a notification reaches someone. */
|
|
251
|
+
type NotificationChannel = "email" | "sms" | "in_app";
|
|
252
|
+
/**
|
|
253
|
+
* The one automatic message this business would genuinely want — the thing a
|
|
254
|
+
* practitioner sets up on day one and never turns off.
|
|
255
|
+
*/
|
|
256
|
+
interface UseCaseNotificationRule {
|
|
257
|
+
token: string;
|
|
258
|
+
name: string;
|
|
259
|
+
describes: string;
|
|
260
|
+
when: UseCaseNotificationTrigger;
|
|
261
|
+
/** Who it goes to, in the business's own words: "the assigned hygienist". */
|
|
262
|
+
audience: string;
|
|
263
|
+
channel: NotificationChannel;
|
|
264
|
+
/** The actual message. Merge fields allowed, same convention as documents. */
|
|
265
|
+
message: string;
|
|
266
|
+
}
|
|
267
|
+
interface UseCaseNotificationTrigger {
|
|
268
|
+
table: string;
|
|
269
|
+
event: "created" | "updated" | "stage_entered" | "due" | "overdue";
|
|
270
|
+
/** For `stage_entered`: the stage key. */
|
|
271
|
+
stage?: string;
|
|
272
|
+
/** For `due` / `overdue`: the date field watched. */
|
|
273
|
+
field?: string;
|
|
274
|
+
/** For `due`: how many days ahead it fires. */
|
|
275
|
+
daysBefore?: number;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Where the shape and the values came from. `synthesized` means a person wrote
|
|
279
|
+
* plausible values out of domain knowledge; `public-data` means the numbers or
|
|
280
|
+
* names were derived from a genuinely public dataset, which is named.
|
|
281
|
+
*
|
|
282
|
+
* Either way the law holds: no real person, no real customer, no production row.
|
|
283
|
+
*/
|
|
284
|
+
interface UseCaseProvenance {
|
|
285
|
+
kind: "synthesized" | "public-data";
|
|
286
|
+
/** Named when `kind` is `public-data`. */
|
|
287
|
+
source?: string;
|
|
288
|
+
/** Who or what wrote this file, and when. */
|
|
289
|
+
authoredBy: string;
|
|
290
|
+
authoredOn: string;
|
|
291
|
+
/**
|
|
292
|
+
* The affirmation, carried in the data so a reviewer can see it: every person,
|
|
293
|
+
* address, phone and mailbox here is invented and belongs to nobody.
|
|
294
|
+
*/
|
|
295
|
+
noRealPeople: true;
|
|
296
|
+
}
|
|
297
|
+
/** One real business, and everything a test, seed, demo or screenshot needs of it. */
|
|
298
|
+
interface UseCase {
|
|
299
|
+
/** kebab-case and unique: "harbor-dental-new-patient-intake". */
|
|
300
|
+
id: string;
|
|
301
|
+
/**
|
|
302
|
+
* THE SENTENCE. Who the user is, what business they run, and what job this
|
|
303
|
+
* exact feature does for them — one sentence, at the top, before anything
|
|
304
|
+
* else. This is the first thing the law asks for and the validator checks it.
|
|
305
|
+
*/
|
|
306
|
+
useCase: string;
|
|
307
|
+
/** The industry, for rotation: "Dentistry", "Property management". */
|
|
308
|
+
industry: string;
|
|
309
|
+
business: BusinessIdentity;
|
|
310
|
+
/**
|
|
311
|
+
* The tag written into a test organization's settings so cleanup can find it.
|
|
312
|
+
* Cleanup finds test data by THIS, never by a junk name.
|
|
313
|
+
*/
|
|
314
|
+
cleanupTag: string;
|
|
315
|
+
tables: UseCaseTable[];
|
|
316
|
+
relationships: UseCaseRelationship[];
|
|
317
|
+
form: UseCaseForm;
|
|
318
|
+
pipeline: UseCasePipeline;
|
|
319
|
+
dashboardQuestion: UseCaseDashboardQuestion;
|
|
320
|
+
documentTemplate: UseCaseDocumentTemplate;
|
|
321
|
+
notificationRule: UseCaseNotificationRule;
|
|
322
|
+
provenance: UseCaseProvenance;
|
|
323
|
+
}
|
|
324
|
+
/** What the registry lists without loading a use case's rows. */
|
|
325
|
+
interface UseCaseSummary {
|
|
326
|
+
id: string;
|
|
327
|
+
useCase: string;
|
|
328
|
+
industry: string;
|
|
329
|
+
businessName: string;
|
|
330
|
+
/** How many tables and rows the file carries, so a caller can pick by size. */
|
|
331
|
+
tableCount: number;
|
|
332
|
+
rowCount: number;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/** One banned pattern, with the reason and what to do instead. */
|
|
336
|
+
interface PlaceholderPattern {
|
|
337
|
+
/** Stable id, used in the guard's output so a failure is greppable. */
|
|
338
|
+
id: string;
|
|
339
|
+
/** Matches the junk. Always global + case-insensitive. */
|
|
340
|
+
test: RegExp;
|
|
341
|
+
/** What is wrong with it, in one line. */
|
|
342
|
+
why: string;
|
|
343
|
+
/** What to write instead. */
|
|
344
|
+
instead: string;
|
|
345
|
+
/**
|
|
346
|
+
* Skip the hit when the LINE it sits on matches this. For words that are junk
|
|
347
|
+
* in one world and vocabulary in another: "Acme" is a cartoon company, but
|
|
348
|
+
* ACME is also RFC 8555, the protocol Let's Encrypt speaks, and a guard that
|
|
349
|
+
* cannot tell them apart will be told to shut up rather than obeyed.
|
|
350
|
+
*/
|
|
351
|
+
unlessLineMatches?: RegExp;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* The pragma that exempts a single line. The reason is not optional: a bare
|
|
355
|
+
* `matrx-real-data:allow` does not match and does not exempt anything.
|
|
356
|
+
*/
|
|
357
|
+
declare const ALLOW_PRAGMA: RegExp;
|
|
358
|
+
/**
|
|
359
|
+
* THE LIST. Every entry is anchored on word boundaries so it catches the token
|
|
360
|
+
* and not the vocabulary it lives inside.
|
|
361
|
+
*/
|
|
362
|
+
declare const PLACEHOLDER_PATTERNS: readonly PlaceholderPattern[];
|
|
363
|
+
/** One hit of one pattern. */
|
|
364
|
+
interface PlaceholderHit {
|
|
365
|
+
patternId: string;
|
|
366
|
+
/** The exact text that matched. */
|
|
367
|
+
match: string;
|
|
368
|
+
why: string;
|
|
369
|
+
instead: string;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Every banned pattern in `text`, ignoring any LINE carrying the allow pragma.
|
|
373
|
+
*
|
|
374
|
+
* Line-scoped rather than whole-text so one exemption never blinds the rest of
|
|
375
|
+
* a file, which is the failure mode of a file-level ignore comment.
|
|
376
|
+
*/
|
|
377
|
+
declare function findPlaceholders(text: string): PlaceholderHit[];
|
|
378
|
+
/** The sentence a guard or a suite prints for one hit. Never a bare code. */
|
|
379
|
+
declare function describePlaceholder(hit: PlaceholderHit): string;
|
|
380
|
+
|
|
381
|
+
/** Every word a `parityType` may be: the thirteen, the five behaviours, the synonyms. */
|
|
382
|
+
declare const RESOLVABLE_FIELD_TYPE_WORDS: readonly string[];
|
|
383
|
+
/**
|
|
384
|
+
* The minimum a seeded business needs before a screen looks like it is working
|
|
385
|
+
* rather than like a fixture. Below this, a screenshot shows an empty state.
|
|
386
|
+
*
|
|
387
|
+
* It was 8 until a real dataset argued with it: a whole-house renovation has SIX
|
|
388
|
+
* ROOMS, and demanding eight would have meant inventing two rooms that do not
|
|
389
|
+
* exist — which is the exact failure this whole library is against. Six rooms on
|
|
390
|
+
* a board is a working project, not an empty screen. So the floor is what a
|
|
391
|
+
* screen genuinely needs, and the suite keeps the stronger check where it
|
|
392
|
+
* belongs: at least 20 rows across the whole use case.
|
|
393
|
+
*/
|
|
394
|
+
declare const MIN_ROWS_IN_PRIMARY_TABLE = 5;
|
|
395
|
+
/** A refusal: what is wrong, where, and what to do. */
|
|
396
|
+
interface UseCaseProblem {
|
|
397
|
+
/** Dotted path into the use case: "tables[1].fields[3].choices". */
|
|
398
|
+
at: string;
|
|
399
|
+
/** The sentence. Always says what to do, never only what is wrong. */
|
|
400
|
+
says: string;
|
|
401
|
+
}
|
|
402
|
+
interface UseCaseVerdict {
|
|
403
|
+
ok: boolean;
|
|
404
|
+
problems: UseCaseProblem[];
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Check one use case. Returns every problem rather than the first, because a
|
|
408
|
+
* crew fixing a dataset wants the whole list in one pass.
|
|
409
|
+
*/
|
|
410
|
+
declare function validateUseCase(useCase: UseCase): UseCaseVerdict;
|
|
411
|
+
/**
|
|
412
|
+
* Validate, and throw with every problem listed. This is what a seeder calls
|
|
413
|
+
* before it writes anything to a live organization — a half-valid dataset is
|
|
414
|
+
* worse than none, because it produces a screen that looks like it worked.
|
|
415
|
+
*/
|
|
416
|
+
declare function assertUseCase(useCase: UseCase): void;
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Every registered use case, by id. ADD YOUR LINE HERE and nowhere else.
|
|
420
|
+
*
|
|
421
|
+
* Keep it alphabetical — it is read by people looking for an industry.
|
|
422
|
+
*/
|
|
423
|
+
declare const USE_CASE_LOADERS: Record<string, () => Promise<{
|
|
424
|
+
useCase: UseCase;
|
|
425
|
+
}>>;
|
|
426
|
+
/** The ids, sorted, so any listing is stable. */
|
|
427
|
+
declare function useCaseIds(): string[];
|
|
428
|
+
/** Load one by id. Throws by name when it is not registered. */
|
|
429
|
+
declare function loadUseCase(id: string): Promise<UseCase>;
|
|
430
|
+
/** Load all of them. For the suite, the seeders and the census. */
|
|
431
|
+
declare function loadAllUseCases(): Promise<UseCase[]>;
|
|
432
|
+
/** Summarize one without the caller walking its tables. */
|
|
433
|
+
declare function summarize(useCase: UseCase): UseCaseSummary;
|
|
434
|
+
/** Every use case, summarized. Loads all of them, so call it server-side. */
|
|
435
|
+
declare function listUseCases(): Promise<UseCaseSummary[]>;
|
|
436
|
+
/**
|
|
437
|
+
* Pick the use case for a given consumer, deterministically.
|
|
438
|
+
*
|
|
439
|
+
* The law says to ROTATE across industries so the platform is exercised by many
|
|
440
|
+
* kinds of business rather than one toy. A suite, a demo or a screenshot script
|
|
441
|
+
* passes a stable name for itself and always gets the same business — stable
|
|
442
|
+
* enough to assert on, different enough across consumers that the platform gets
|
|
443
|
+
* exercised broadly.
|
|
444
|
+
*/
|
|
445
|
+
declare function useCaseFor(consumer: string): string;
|
|
446
|
+
|
|
447
|
+
export { ALLOW_PRAGMA, type BusinessIdentity, type FormAudience, MIN_ROWS_IN_PRIMARY_TABLE, type NotificationChannel, PLACEHOLDER_PATTERNS, type PlaceholderHit, type PlaceholderPattern, type PostalAddress, RESOLVABLE_FIELD_TYPE_WORDS, USE_CASE_LOADERS, type UseCase, type UseCaseDashboardQuestion, type UseCaseDocumentTemplate, type UseCaseField, type UseCaseForm, type UseCaseFormField, type UseCaseMergeField, type UseCaseNotificationRule, type UseCaseNotificationTrigger, type UseCasePipeline, type UseCasePipelineStage, type UseCaseProblem, type UseCaseProvenance, type UseCaseRelationship, type UseCaseRow, type UseCaseSummary, type UseCaseTable, type UseCaseVerdict, assertUseCase, describePlaceholder, findPlaceholders, listUseCases, loadAllUseCases, loadUseCase, summarize, useCaseFor, useCaseIds, validateUseCase };
|