@opencxh/domain 1.171.0 → 1.172.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/entities/activity/blocks.d.ts +30 -30
  2. package/dist/entities/activity/catalog.d.ts +63 -86
  3. package/dist/entities/activity/descriptor.d.ts +31 -32
  4. package/dist/entities/activity/index.d.ts +2 -2
  5. package/dist/entities/activity/preview.d.ts +7 -7
  6. package/dist/entities/activity/resolve.d.ts +37 -38
  7. package/dist/entities/activity/types.d.ts +34 -34
  8. package/dist/entities/ai-account/types.d.ts +3 -3
  9. package/dist/entities/ai-account/vendors.d.ts +25 -32
  10. package/dist/entities/ai-budget/types.d.ts +12 -8
  11. package/dist/entities/ai-conversation/types.d.ts +12 -12
  12. package/dist/entities/ai-profile/types.d.ts +21 -26
  13. package/dist/entities/ai-settings/types.d.ts +12 -13
  14. package/dist/entities/analytics/dashboard.d.ts +1 -1
  15. package/dist/entities/analytics/index.d.ts +4 -4
  16. package/dist/entities/analytics/source.d.ts +1 -1
  17. package/dist/entities/analytics/usage.d.ts +23 -28
  18. package/dist/entities/artifact/blocks.d.ts +54 -69
  19. package/dist/entities/artifact/markdown.d.ts +2 -3
  20. package/dist/entities/artifact/types.d.ts +47 -55
  21. package/dist/entities/assignment/types.d.ts +74 -88
  22. package/dist/entities/calendar-event/types.d.ts +1 -1
  23. package/dist/entities/channel/index.d.ts +1 -1
  24. package/dist/entities/channel/signature.d.ts +8 -9
  25. package/dist/entities/communication/index.d.ts +1 -1
  26. package/dist/entities/communication/message-template.d.ts +1 -1
  27. package/dist/entities/company/types.d.ts +1 -1
  28. package/dist/entities/contact/index.d.ts +1 -1
  29. package/dist/entities/contact/provider.d.ts +2 -1
  30. package/dist/entities/contact/types.d.ts +1 -10
  31. package/dist/entities/custom-field-def/types.d.ts +14 -14
  32. package/dist/entities/external-identity/types.d.ts +45 -50
  33. package/dist/entities/interaction/index.d.ts +1 -1
  34. package/dist/entities/interaction/types.d.ts +44 -47
  35. package/dist/entities/live-lens/types.d.ts +39 -44
  36. package/dist/entities/mcp/types.d.ts +53 -57
  37. package/dist/entities/memory/alias.d.ts +7 -7
  38. package/dist/entities/memory/browse.d.ts +21 -21
  39. package/dist/entities/memory/ingest.d.ts +26 -17
  40. package/dist/entities/memory/item.d.ts +53 -58
  41. package/dist/entities/memory/kind.d.ts +26 -26
  42. package/dist/entities/memory/query.d.ts +49 -51
  43. package/dist/entities/playbook/actor.d.ts +20 -19
  44. package/dist/entities/playbook/assignment.d.ts +54 -63
  45. package/dist/entities/playbook/index.d.ts +2 -2
  46. package/dist/entities/playbook/labels.d.ts +4 -4
  47. package/dist/entities/playbook/trigger-vars.d.ts +14 -15
  48. package/dist/entities/playbook/types.d.ts +173 -303
  49. package/dist/entities/resource-reminder/types.d.ts +8 -9
  50. package/dist/entities/scope/actor.d.ts +16 -0
  51. package/dist/entities/{note → scope}/index.d.ts +1 -0
  52. package/dist/entities/scope/scope.test.d.ts +1 -0
  53. package/dist/entities/scope/types.d.ts +53 -0
  54. package/dist/entities/task/types.d.ts +1 -1
  55. package/dist/entities/time-entry/duration.d.ts +11 -11
  56. package/dist/entities/time-entry/types.d.ts +60 -60
  57. package/dist/entities/time-entry/work-type.d.ts +21 -24
  58. package/dist/entities/topic/examples.d.ts +26 -27
  59. package/dist/entities/topic/scope.d.ts +11 -12
  60. package/dist/entities/topic/types.d.ts +28 -28
  61. package/dist/entities/user/types.d.ts +24 -28
  62. package/dist/entities/webhook/types.d.ts +6 -6
  63. package/dist/entities/work/keys.d.ts +25 -26
  64. package/dist/entities/work/ladder.d.ts +48 -52
  65. package/dist/entities/work/types.d.ts +109 -115
  66. package/dist/index.cjs +6 -6
  67. package/dist/index.d.ts +29 -33
  68. package/dist/index.js +1391 -1254
  69. package/dist/platform/account.d.ts +34 -38
  70. package/dist/platform/ai-tools.d.ts +48 -52
  71. package/dist/platform/api.d.ts +9 -8
  72. package/dist/platform/author.d.ts +7 -9
  73. package/dist/platform/capabilities.d.ts +3 -3
  74. package/dist/platform/communication.d.ts +163 -204
  75. package/dist/platform/context.d.ts +8 -8
  76. package/dist/platform/identity.d.ts +16 -19
  77. package/dist/platform/kernel.d.ts +1 -1
  78. package/dist/platform/manifest.d.ts +2 -2
  79. package/dist/platform/media.d.ts +13 -15
  80. package/dist/platform/permission.d.ts +39 -0
  81. package/dist/platform/permission.test.d.ts +1 -0
  82. package/dist/platform/presence.d.ts +30 -30
  83. package/dist/platform/provider.d.ts +14 -76
  84. package/dist/platform/resource-source.d.ts +43 -45
  85. package/dist/platform/resource.d.ts +17 -23
  86. package/dist/platform/scope.d.ts +36 -62
  87. package/dist/platform/services.d.ts +4 -4
  88. package/dist/platform/settings.d.ts +0 -14
  89. package/dist/platform/storage.d.ts +2 -2
  90. package/dist/platform/sync-source.d.ts +196 -216
  91. package/dist/platform/transcript-cadence.d.ts +37 -41
  92. package/dist/platform/ui.d.ts +6 -6
  93. package/dist/text/endpoint.d.ts +11 -27
  94. package/package.json +3 -5
  95. package/dist/entities/note/types.d.ts +0 -14
  96. package/dist/entities/shopify/index.d.ts +0 -1
  97. package/dist/entities/shopify/types.d.ts +0 -79
  98. package/dist/platform/lifecycle.d.ts +0 -13
  99. package/dist/platform/reactive.d.ts +0 -13
  100. package/dist/platform/sdk.d.ts +0 -182
  101. package/dist/platform/service-registry.d.ts +0 -13
@@ -1,45 +1,45 @@
1
- import { OwnerScope } from '../contact/types';
1
+ import { OrgTeamScope } from '../scope/types';
2
2
  /**
3
- * Een onderwerp is een **etiket** op een gesprek: waar gaat dit over. Verder niets.
3
+ * A topic is a **label** on a conversation: what is this about. Nothing more.
4
4
  *
5
- * Er zat ooit ook een kennis-kant in (`knowledgeSources`: urls en kb-artikelen die "bij dit
6
- * onderwerp horen"). Die is eruit gehaald omdat hij door niemand gelezen werd — het formulier
7
- * vulde hem, de entity bewaarde hem, en geen enkele prompt of zoekactie deed er iets mee. Wat hij
8
- * beloofde doet de kennisbank inmiddels beter (hybride RAG over álle artikelen) en het geheugen
9
- * daarnaast (`memory_find_similar`, uit echt verkeer). Zie `docs/TOPICS.md`.
5
+ * It once also had a knowledge side (`knowledgeSources`: urls and kb articles "belonging to this
6
+ * topic"). That was removed because nobody read it — the form filled it, the entity stored it, and
7
+ * no prompt or search did anything with it. What it promised the knowledge base now does better
8
+ * (hybrid RAG over *all* articles) and the memory layer alongside it (`memory_find_similar`, from
9
+ * real traffic). See `docs/TOPICS.md`.
10
10
  */
11
11
  export interface Topic {
12
12
  id: string;
13
13
  organizationId: string;
14
14
  /**
15
- * Van wie dit onderwerp is. `org` of `team`; **`personal` wordt geweigerd bij het schrijven** —
16
- * een onderwerp dat maar één persoon kent, kan een collega niet lezen op een gesprek dat hij
17
- * overneemt. Het type laat het toe omdat `OwnerScope` gedeeld is; de validatie niet.
15
+ * Whose topic this is: `org` or `team`. A topic only one person knows cannot be read by a
16
+ * colleague taking over the conversation. `OrgTeamScope` says so in the type, so it is not only
17
+ * the write validation enforcing it.
18
18
  */
19
- ownerScope: OwnerScope;
19
+ ownerScope: OrgTeamScope;
20
20
  name: string;
21
21
  description: string;
22
22
  /**
23
- * Voorbeeldzinnen die de classificatie-prompt meekrijgt. Dit is het enige veld dat de
24
- * classifier scherper maakt, en dus het enige dat het waard is om bij te houden.
23
+ * Example sentences the classification prompt receives. The only field that sharpens the
24
+ * classifier, and therefore the only one worth maintaining.
25
25
  */
26
26
  examples: string[];
27
27
  /**
28
- * Voorgestelde voorbeelden, nog niet overgenomen. Groeit vanzelf: elke keer dat een **mens**
29
- * dit onderwerp op een gesprek zet of corrigeert, komt de openingszin hier terecht.
28
+ * Suggested examples, not accepted yet. Grows by itself: every time a **person** puts this topic
29
+ * on a conversation or corrects it, the opening sentence lands here.
30
30
  *
31
- * Bewust náást `examples` en niet erin: de classificatie-prompt is de plek waar één slecht
32
- * voorbeeld het gedrag van élk volgend gesprek verschuift, en er is geen undo op een prompt die
33
- * drie weken scheef stond. `examples` blijft van de beheerder; dit is een voorstel.
31
+ * Deliberately next to `examples` and not in it: the classification prompt is where one bad
32
+ * example shifts the behaviour of *every* following conversation, and there is no undo on a
33
+ * prompt that sat crooked for three weeks. `examples` stays the admin's; this is a suggestion.
34
34
  */
35
35
  exampleCandidates?: TopicExampleCandidate[];
36
36
  }
37
37
  /**
38
- * Eén voorgesteld voorbeeld.
38
+ * One suggested example.
39
39
  *
40
- * `corrected` onderscheidt "iemand zette een onderwerp op een gesprek dat er nog geen had" van
41
- * "iemand zette het onderwerp om" — dat tweede is een gecorrigeerde fout en daarmee het meest
42
- * informatieve geval dat er is. De UI zet ze daarom bovenaan.
40
+ * `corrected` distinguishes "someone put a topic on a conversation that had none" from "someone
41
+ * changed the topic" — the second is a corrected mistake and thereby the most informative case
42
+ * there is. The UI puts those on top.
43
43
  */
44
44
  export interface TopicExampleCandidate {
45
45
  text: string;
@@ -48,14 +48,14 @@ export interface TopicExampleCandidate {
48
48
  corrected: boolean;
49
49
  }
50
50
  /**
51
- * Hoeveel voorbeelden er per onderwerp mee mogen.
51
+ * How many examples a topic may carry.
52
52
  *
53
- * De hele lijst gaat als JSON de systemprompt in bij élke classificatie
54
- * (`apps/ai/server/src/playbook/ai/classify.ts`), dus ongelimiteerd groeien maakt het classificeren
55
- * per gesprek duurder tot het niet meer past.
53
+ * The whole list goes into the system prompt as JSON on *every* classification
54
+ * (`apps/ai/server/src/playbook/ai/classify.ts`), so unlimited growth makes classifying more
55
+ * expensive per conversation until it no longer fits.
56
56
  */
57
57
  export declare const MAX_TOPIC_EXAMPLES = 20;
58
- /** Idem voor de kandidatenlijst: een voorstellenbak die volloopt, leest niemand meer na. */
58
+ /** Same for the candidate list: a suggestion bucket that fills up is one nobody reviews. */
59
59
  export declare const MAX_TOPIC_CANDIDATES = 20;
60
- /** Een voorbeeld is een openingszin, geen transcript. */
60
+ /** An example is an opening sentence, not a transcript. */
61
61
  export declare const MAX_TOPIC_EXAMPLE_CHARS = 300;
@@ -1,26 +1,25 @@
1
1
  /**
2
- * Mens of agent.
2
+ * Human or agent.
3
3
  *
4
- * Een agent is **geen apart begrip naast de gebruiker** maar een gebruiker met een ander type.
5
- * Dat is een keuze met een concreet doel: hij krijgt een echt `userId`, dus hij loopt door
6
- * `authorizeIdentity` op het fail-closed pad, hij tekent zijn activities met zijn eigen naam in
7
- * plaats van als "system", hij kan lid van een team zijn (`getReadableTeamIds` werkt), en hij
8
- * verbruikt van zijn eigen per-user-budget. Elk van die dingen zou anders een uitzondering zijn
9
- * geweest, en elke uitzondering is een plek waar een audit hem kwijtraakt.
4
+ * An agent is **not a separate concept beside the user** but a user with a different type. A
5
+ * choice with a concrete purpose: it gets a real `userId`, so it runs through `authorizeIdentity`
6
+ * on the fail-closed path, it signs its activities with its own name instead of as "system", it
7
+ * can be a team member (`getReadableTeamIds` works), and it spends from its own per-user budget.
8
+ * Each of those would otherwise have been an exception, and every exception is a place where an
9
+ * audit loses it.
10
10
  *
11
- * Afwezig betekent `"user"`: bestaande rijen zijn mensen, en de mirror wordt niet gebackfilld.
11
+ * Absent means `"user"`: existing rows are humans, and the mirror is not backfilled.
12
12
  */
13
13
  export type UserType = "user" | "agent";
14
14
  /**
15
- * Wat een ander oppervlak van een gebruiker mag weten om hem te **tónen**.
15
+ * What another surface may know about a user in order to **show** them.
16
16
  *
17
- * Los van {@link User}, en dat is het punt: een naam opzoeken is iets anders dan een gebruiker
18
- * beheren. De beheerroute geeft het hele record plus zijn rollen (een extra RPC naar
19
- * `system.rbac`) — dat is precies wat je niet wil als je alleen een auteursnaam in een tijdlijn
20
- * zet: het kost een call die niemand nodig heeft en het deelt e-mail en rollen met een app die
21
- * daar niets mee te maken heeft.
17
+ * Separate from {@link User}, and that is the point: looking a name up is not the same as managing
18
+ * a user. The admin route returns the whole record plus its roles (an extra RPC to `system.rbac`) —
19
+ * exactly what you do not want when only putting an author name in a timeline: it costs a call
20
+ * nobody needs and shares email and roles with an app that has nothing to do with them.
22
21
  *
23
- * `type` zit er wél in: een tijdlijn of een deelnemerslijst wil een agent kunnen markeren.
22
+ * `type` *is* in here: a timeline or a participant list wants to be able to mark an agent.
24
23
  */
25
24
  export interface UserProfile {
26
25
  id: string;
@@ -29,16 +28,16 @@ export interface UserProfile {
29
28
  avatarUrl?: string;
30
29
  type?: UserType;
31
30
  /**
32
- * Het brein van een agent, als dit een agent is — zie {@link User.profileId}.
31
+ * An agent's brain, when this is an agent — see {@link User.profileId}.
33
32
  *
34
- * Hoort bij dit compacte record en niet alleen bij het volledige: "is dit een agent" staat er
35
- * al (`type`), en "met welk brein" is de directe vervolgvraag van elke beller die er werk aan
36
- * geeft. Zonder dit veld moest de ai-app de beheerroute gebruiken — het hele record plus een
37
- * RPC naar `system.rbac` — om één id te weten.
33
+ * Belongs on this compact record and not only on the full one: "is this an agent" is already
34
+ * here (`type`), and "with which brain" is the immediate follow-up of every caller handing it
35
+ * work. Without this field the ai app had to use the admin route — the whole record plus an RPC
36
+ * to `system.rbac` — to learn one id.
38
37
  */
39
38
  profileId?: string;
40
39
  }
41
- /** Is deze gebruiker een agent? Afwezig type = mens. */
40
+ /** Is this user an agent? An absent type = human. */
42
41
  export declare function isAgentUser(user: {
43
42
  type?: UserType | string;
44
43
  }): boolean;
@@ -48,16 +47,13 @@ export interface User {
48
47
  email: string;
49
48
  availableOrganizations: string[];
50
49
  /**
51
- * Mens of agent. Zie {@link UserType}.
50
+ * Human or agent. See {@link UserType}.
52
51
  *
53
- * Staat op de **lokale mirror** en niet in `system.users`: dat is het platform-record en dat
54
- * kennen we niet. Alles wat "is dit een mens" moet weten leest dit veld.
52
+ * Sits on the **local mirror** and not in `system.users`: that is the platform record and we do
53
+ * not own it. Everything that needs to know "is this a human" reads this field.
55
54
  */
56
55
  type?: UserType;
57
- /**
58
- * Het brein van een agent: het `AIProfile` waarmee hij werkt. Alleen gezet als
59
- * `type === "agent"`.
60
- */
56
+ /** An agent's brain: the `AIProfile` it works with. Only set when `type === "agent"`. */
61
57
  profileId?: string;
62
58
  /** Mirrored from system.users. */
63
59
  firstName?: string;
@@ -19,16 +19,16 @@ export interface Webhook {
19
19
  enabled: boolean;
20
20
  createdBy: string;
21
21
  /**
22
- * Hoe de laatste aflevering ging.
22
+ * How the last delivery went.
23
23
  *
24
- * Vier velden en geen afleverhistorie: de vraag die een beheerder stelt is "komt dit aan?", en
25
- * die is met de laatste poging plus een teller beantwoord. Een volledige historie is een eigen
26
- * scherm en een eigen entiteit.
24
+ * Four fields and no delivery history: the question an admin asks is "does this arrive?", and
25
+ * that is answered by the last attempt plus a counter. A full history is a screen of its own and
26
+ * an entity of its own.
27
27
  */
28
28
  lastDeliveryAt?: number;
29
- /** HTTP-status van de laatste poging. Afwezig = de call kwam niet tot een antwoord. */
29
+ /** HTTP status of the last attempt. Absent = the call never reached an answer. */
30
30
  lastStatus?: number;
31
31
  lastError?: string;
32
- /** Opeenvolgende mislukkingen, nul zodra er één aankomt — niet een totaalteller. */
32
+ /** Consecutive failures, zero as soon as one arrives — not a running total. */
33
33
  failureCount?: number;
34
34
  }
@@ -1,57 +1,56 @@
1
1
  import { WorkItem, WorkProject } from './types';
2
2
  /**
3
- * Sleutels: de scopeKeys waarmee andere apps werk aanwijzen, en de menselijke itemsleutel.
3
+ * Keys: the scopeKeys other apps point at work with, and the human item key.
4
4
  *
5
- * Beide staan in `domain` en niet in de app, omdat het contracten zijn: de client bouwt een
6
- * scopeKey om een timer te starten, de server autoriseert hem, en twee plekken die het
7
- * voorvoegsel los uitschrijven lopen bij de eerste typefout stil uiteen — met "geen toegang
8
- * tot deze scope" als gevolg in plaats van een foutmelding die zegt wat er mis is.
5
+ * Both live in `domain` and not in the app, because they are contracts: the client builds a
6
+ * scopeKey to start a timer, the server authorizes it, and two places spelling the prefix out
7
+ * separately drift apart silently on the first typo — resulting in "no access to this scope"
8
+ * instead of an error saying what is wrong.
9
9
  */
10
- /** De scope-soorten die `apps/work` claimt via `/provider/scope/describe`. */
10
+ /** The scope kinds `apps/work` claims through `/provider/scope/describe`. */
11
11
  export declare const WORK_ITEM_SCOPE_KIND = "work_item";
12
12
  export declare const WORK_PROJECT_SCOPE_KIND = "work_project";
13
13
  export declare function workItemScopeKey(itemId: string): string;
14
14
  export declare function workProjectScopeKey(projectId: string): string;
15
15
  /**
16
- * De menselijke sleutel: `SAL-142`, of `SAL-142-1` voor een subitem.
16
+ * The human key: `SAL-142`, or `SAL-142-1` for a subitem.
17
17
  *
18
- * Alleen voor items mét project — een los item heeft er geen, en dat is geen omissie maar het
19
- * verschil tussen "werk dat een plek in een proces heeft" en "iets wat ik nog moet doen".
18
+ * Only for items *with* a project — a loose item has none, and that is not an omission but the
19
+ * difference between "work with a place in a process" and "something I still have to do".
20
20
  */
21
21
  export declare function formatItemKey(projectKey: string, sequenceNumber: number, subSequence?: number): string;
22
- /** Wat er in een `SAL-142-1` zit, of `null` als het geen itemsleutel is. */
22
+ /** What sits inside a `SAL-142-1`, or `null` when it is not an item key. */
23
23
  export interface ParsedItemKey {
24
24
  projectKey: string;
25
25
  sequenceNumber: number;
26
26
  subSequence?: number;
27
27
  }
28
28
  /**
29
- * Leest een sleutel die iemand heeft ingetypt of geplakt.
29
+ * Reads a key someone typed or pasted.
30
30
  *
31
- * Hoofdletterongevoelig aan de invoerkant en genormaliseerd aan de uitvoerkant, want mensen
32
- * typen `sal-142` in een zoekveld en verwachten hun item. Het projectvoorvoegsel is
33
- * `[A-Z0-9]{2,8}`, wat een streepje uitsluit — anders zou `SAL-142-1` net zo goed te lezen
34
- * zijn als project `SAL-142`, item `1`.
31
+ * Case-insensitive on the input side and normalized on the output side, because people type
32
+ * `sal-142` in a search field and expect their item. The project prefix is `[A-Z0-9]{2,8}`, which
33
+ * excludes a hyphen — otherwise `SAL-142-1` could just as well read as project `SAL-142`, item `1`.
35
34
  */
36
35
  export declare function parseItemKey(input: string): ParsedItemKey | null;
37
- /** De projectsleutel die bij een naam hoort: `"Sales pipeline"` → `"SAL"`. */
36
+ /** The project key belonging to a name: `"Sales pipeline"` → `"SAL"`. */
38
37
  export declare function suggestProjectKey(name: string): string;
39
38
  /**
40
- * De dossiersleutels van een item: waarmee uren, geheugen en attributen het terugvinden.
39
+ * An item's file keys: what hours, memory and attributes find it back with.
41
40
  *
42
- * **Klein houden.** Dit is de set van de rij zelf en niet zijn hele omgeving — deze sleutels
43
- * rijden mee op elke autorisatie, inclusief elke geheugen-schrijfactie, dus de kinderen van
44
- * dit item horen er niet in. Dezelfde afweging die `companyDossierKeys` maakt tegenover
45
- * `keySetForCompany` in crm.
41
+ * **Keep it small.** This is the set of the row itself and not of its whole surroundings — these
42
+ * keys ride along on every authorization, including every memory write, so this item's children do
43
+ * not belong in it. The same trade-off `companyDossierKeys` makes against `keySetForCompany` in
44
+ * crm.
46
45
  *
47
- * De harde bovengrens is er voor het pathologische geval: een item met tweehonderd partijen
48
- * mag geen array van tweehonderd sleutels op elke autorisatie leggen.
46
+ * The hard upper bound is there for the pathological case: an item with two hundred parties must
47
+ * not put an array of two hundred keys on every authorization.
49
48
  */
50
49
  export declare function itemDossierKeys(item: Pick<WorkItem, "id" | "projectId" | "ancestorKeys" | "partyKeys">, limit?: number): string[];
51
50
  /**
52
- * De dossiersleutels van een project: alleen zichzelf.
51
+ * A project's file keys: itself only.
53
52
  *
54
- * Een project heeft onbegrensd veel items, dus zijn kinderen meegeven zou een onbegrensd
55
- * array op elke autorisatie leggen. Wie de items wil, vraagt ernaar.
53
+ * A project has unbounded items, so passing its children would put an unbounded array on every
54
+ * authorization. Whoever wants the items asks for them.
56
55
  */
57
56
  export declare function projectDossierKeys(project: Pick<WorkProject, "id">): string[];
@@ -1,97 +1,93 @@
1
1
  import { WorkProject, WorkStatus, WorkStatusCategory } from './types';
2
2
  /**
3
- * De statusladder — de enige plek die weet of een item een project heeft.
3
+ * The status ladder — the only place that knows whether an item has a project.
4
4
  *
5
- * `WorkItem.projectId` is optioneel, en zonder discipline betekent dat een `if (projectId)`
6
- * in elke lijst, elke teller en elke statuskiezer. Alles wat "welke statussen kan dit item
7
- * hebben" of "is dit open" vraagt gaat daarom door {@link ladderFor} en {@link categoryOf},
8
- * en nergens anders.
5
+ * `WorkItem.projectId` is optional, and without discipline that means an `if (projectId)` in every
6
+ * list, every counter and every status picker. So anything asking "which statuses can this item
7
+ * have" or "is this open" goes through {@link ladderFor} and {@link categoryOf}, and nowhere else.
9
8
  */
10
9
  /**
11
- * De vaste ladder voor werk zónder project.
10
+ * The fixed ladder for work *without* a project.
12
11
  *
13
- * Deze drie sleutels zijn **gereserveerd**: een project mag ze niet claimen, want dan zou
14
- * dezelfde sleutel in twee ladders een andere categorie kunnen hebben en werd de
15
- * org-brede "wat staat er open"-query stil onjuist. `validateStatuses` bewaakt dat.
12
+ * These three keys are **reserved**: a project may not claim them, because then the same key could
13
+ * have a different category in two ladders and the org-wide "what is open" query would silently go
14
+ * wrong. `validateStatuses` guards that.
16
15
  *
17
- * De labels zijn **i18n-sleutels, geen tekst** — een letterlijke string hier zou de taal op
18
- * moduleniveau vastzetten voor elke consument, en dat is precies wat de i18n-regel in
19
- * `DESIGN_SYSTEM.md` §11 verbiedt. Ze staan zonder app-voorvoegsel omdat de app-sdk dat er
20
- * bij het opzoeken zelf voor zet; een `work:`-voorvoegsel hier zou in de eigen app
21
- * verdubbelen tot `work:work:status_open`.
16
+ * The labels are **i18n keys, not text** — a literal string here would fix the language at module
17
+ * level for every consumer, exactly what the i18n rule in `DESIGN_SYSTEM.md` §11 forbids. They
18
+ * carry no app prefix because the app-sdk adds that on lookup; a `work:` prefix here would double
19
+ * up to `work:work:status_open` inside the app itself.
22
20
  *
23
- * Een projectstatus heeft géén sleutel maar een naam die een beheerder heeft ingetypt. Alleen
24
- * deze drie zijn vertaalbaar, want alleen deze zijn van ons.
21
+ * A project status has no key but a name an admin typed. Only these three are translatable,
22
+ * because only these are ours.
25
23
  */
26
24
  export declare const LOOSE_STATUSES: readonly WorkStatus[];
27
- /** De sleutels die {@link LOOSE_STATUSES} bezet houdt. */
25
+ /** The keys {@link LOOSE_STATUSES} occupies. */
28
26
  export declare const RESERVED_STATUS_KEYS: readonly string[];
29
27
  /**
30
- * De ladder die voor dit item geldt.
28
+ * The ladder that applies to this item.
31
29
  *
32
- * Een project zónder statussen valt terug op de vaste ladder in plaats van een lege lijst op
33
- * te leveren: een statuskiezer met nul opties is een doodlopende weg, en een half aangemaakt
34
- * project hoort niet onbruikbaar te zijn.
30
+ * A project *without* statuses falls back to the fixed ladder instead of yielding an empty list: a
31
+ * status picker with zero options is a dead end, and a half-created project should not be
32
+ * unusable.
35
33
  */
36
34
  export declare function ladderFor(project?: WorkProject | null): readonly WorkStatus[];
37
35
  /**
38
- * De categorie van een statussleutel binnen een ladder.
36
+ * The category of a status key within a ladder.
39
37
  *
40
- * Valt terug op `"todo"` bij een onbekende sleutel, en dat is de veilige kant: een item dat
41
- * door een verwijderde status wees zou anders als afgerond uit elke telling verdwijnen. Beter
42
- * zichtbaar op de verkeerde plek dan onzichtbaar.
38
+ * Falls back to `"todo"` on an unknown key, which is the safe side: an item pointing at a deleted
39
+ * status would otherwise vanish from every count as if finished. Better visible in the wrong place
40
+ * than invisible.
43
41
  */
44
42
  export declare function categoryOf(statusKey: string, ladder: readonly WorkStatus[]): WorkStatusCategory;
45
- /** De status zelf, als de ladder hem kent. */
43
+ /** The status itself, when the ladder knows it. */
46
44
  export declare function statusIn(statusKey: string, ladder: readonly WorkStatus[]): WorkStatus | undefined;
47
- /** Waar een nieuw item begint: de expliciete keuze van het project, anders de eerste stap. */
45
+ /** Where a new item starts: the project's explicit choice, otherwise the first step. */
48
46
  export declare function defaultStatusKey(project?: WorkProject | null): string;
49
- /** `order` eerst, gelijke waarden op label zodat de volgorde stabiel is. */
47
+ /** `order` first, ties broken on label so the ordering is stable. */
50
48
  export declare function sortStatuses(ladder: readonly WorkStatus[]): WorkStatus[];
51
49
  /**
52
- * Is dit item afgerond? De enige juiste manier om die vraag te stellen.
50
+ * Is this item finished? The only correct way to ask that question.
53
51
  *
54
- * `isWorkClosed` en niet `isClosed`, want `entities/interaction` exporteert die naam al voor
55
- * een gesprek. Twee `isClosed`en in één barrel is precies de verwarring waar dit veld niet
56
- * op zit te wachten.
52
+ * `isWorkClosed` and not `isClosed`, because `entities/interaction` already exports that name for a
53
+ * conversation. Two `isClosed`es in one barrel is exactly the confusion this field does not need.
57
54
  */
58
55
  export declare function isWorkClosed(statusKey: string, ladder: readonly WorkStatus[]): boolean;
59
56
  /**
60
- * De statussleutel die bij een naam hoort: kleine letters, streepjes, geen accenten.
57
+ * The status key belonging to a name: lowercase, hyphens, no accents.
61
58
  *
62
- * Dezelfde vorm en dezelfde reden als `workTypeKey` bij de werksoorten: het beheerscherm
63
- * toont hem al tijdens het typen, dus wat de gebruiker daar ziet moet precies zijn wat de
64
- * server wegschrijft. `normalize("NFD")` plus het weghalen van de combineertekens, zodat
65
- * "Béta" `beta` wordt en niet `b-ta`.
59
+ * Same shape and same reason as `workTypeKey` for the work types: the admin screen shows it while
60
+ * you type, so what the user sees there has to be exactly what the server writes.
61
+ * `normalize("NFD")` plus stripping the combining marks, so "Béta" becomes `beta` and not `b-ta`.
66
62
  */
67
63
  export declare function workStatusKey(label: string): string;
68
64
  /**
69
- * Dezelfde sleutel, gegarandeerd nog vrij binnen de organisatie.
65
+ * The same key, guaranteed still free within the organisation.
70
66
  *
71
- * Botsingen zijn hier de regel en niet de uitzondering: sleutels zijn org-uniek terwijl
72
- * statussen per project beheerd worden, dus twee projecten die allebei een "Review" aanmaken
73
- * komen hier uit. De tweede krijgt `review-2` in plaats van een foutmelding — een beheerder
74
- * die een naam kiest hoort niet te struikelen over een sleutel die hij nooit heeft gezien.
67
+ * Collisions are the rule here and not the exception: keys are org-unique while statuses are
68
+ * managed per project, so two projects both creating a "Review" end up here. The second gets
69
+ * `review-2` instead of an error — an admin picking a name should not trip over a key they never
70
+ * saw.
75
71
  *
76
- * `taken` moet óók de sleutels van verwijderde statussen bevatten zolang er items naar
77
- * wijzen, en altijd {@link RESERVED_STATUS_KEYS}.
72
+ * `taken` must also contain the keys of deleted statuses as long as items point at them, and
73
+ * always {@link RESERVED_STATUS_KEYS}.
78
74
  */
79
75
  export declare function uniqueWorkStatusKey(label: string, taken: Iterable<string>): string;
80
- /** Wat er mis is met een voorgestelde ladder, als leesbare redenen. */
76
+ /** What is wrong with a proposed ladder, as readable reasons. */
81
77
  export interface StatusLadderProblem {
82
- /** Index in de aangeleverde lijst, of `-1` als het de lijst als geheel betreft. */
78
+ /** Index in the supplied list, or `-1` when it concerns the list as a whole. */
83
79
  index: number;
84
80
  reason: "empty" | "duplicate_key" | "reserved_key" | "missing_key" | "no_open" | "no_done";
85
81
  key?: string;
86
82
  }
87
83
  /**
88
- * Valideert een ladder vóór hij wordt opgeslagen.
84
+ * Validates a ladder before it is stored.
89
85
  *
90
- * Bestaat omdat de store hier niets bewaakt: `statuses` is één ingebed array, dus uniciteit
91
- * en volledigheid zijn de verantwoordelijkheid van de schrijver. Puur en zonder I/O, zodat
92
- * het beheerscherm dezelfde regels kan tonen als de server afdwingt.
86
+ * Exists because the store guards nothing here: `statuses` is one embedded array, so uniqueness
87
+ * and completeness are the writer's responsibility. Pure and without I/O, so the admin screen can
88
+ * show the same rules the server enforces.
93
89
  *
94
- * De twee laatste regels zijn geen smaak: een ladder zonder open-categorie maakt elk nieuw
95
- * item meteen afgerond, en een ladder zonder `done` maakt afronden onmogelijk.
90
+ * The last two rules are not taste: a ladder without an open category marks every new item
91
+ * finished immediately, and a ladder without `done` makes finishing impossible.
96
92
  */
97
93
  export declare function validateStatuses(statuses: readonly WorkStatus[]): StatusLadderProblem[];