{ "pipes": [], "interfaces": [ { "name": "Aantekening", "id": "interface-Aantekening-8e28c6bf4ec154e4db100e2ec1ee19fe9c2d50bc429733f8288f32277ce91963f67ec0363028632e71cfb7e05ce25001908c8dd8ee66d732632d67b993c0645b", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export type RegistrationStatus =\n | { tag: 'Geregistreerd'; herregistratieDatum: string } // ISO date\n | { tag: 'Geschorst'; geschorstTot: string; reden: string }\n | { tag: 'Doorgehaald'; doorgehaaldOp: string; reden: string };\n\n/** Just the discriminant — for atoms that only need the label/color. */\nexport type StatusTag = RegistrationStatus['tag'];\n\nexport interface Registration {\n bigNummer: string;\n naam: string;\n beroep: string; // arts, verpleegkundige, apotheker, ...\n registratiedatum: string; // ISO date\n geboortedatum: string;\n status: RegistrationStatus;\n}\n\n/** A note is either a recognised specialism or a plain annotation — a closed set,\n not an open string, so a typo can't slip through. */\nexport type AantekeningType = 'Specialisme' | 'Aantekening';\n\nexport interface Aantekening {\n type: AantekeningType;\n omschrijving: string;\n datum: string;\n}\n", "properties": [ { "name": "datum", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 32 }, { "name": "omschrijving", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 31 }, { "name": "type", "deprecated": false, "deprecationMessage": "", "type": "AantekeningType", "indexKey": "", "optional": false, "description": "", "line": 30 } ], "indexSignatures": [], "kind": 172, "methods": [], "extends": [] }, { "name": "Adres", "id": "interface-Adres-07cec46d80a41919e40d0bcb002981627d1a30edb363d64a0a140a8af2c38ad85be5603d88030d0704870800694c5bed9c709ae6891fe83e646e90c1a67cf548", "file": "src/app/registratie/domain/person.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export interface Adres {\n straat: string;\n postcode: string;\n woonplaats: string;\n}\n\nexport interface Person {\n naam: string;\n geboortedatum: string; // ISO date\n adres: Adres;\n}\n", "properties": [ { "name": "postcode", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 4 }, { "name": "straat", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 3 }, { "name": "woonplaats", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 5 } ], "indexSignatures": [], "kind": 172, "description": "
Person identity as supplied by the BRP (Basisregistratie Personen).
\n", "rawdescription": "\nPerson identity as supplied by the BRP (Basisregistratie Personen).", "methods": [], "extends": [] }, { "name": "Answers", "id": "interface-Answers-53c06ae2dad9470cd0c742a7e5903458a870e5eaaf70ce3043cec53935f09d2cb0d5f9980b723ce79be2460d550908bc894743c867abdf0974f17f7596cdd05d", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Result, ok, err, assertNever } from '@shared/kernel/fp';\nimport { Uren, parseUren } from '@registratie/domain/value-objects/uren';\n\n/**\n * A BRANCHING wizard. Unlike herregistratie.machine (fixed 2 steps), the set of\n * steps here is NOT stored — it's *derived* from the answers by `visibleSteps`.\n * Answer \"buiten Nederland gewerkt? → ja\" and two extra steps appear; report few\n * hours and a scholing-question appears. The progress bar's denominator changes\n * as you type. \"Which question comes next\" is a pure function, so it's trivial\n * to test and impossible to get out of sync with the data.\n */\n\nexport type JaNee = 'ja' | 'nee';\n\n/** Every possible question, as a union — never a bare string. */\nexport type StepId = 'buitenland' | 'buitenlandDetails' | 'uren' | 'scholing' | 'punten' | 'review';\n\n/** One record carried across every step (and persisted). All optional: the user\n fills it in gradually, and branches may never ask some fields. */\nexport interface Answers {\n buitenlandGewerkt?: JaNee; // Q1\n land?: string; // Q1a — only when buitenlandGewerkt === 'ja'\n buitenlandseUren?: string; // Q1b — only when buitenlandGewerkt === 'ja'\n uren?: string; // Q2 — uren in NL\n scholingGevolgd?: JaNee; // Q3 — only when total hours are below the threshold\n punten?: string; // Q4\n}\n\n/** What we have after the review step parses — guaranteed valid/typed. */\nexport interface ValidIntake {\n werktBuitenland: boolean;\n land?: string;\n buitenlandseUren?: Uren;\n uren: Uren;\n aanvullendeScholing?: boolean;\n punten: Uren;\n}\n\n/** Below this many NL-hours we ask whether extra scholing was followed. */\nconst LAGE_UREN_DREMPEL = 1000;\n\nfunction lageUren(a: Answers): boolean {\n const r = parseUren(a.uren ?? '');\n return r.ok && r.value < LAGE_UREN_DREMPEL;\n}\n\n/**\n * THE branching, as one pure function. The step list is recomputed on every\n * transition, so changing an earlier answer immediately adds/removes later steps.\n */\nexport function visibleSteps(a: Answers): StepId[] {\n const steps: StepId[] = ['buitenland'];\n if (a.buitenlandGewerkt === 'ja') steps.push('buitenlandDetails');\n steps.push('uren');\n if (lageUren(a)) steps.push('scholing');\n steps.push('punten', 'review');\n return steps;\n}\n\nexport type IntakeState =\n | { tag: 'Answering'; answers: Answers; cursor: number; errors: PartialOne record carried across every step (and persisted). All optional: the user\nfills it in gradually, and branches may never ask some fields.
\n", "rawdescription": "\nOne record carried across every step (and persisted). All optional: the user\nfills it in gradually, and branches may never ask some fields.", "methods": [], "extends": [] }, { "name": "BigProfile", "id": "interface-BigProfile-c363e317899ff3cd424b0033c2f57ea14e9617f52401171543b5a82d67046a894a2806afc198812808d0080b3093471e081f7e79b12f2c8c37eef68785e47a43", "file": "src/app/registratie/domain/big-profile.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Registration } from './registration';\nimport { Person } from './person';\n\n/**\n * The view the dashboard/detail render: a registration (from the BIG-register)\n * enriched with person data (from the BRP). It only exists when BOTH sources\n * have loaded — see BigProfileStore, which builds it with map2.\n */\nexport interface BigProfile {\n registration: Registration;\n person: Person;\n}\n", "properties": [ { "name": "person", "deprecated": false, "deprecationMessage": "", "type": "Person", "indexKey": "", "optional": false, "description": "", "line": 11 }, { "name": "registration", "deprecated": false, "deprecationMessage": "", "type": "Registration", "indexKey": "", "optional": false, "description": "", "line": 10 } ], "indexSignatures": [], "kind": 172, "description": "The view the dashboard/detail render: a registration (from the BIG-register)\nenriched with person data (from the BRP). It only exists when BOTH sources\nhave loaded — see BigProfileStore, which builds it with map2.
\n", "rawdescription": "\n\nThe view the dashboard/detail render: a registration (from the BIG-register)\nenriched with person data (from the BRP). It only exists when BOTH sources\nhave loaded — see BigProfileStore, which builds it with map2.\n", "methods": [], "extends": [] }, { "name": "ChangeRequest", "id": "interface-ChangeRequest-8d79b6a9ce75f62f4e04f9d3ed0867e00d005c9c05cf267503536c4eec9813372aff51a3c8686927fd07f46503b60ddb4107edcc5f57fdfa1b6b52fe2a98026c", "file": "src/app/registratie/ui/change-request-form/change-request-form.component.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Component, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormFieldComponent } from '@shared/ui/form-field/form-field.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { Postcode, parsePostcode } from '@registratie/domain/value-objects/postcode';\n\n/** A submitted change request carries a *parsed* postcode (branded Postcode),\n not a raw string — downstream code can't receive an unvalidated one. */\nexport interface ChangeRequest {\n street: string;\n zip: Postcode;\n city: string;\n}\n\n/** Organism: change-request (adreswijziging) form. Reuses the same form-field\n molecule + text-input/button atoms as the login form. Field errors come\n straight from the parser's Result — no parallel \"is it valid\" flag to drift. */\n@Component({\n selector: 'app-change-request-form',\n imports: [FormsModule, FormFieldComponent, TextInputComponent, ButtonComponent, HeadingComponent],\n template: `\nA submitted change request carries a parsed postcode (branded Postcode),\nnot a raw string — downstream code can't receive an unvalidated one.
\n", "rawdescription": "\nA submitted change request carries a *parsed* postcode (branded Postcode),\nnot a raw string — downstream code can't receive an unvalidated one.", "methods": [], "extends": [] }, { "name": "Draft", "id": "interface-Draft-097a742aa05bc7bbfee387dd3ea5b2ac382815db8ca18107e699d11e6da110cdeae2eb377bcea284f415cfd263937c3b0f6e7ed2ee9090d660d898dddefe3a4f", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Result, assertNever } from '@shared/kernel/fp';\nimport { Uren, parseUren } from '@registratie/domain/value-objects/uren';\n\n/** What the user is typing (raw, possibly invalid). */\nexport interface Draft {\n uren: string;\n jaren: string;\n punten: string;\n}\n\n/** What we have AFTER parsing — branded/typed, guaranteed valid. */\nexport interface Valid {\n uren: Uren;\n jaren: number;\n punten: number;\n}\n\n/**\n * The whole wizard as one tagged union. `step` and `errors` exist ONLY while\n * Editing; Submitting/Submitted/Failed carry a `Valid` payload and nothing else.\n * So \"submitting while a field is invalid\" or \"showing the success screen with\n * errors set\" are unrepresentable — the bug class is gone by construction.\n */\nexport type WizardState =\n | { tag: 'Editing'; step: 1 | 2; draft: Draft; errors: PartialWhat the user is typing (raw, possibly invalid).
\n", "rawdescription": "\nWhat the user is typing (raw, possibly invalid).", "methods": [], "extends": [] }, { "name": "Person", "id": "interface-Person-07cec46d80a41919e40d0bcb002981627d1a30edb363d64a0a140a8af2c38ad85be5603d88030d0704870800694c5bed9c709ae6891fe83e646e90c1a67cf548", "file": "src/app/registratie/domain/person.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "export interface Adres {\n straat: string;\n postcode: string;\n woonplaats: string;\n}\n\nexport interface Person {\n naam: string;\n geboortedatum: string; // ISO date\n adres: Adres;\n}\n", "properties": [ { "name": "adres", "deprecated": false, "deprecationMessage": "", "type": "Adres", "indexKey": "", "optional": false, "description": "", "line": 11 }, { "name": "geboortedatum", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 10 }, { "name": "naam", "deprecated": false, "deprecationMessage": "", "type": "string", "indexKey": "", "optional": false, "description": "", "line": 9 } ], "indexSignatures": [], "kind": 172, "methods": [], "extends": [] }, { "name": "RadioOption", "id": "interface-RadioOption-ac09f04d2bd5bb44d96600b5081778fdf878ad9137e373a0832855877706afbe37687f7937f568a890e541467637b067a6c8646dcb2005ab746f1a829d8d39a2", "file": "src/app/shared/ui/radio-group/radio-group.component.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Component, forwardRef, input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface RadioOption {\n value: string;\n label: string;\n}\n\n/** Atom: a radio group. Thin wrapper over the Utrecht/RHC radio CSS, wired as a\n form control so it works with ngModel just like the text-input atom. */\n@Component({\n selector: 'app-radio-group',\n template: `\nWho is logged in. Framework-free domain type.
\n", "rawdescription": "\nWho is logged in. Framework-free domain type.", "methods": [], "extends": [] }, { "name": "Store", "id": "interface-Store-de6d0ec7e0704c5d9490e9a33e624477e924daff53384c527eb4aaa76178bd1716ada071d7e46af3e0a859a7cbec63cdc114f61db5d36b61e49effcd5ac744f9", "file": "src/app/shared/application/store.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Signal, signal } from '@angular/core';\n\n/**\n * A tiny \"Elm-style\" store. The whole idea: all state lives in ONE value\n * (the Model). The only way to change it is to send a message (Msg) to a PURE\n * function `update(model, msg)` that returns the next Model. Nothing else\n * mutates state, so to understand the app you only read the update function.\n *\n * Side effects (HTTP, timers) do NOT go in `update` — that stays pure and easy\n * to test. Instead, effectful \"command\" functions call the network and then\n * `dispatch` a message describing what happened (e.g. Loaded / Failed).\n */\nexport interface StoreThe current state, as a read-only Angular signal.
\n", "line": 15, "rawdescription": "\nThe current state, as a read-only Angular signal.", "modifierKind": [ 148 ] } ], "indexSignatures": [], "kind": 174, "description": "A tiny "Elm-style" store. The whole idea: all state lives in ONE value\n(the Model). The only way to change it is to send a message (Msg) to a PURE\nfunction update(model, msg) that returns the next Model. Nothing else\nmutates state, so to understand the app you only read the update function.
Side effects (HTTP, timers) do NOT go in update — that stays pure and easy\nto test. Instead, effectful "command" functions call the network and then\ndispatch a message describing what happened (e.g. Loaded / Failed).
Send a message; the model becomes update(model, msg).
\n", "jsdoctags": [ { "name": "msg", "type": "Msg", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "extends": [] }, { "name": "Valid", "id": "interface-Valid-097a742aa05bc7bbfee387dd3ea5b2ac382815db8ca18107e699d11e6da110cdeae2eb377bcea284f415cfd263937c3b0f6e7ed2ee9090d660d898dddefe3a4f", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Result, assertNever } from '@shared/kernel/fp';\nimport { Uren, parseUren } from '@registratie/domain/value-objects/uren';\n\n/** What the user is typing (raw, possibly invalid). */\nexport interface Draft {\n uren: string;\n jaren: string;\n punten: string;\n}\n\n/** What we have AFTER parsing — branded/typed, guaranteed valid. */\nexport interface Valid {\n uren: Uren;\n jaren: number;\n punten: number;\n}\n\n/**\n * The whole wizard as one tagged union. `step` and `errors` exist ONLY while\n * Editing; Submitting/Submitted/Failed carry a `Valid` payload and nothing else.\n * So \"submitting while a field is invalid\" or \"showing the success screen with\n * errors set\" are unrepresentable — the bug class is gone by construction.\n */\nexport type WizardState =\n | { tag: 'Editing'; step: 1 | 2; draft: Draft; errors: PartialWhat we have AFTER parsing — branded/typed, guaranteed valid.
\n", "rawdescription": "\nWhat we have AFTER parsing — branded/typed, guaranteed valid.", "methods": [], "extends": [] }, { "name": "ValidIntake", "id": "interface-ValidIntake-53c06ae2dad9470cd0c742a7e5903458a870e5eaaf70ce3043cec53935f09d2cb0d5f9980b723ce79be2460d550908bc894743c867abdf0974f17f7596cdd05d", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "type": "interface", "sourceCode": "import { Result, ok, err, assertNever } from '@shared/kernel/fp';\nimport { Uren, parseUren } from '@registratie/domain/value-objects/uren';\n\n/**\n * A BRANCHING wizard. Unlike herregistratie.machine (fixed 2 steps), the set of\n * steps here is NOT stored — it's *derived* from the answers by `visibleSteps`.\n * Answer \"buiten Nederland gewerkt? → ja\" and two extra steps appear; report few\n * hours and a scholing-question appears. The progress bar's denominator changes\n * as you type. \"Which question comes next\" is a pure function, so it's trivial\n * to test and impossible to get out of sync with the data.\n */\n\nexport type JaNee = 'ja' | 'nee';\n\n/** Every possible question, as a union — never a bare string. */\nexport type StepId = 'buitenland' | 'buitenlandDetails' | 'uren' | 'scholing' | 'punten' | 'review';\n\n/** One record carried across every step (and persisted). All optional: the user\n fills it in gradually, and branches may never ask some fields. */\nexport interface Answers {\n buitenlandGewerkt?: JaNee; // Q1\n land?: string; // Q1a — only when buitenlandGewerkt === 'ja'\n buitenlandseUren?: string; // Q1b — only when buitenlandGewerkt === 'ja'\n uren?: string; // Q2 — uren in NL\n scholingGevolgd?: JaNee; // Q3 — only when total hours are below the threshold\n punten?: string; // Q4\n}\n\n/** What we have after the review step parses — guaranteed valid/typed. */\nexport interface ValidIntake {\n werktBuitenland: boolean;\n land?: string;\n buitenlandseUren?: Uren;\n uren: Uren;\n aanvullendeScholing?: boolean;\n punten: Uren;\n}\n\n/** Below this many NL-hours we ask whether extra scholing was followed. */\nconst LAGE_UREN_DREMPEL = 1000;\n\nfunction lageUren(a: Answers): boolean {\n const r = parseUren(a.uren ?? '');\n return r.ok && r.value < LAGE_UREN_DREMPEL;\n}\n\n/**\n * THE branching, as one pure function. The step list is recomputed on every\n * transition, so changing an earlier answer immediately adds/removes later steps.\n */\nexport function visibleSteps(a: Answers): StepId[] {\n const steps: StepId[] = ['buitenland'];\n if (a.buitenlandGewerkt === 'ja') steps.push('buitenlandDetails');\n steps.push('uren');\n if (lageUren(a)) steps.push('scholing');\n steps.push('punten', 'review');\n return steps;\n}\n\nexport type IntakeState =\n | { tag: 'Answering'; answers: Answers; cursor: number; errors: PartialWhat we have after the review step parses — guaranteed valid/typed.
\n", "rawdescription": "\nWhat we have after the review step parses — guaranteed valid/typed.", "methods": [], "extends": [] } ], "injectables": [ { "name": "BigProfileStore", "id": "injectable-BigProfileStore-d0fd61e9f3ea54ee7ebca6eb9a097da261a7447f337e972e7bbb2a8c238f15a8f175b1fddac6c031fc95f77ab8d2778748a149f358ef5f5ec22ecaa23971ef9a", "file": "src/app/registratie/application/big-profile.store.ts", "properties": [ { "name": "aantekeningen", "defaultValue": "computedSpecialisms/notes stay a separate stream (they have their own empty state).
\n", "line": 41, "rawdescription": "\nSpecialisms/notes stay a separate stream (they have their own empty state).", "modifierKind": [ 148 ] }, { "name": "aantekeningenRes", "defaultValue": "this.big.aantekeningenResource()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 26, "modifierKind": [ 123 ] }, { "name": "big", "defaultValue": "inject(BigRegisterAdapter)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 22, "modifierKind": [ 123 ] }, { "name": "brp", "defaultValue": "inject(BrpAdapter)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 23, "modifierKind": [ 123 ] }, { "name": "pending", "defaultValue": "signal(false)", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 46, "modifierKind": [ 123 ] }, { "name": "pendingHerregistratie", "defaultValue": "this.pending.asReadonly()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "True while a herregistratie submission is in flight or just submitted.
\n", "line": 48, "rawdescription": "\nTrue while a herregistratie submission is in flight or just submitted.", "modifierKind": [ 148 ] }, { "name": "personRes", "defaultValue": "this.brp.personResource()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 27, "modifierKind": [ 123 ] }, { "name": "profile", "defaultValue": "computedBIG-register + BRP folded into one state.
\n", "line": 30, "rawdescription": "\nBIG-register + BRP folded into one state.", "modifierKind": [ 148 ] }, { "name": "registrationRes", "defaultValue": "this.big.registrationResource()", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 25, "modifierKind": [ 123 ] } ], "methods": [ { "name": "beginHerregistratie", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 50, "deprecated": false, "deprecationMessage": "" }, { "name": "confirmHerregistratie", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 53, "deprecated": false, "deprecationMessage": "" }, { "name": "rollbackHerregistratie", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 57, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "description": "The single source of truth for the logged-in professional's profile, shared\nacross pages (providedIn:'root' = one instance). It owns the httpResources\n(created here, in the required injection context) and exposes them as\nRemoteData signals.
\nThe headline trick: profile combines TWO independent services — the\nBIG-register and the BRP — into ONE RemoteData via map2. A page renders a\nsingle state (loading / error / loaded), never juggling three.
Infrastructure adapter for the BIG-register source. Exposes signal-based\nresources (Angular's httpResource); each returns a Resource with\nstatus()/value()/error()/reload(). Call from an injection context\n(a field initializer in the store).
\n", "rawdescription": "\n\nInfrastructure adapter for the BIG-register source. Exposes signal-based\nresources (Angular's httpResource); each returns a Resource with\nstatus()/value()/error()/reload(). Call from an injection context\n(a field initializer in the store).\n", "sourceCode": "import { Injectable } from '@angular/core';\nimport { httpResource } from '@angular/common/http';\nimport { Registration, Aantekening } from '../domain/registration';\n\n/**\n * Infrastructure adapter for the BIG-register source. Exposes signal-based\n * resources (Angular's httpResource); each returns a Resource with\n * status()/value()/error()/reload(). Call from an injection context\n * (a field initializer in the store).\n */\n@Injectable({ providedIn: 'root' })\nexport class BigRegisterAdapter {\n registrationResource() {\n return httpResourceInfrastructure adapter for the BRP (Basisregistratie Personen) source.
\n", "rawdescription": "\nInfrastructure adapter for the BRP (Basisregistratie Personen) source.", "sourceCode": "import { Injectable } from '@angular/core';\nimport { httpResource } from '@angular/common/http';\nimport { Person } from '../domain/person';\n\n/** Infrastructure adapter for the BRP (Basisregistratie Personen) source. */\n@Injectable({ providedIn: 'root' })\nexport class BrpAdapter {\n personResource() {\n return httpResourceInfrastructure: talks to the (mock) DigiD identity provider.
\n", "rawdescription": "\nInfrastructure: talks to the (mock) DigiD identity provider.", "sourceCode": "import { Injectable } from '@angular/core';\nimport { Result, ok, err } from '@shared/kernel/fp';\nimport { Session } from '../domain/session';\n\n/** Infrastructure: talks to the (mock) DigiD identity provider. */\n@Injectable({ providedIn: 'root' })\nexport class DigidAdapter {\n // ponytail: fake DigiD — any 9-digit BSN authenticates to a fixed identity.\n // Swap for a real OIDC redirect flow when there's a backend.\n async authenticate(bsn: string): PromiseEffectful command: authenticate, then store the session on success.
\n", "modifierKind": [ 134 ], "jsdoctags": [ { "name": "bsn", "type": "string", "optional": false, "dotDotDotToken": false, "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "logout", "args": [], "optional": false, "returnType": "void", "typeParameters": [], "line": 27, "deprecated": false, "deprecationMessage": "" } ], "deprecated": false, "deprecationMessage": "", "description": "Holds the current session for the whole app. Because it is providedIn:'root'\nthere is exactly one instance — every component that injects it sees the same\nsession signal, so logging in is instantly visible everywhere (the guard, the\nheader, etc.). ponytail: in-memory only; a refresh logs you out.
\n", "rawdescription": "\n\nHolds the current session for the whole app. Because it is providedIn:'root'\nthere is exactly one instance — every component that injects it sees the same\nsession signal, so logging in is instantly visible everywhere (the guard, the\nheader, etc.). ponytail: in-memory only; a refresh logs you out.\n", "sourceCode": "import { Injectable, computed, inject, signal } from '@angular/core';\nimport { Result } from '@shared/kernel/fp';\nimport { Session } from '../domain/session';\nimport { DigidAdapter } from '../infrastructure/digid.adapter';\n\n/**\n * Holds the current session for the whole app. Because it is providedIn:'root'\n * there is exactly one instance — every component that injects it sees the same\n * session signal, so logging in is instantly visible everywhere (the guard, the\n * header, etc.). ponytail: in-memory only; a refresh logs you out.\n */\n@Injectable({ providedIn: 'root' })\nexport class SessionStore {\n private digid = inject(DigidAdapter);\n private _session = signalGeen gegevens gevonden.
}\n }\n @case ('Success') {\nGeen gegevens gevonden.
}\n }\n @case ('Success') {\nGeen gegevens gevonden.
}\n }\n @case ('Success') {\nGeen gegevens gevonden.
}\n }\n @case ('Success') {\nAtom: alert/message banner.
\n", "rawdescription": "\nAtom: alert/message banner.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\ntype AlertType = 'info' | 'ok' | 'warning' | 'error';\n\n/** Atom: alert/message banner. */\n@Component({\n selector: 'app-alert',\n template: `\nGeen gegevens gevonden.
}\n }\n @case ('Success') {\nRenders exactly ONE of loading / empty / error / loaded for a signal-based\nresource (e.g. httpResource). Built on a RemoteData tagged union (see\ncore/remote-data.ts), so the states are mutually exclusive by construction —\nthe UI can never show two at once ("impossible states"). Unprovided slots\nfall back to sensible defaults.
\n", "rawdescription": "\n\nRenders exactly ONE of loading / empty / error / loaded for a signal-based\nresource (e.g. httpResource). Built on a RemoteData tagged union (see\ncore/remote-data.ts), so the states are mutually exclusive by construction —\nthe UI can never show two at once (\"impossible states\"). Unprovided slots\nfall back to sensible defaults.\n", "type": "component", "sourceCode": "import { Component, Directive, TemplateRef, computed, contentChild, input } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport type { Resource } from '@angular/core';\nimport { SpinnerComponent } from '@shared/ui/spinner/spinner.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { RemoteData, fromResource, foldRemote } from '@shared/application/remote-data';\n\n/* Slot markers. Put onGeen gegevens gevonden.
}\n }\n @case ('Success') {\nAtom: button. Thin wrapper over the Utrecht/RHC button CSS.
\n", "rawdescription": "\nAtom: button. Thin wrapper over the Utrecht/RHC button CSS.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\ntype Variant = 'primary' | 'secondary' | 'subtle' | 'danger';\n\n/** Atom: button. Thin wrapper over the Utrecht/RHC button CSS. */\n@Component({\n selector: 'app-button',\n template: `\n \n `,\n})\nexport class ButtonComponent {\n variant = inputOrganism: change-request (adreswijziging) form. Reuses the same form-field\nmolecule + text-input/button atoms as the login form. Field errors come\nstraight from the parser's Result — no parallel "is it valid" flag to drift.
\n", "rawdescription": "\nOrganism: change-request (adreswijziging) form. Reuses the same form-field\nmolecule + text-input/button atoms as the login form. Field errors come\nstraight from the parser's Result — no parallel \"is it valid\" flag to drift.", "type": "component", "sourceCode": "import { Component, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormFieldComponent } from '@shared/ui/form-field/form-field.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { Postcode, parsePostcode } from '@registratie/domain/value-objects/postcode';\n\n/** A submitted change request carries a *parsed* postcode (branded Postcode),\n not a raw string — downstream code can't receive an unvalidated one. */\nexport interface ChangeRequest {\n street: string;\n zip: Postcode;\n city: string;\n}\n\n/** Organism: change-request (adreswijziging) form. Reuses the same form-field\n molecule + text-input/button atoms as the login form. Field errors come\n straight from the parser's Result — no parallel \"is it valid\" flag to drift. */\n@Component({\n selector: 'app-change-request-form',\n imports: [FormsModule, FormFieldComponent, TextInputComponent, ButtonComponent, HeadingComponent],\n template: `\n\n Vijf functionele patronen die atomic design makkelijker maakt om te tonen — telkens\n \"fout\" (de oude vorm liet het toe) naast \"goed\" (het type maakt het onmogelijk).\n
\n\n \nLaat elke variant precies de gegevens dragen die kloppen — niets meer.
\nFout — vlakke interface
\n \nEen doorgehaalde registratie houdt tóch een herregistratiedatum: onmogelijke toestand.
\nGoed — sum type
\nDe variant Doorgehaald kent geen herregistratiedatum, dus de rij bestaat simpelweg niet.
Eén waarde met vier elkaar uitsluitende toestanden in plaats van drie losse booleans.
\nVier toestanden, één molecuul
\nLoading
\nEmpty
\nFailure
\nSuccess
\nDe exhaustieve fold
\n \nEen nieuwe variant toevoegen breekt de compile via assertNever tot je hem afhandelt.
Na het parsen onthoudt het type dat de waarde geldig is.
\nSmart constructor → Result
\nok
\nPostcode = \"{{ $any(parsed()).value }}\"\n Een gevalideerde Postcode is een ander type dan een ruwe string.
err
\n{{ $any(parsed()).error }}\n }\n Eén tagged union stuurt de UI. Speel met de wizard — de gemarkeerde toestand is de huidige.
\nFout — losse booleans
\n \nNiets verhindert \"submitting\" mét validatiefouten of een successcherm met errors.
\nGoed — één tagged union
\n\n Welke stappen bestaan is geen opgeslagen toestand maar een pure functie van de antwoorden\n (visibleSteps(answers)). Antwoord \"ja\" op buitenland of vul weinig uren in, en de\n lijst hieronder groeit mee.\n
Live afgeleide stappen
\nDe gestippelde stappen verschijnen alleen door eerdere antwoorden. De voortgang \"van N\" verandert mee.
\nDe wizard
\nTeaching showcase: each section pairs the impossible-state-permitting "before"\nwith the "after" where the type system rules it out. Composition-only.
\n", "rawdescription": "\nTeaching showcase: each section pairs the impossible-state-permitting \"before\"\nwith the \"after\" where the type system rules it out. Composition-only.", "type": "component", "sourceCode": "import { Component, computed, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport type { Resource } from '@angular/core';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ASYNC } from '@shared/ui/async/async.component';\nimport { SkeletonComponent } from '@shared/ui/skeleton/skeleton.component';\nimport { RegistrationSummaryComponent } from '@registratie/ui/registration-summary/registration-summary.component';\nimport { HerregistratieWizardComponent } from '@herregistratie/ui/herregistratie-wizard/herregistratie-wizard.component';\nimport { IntakeWizardComponent } from '@herregistratie/ui/intake-wizard/intake-wizard.component';\nimport { Registration } from '@registratie/domain/registration';\nimport { parsePostcode } from '@registratie/domain/value-objects/postcode';\n\n/** Minimal fake Resource so\n Vijf functionele patronen die atomic design makkelijker maakt om te tonen — telkens\n \"fout\" (de oude vorm liet het toe) naast \"goed\" (het type maakt het onmogelijk).\n
\n\n \nLaat elke variant precies de gegevens dragen die kloppen — niets meer.
\nFout — vlakke interface
\n \nEen doorgehaalde registratie houdt tóch een herregistratiedatum: onmogelijke toestand.
\nGoed — sum type
\nDe variant Doorgehaald kent geen herregistratiedatum, dus de rij bestaat simpelweg niet.
Eén waarde met vier elkaar uitsluitende toestanden in plaats van drie losse booleans.
\nVier toestanden, één molecuul
\nLoading
\nEmpty
\nFailure
\nSuccess
\nDe exhaustieve fold
\n \nEen nieuwe variant toevoegen breekt de compile via assertNever tot je hem afhandelt.
Na het parsen onthoudt het type dat de waarde geldig is.
\nSmart constructor → Result
\nok
\nPostcode = \"{{ $any(parsed()).value }}\"\n Een gevalideerde Postcode is een ander type dan een ruwe string.
err
\n{{ $any(parsed()).error }}\n }\n Eén tagged union stuurt de UI. Speel met de wizard — de gemarkeerde toestand is de huidige.
\nFout — losse booleans
\n \nNiets verhindert \"submitting\" mét validatiefouten of een successcherm met errors.
\nGoed — één tagged union
\n\n Welke stappen bestaan is geen opgeslagen toestand maar een pure functie van de antwoorden\n (visibleSteps(answers)). Antwoord \"ja\" op buitenland of vul weinig uren in, en de\n lijst hieronder groeit mee.\n
Live afgeleide stappen
\nDe gestippelde stappen verschijnen alleen door eerdere antwoorden. De voortgang \"van N\" verandert mee.
\nDe wizard
\nU heeft nog geen specialismen of aantekeningen.
\n\n
\n
\n
\n
U heeft nog geen specialismen of aantekeningen.
\n\n
\n
\n
\n
Molecule: one key/value row inside an RHC data-summary.\nWrap several of these in .rhc-data-summary (see registration-summary).
\n", "rawdescription": "\nMolecule: one key/value row inside an RHC data-summary.\nWrap several of these in .rhc-data-summary (see registration-summary).", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\n/** Molecule: one key/value row inside an RHC data-summary.\n Wrap several of these in .rhc-data-summary (see registration-summary). */\n@Component({\n selector: 'app-data-row',\n template: `\nMolecule: form field = label + projected control + optional error/description.\nReused by both the login form and the change-request form.
\n", "rawdescription": "\nMolecule: form field = label + projected control + optional error/description.\nReused by both the login form and the change-request form.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\n/** Molecule: form field = label + projected control + optional error/description.\n Reused by both the login form and the change-request form. */\n@Component({\n selector: 'app-form-field',\n template: `\nAtom: heading. Renders the right h1..h5 with RHC heading styling.\nSingle
A whole new page built from existing building blocks. Eligibility is a pure\ndomain rule (registration.policy) read from the shared profile state.
\n", "rawdescription": "\nA whole new page built from existing building blocks. Eligibility is a pure\ndomain rule (registration.policy) read from the shared profile state.", "type": "component", "sourceCode": "import { Component, computed, inject } from '@angular/core';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { ASYNC } from '@shared/ui/async/async.component';\nimport { map } from '@shared/application/remote-data';\nimport { BigProfileStore } from '@registratie/application/big-profile.store';\nimport { isHerregistratieEligible } from '@registratie/domain/registration.policy';\nimport { HerregistratieWizardComponent } from '@herregistratie/ui/herregistratie-wizard/herregistratie-wizard.component';\n\n/** A whole new page built from existing building blocks. Eligibility is a pure\n domain rule (registration.policy) read from the shared profile state. */\n@Component({\n selector: 'app-herregistratie-page',\n imports: [PageShellComponent, AlertComponent, ...ASYNC, HerregistratieWizardComponent],\n template: `\nStap {{ step() }} van 2
\n \n }\n @case ('Submitting') {\nOptional seed so Storybook / the showcase can mount any state directly.
\n", "line": 69, "rawdescription": "\nOptional seed so Storybook / the showcase can mount any state directly.", "required": false } ], "outputsClass": [], "propertiesClass": [ { "name": "dispatch", "defaultValue": "this.store.dispatch", "deprecated": false, "deprecationMessage": "", "type": "unknown", "indexKey": "", "optional": false, "description": "", "line": 72, "modifierKind": [ 124 ] }, { "name": "draft", "defaultValue": "computedThe effect: when we entered Submitting, call the backend command, flip the\noptimistic cross-page flag, then dispatch the result (and commit/rollback).
\n", "modifierKind": [ 123, 134 ] } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "FormsModule", "type": "module" }, { "name": "FormFieldComponent", "type": "component" }, { "name": "TextInputComponent", "type": "component" }, { "name": "ButtonComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "SpinnerComponent", "type": "component" } ], "description": "Organism: multi-step herregistratie wizard. ALL state lives in one signal\ndriven by the pure reduce function (see herregistratie.machine.ts) via an\nElm-style store. The UI just sends messages and folds over the state's tag —\nno booleans like submitting/submitted that could contradict each other.\nSubmitting also flips an optimistic flag on the shared BigProfileStore, so\nthe dashboard shows "in behandeling" immediately.
Stap {{ step() }} van 2
\n \n }\n @case ('Submitting') {\nPage: the branching intake questionnaire. Built entirely from existing\nbuilding blocks (page shell + alert + the intake-wizard organism).
\n", "rawdescription": "\nPage: the branching intake questionnaire. Built entirely from existing\nbuilding blocks (page shell + alert + the intake-wizard organism).", "type": "component", "sourceCode": "import { Component } from '@angular/core';\nimport { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';\nimport { AlertComponent } from '@shared/ui/alert/alert.component';\nimport { IntakeWizardComponent } from '@herregistratie/ui/intake-wizard/intake-wizard.component';\n\n/** Page: the branching intake questionnaire. Built entirely from existing\n building blocks (page shell + alert + the intake-wizard organism). */\n@Component({\n selector: 'app-intake-page',\n imports: [PageShellComponent, AlertComponent, IntakeWizardComponent],\n template: `\nStap {{ cursor() + 1 }} van {{ steps().length }}
\n \n }\n @case ('Submitting') {\nOptional seed so Storybook / the showcase can mount any state directly.
\n", "line": 116, "rawdescription": "\nOptional seed so Storybook / the showcase can mount any state directly.", "required": false } ], "outputsClass": [], "propertiesClass": [ { "name": "answering", "defaultValue": "computed(() => (this.state().tag === 'Answering' ? (this.state() as ExtractPublic so the showcase can render the live step list next to the wizard.
\n", "line": 124, "rawdescription": "\nPublic so the showcase can render the live step list next to the wizard.", "modifierKind": [ 148 ] }, { "name": "store", "defaultValue": "createStoreThe effect: when we enter Submitting, call the backend, flip the optimistic\ncross-page flag, then dispatch the outcome (and commit/rollback).
\n", "modifierKind": [ 123, 134 ] } ], "deprecated": false, "deprecationMessage": "", "hostBindings": [], "hostListeners": [], "standalone": false, "imports": [ { "name": "FormsModule", "type": "module" }, { "name": "FormFieldComponent", "type": "component" }, { "name": "TextInputComponent", "type": "component" }, { "name": "RadioGroupComponent", "type": "component" }, { "name": "ButtonComponent", "type": "component" }, { "name": "AlertComponent", "type": "component" }, { "name": "SpinnerComponent", "type": "component" } ], "description": "Organism: a BRANCHING intake questionnaire. All state lives in one signal\ndriven by the pure reduce (intake.machine.ts). Which step renders is derived\nfrom the answers via visibleSteps, never stored — so editing an earlier\nanswer immediately changes the remaining steps. Answers are persisted to\nlocalStorage so a page reload keeps the user's progress.
Stap {{ cursor() + 1 }} van {{ steps().length }}
\n \n }\n @case ('Submitting') {\nAtom: link. Internal router link styled as an RHC/Utrecht link.
\n", "rawdescription": "\nAtom: link. Internal router link styled as an RHC/Utrecht link.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\n/** Atom: link. Internal router link styled as an RHC/Utrecht link. */\n@Component({\n selector: 'app-link',\n imports: [RouterLink],\n template: `Organism: DigiD-style mock login. No real auth — just composes atoms/molecules.
\n", "rawdescription": "\nOrganism: DigiD-style mock login. No real auth — just composes atoms/molecules.", "type": "component", "sourceCode": "import { Component, output } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { FormFieldComponent } from '@shared/ui/form-field/form-field.component';\nimport { TextInputComponent } from '@shared/ui/text-input/text-input.component';\nimport { ButtonComponent } from '@shared/ui/button/button.component';\n\n/** Organism: DigiD-style mock login. No real auth — just composes atoms/molecules. */\n@Component({\n selector: 'app-login-form',\n imports: [FormsModule, FormFieldComponent, TextInputComponent, ButtonComponent],\n template: `\n \n `,\n})\nexport class LoginFormComponent {\n bsn = '';\n password = '';\n submitted = output{{ intro() }}
\n }\nTemplate: standard page body — optional back-link, a heading, optional intro,\nand projected content. Rendered inside the persistent ShellComponent via the\nrouter outlet, so it owns only the content (not the header/footer chrome).
\n", "rawdescription": "\nTemplate: standard page body — optional back-link, a heading, optional intro,\nand projected content. Rendered inside the persistent ShellComponent via the\nrouter outlet, so it owns only the content (not the header/footer chrome).", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { HeadingComponent } from '@shared/ui/heading/heading.component';\nimport { LinkComponent } from '@shared/ui/link/link.component';\n\n/** Template: standard page body — optional back-link, a heading, optional intro,\n and projected content. Rendered inside the persistent ShellComponent via the\n router outlet, so it owns only the content (not the header/footer chrome). */\n@Component({\n selector: 'app-page-shell',\n imports: [HeadingComponent, LinkComponent],\n styles: [':host{display:block}'],\n template: `\n{{ intro() }}
\n }\nAtom: a radio group. Thin wrapper over the Utrecht/RHC radio CSS, wired as a\nform control so it works with ngModel just like the text-input atom.
\n", "rawdescription": "\nAtom: a radio group. Thin wrapper over the Utrecht/RHC radio CSS, wired as a\nform control so it works with ngModel just like the text-input atom.", "type": "component", "sourceCode": "import { Component, forwardRef, input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface RadioOption {\n value: string;\n label: string;\n}\n\n/** Atom: a radio group. Thin wrapper over the Utrecht/RHC radio CSS, wired as a\n form control so it works with ngModel just like the text-input atom. */\n@Component({\n selector: 'app-radio-group',\n template: `\nOrganism: registration summary card. Composes data-row molecules + status-badge atom.
\n", "rawdescription": "\nOrganism: registration summary card. Composes data-row molecules + status-badge atom.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { Registration } from '@registratie/domain/registration';\nimport { statusColor, statusLabel } from '@registratie/domain/registration.policy';\nimport { DataRowComponent } from '@shared/ui/data-row/data-row.component';\nimport { StatusBadgeComponent } from '@shared/ui/status-badge/status-badge.component';\n\n/** Organism: registration summary card. Composes data-row molecules + status-badge atom. */\n@Component({\n selector: 'app-registration-summary',\n imports: [DatePipe, DataRowComponent, StatusBadgeComponent],\n template: `\n| Type | \nOmschrijving | \nDatum | \n
|---|---|---|
| {{ row.type }} | \n{{ row.omschrijving }} | \n{{ row.datum | date:'mediumDate' }} | \n
Organism: table of specialismen/aantekeningen.
\n", "rawdescription": "\nOrganism: table of specialismen/aantekeningen.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { DatePipe } from '@angular/common';\nimport { Aantekening } from '@registratie/domain/registration';\n\n/** Organism: table of specialismen/aantekeningen. */\n@Component({\n selector: 'app-registration-table',\n imports: [DatePipe],\n template: `\n| Type | \nOmschrijving | \nDatum | \n
|---|---|---|
| {{ row.type }} | \n{{ row.omschrijving }} | \n{{ row.datum | date:'mediumDate' }} | \n
Template: persistent app chrome. Header + footer mount once; only the routed\ncontent inside
Organism: site footer.
\n", "rawdescription": "\nOrganism: site footer.", "type": "component", "sourceCode": "import { Component } from '@angular/core';\n\n/** Organism: site footer. */\n@Component({\n selector: 'app-site-footer',\n styles: [':host{display:block}'],\n template: `\n \n `,\n})\nexport class SiteFooterComponent {}\n", "assetsDirs": [], "styleUrlsData": "", "stylesData": ":host{display:block}\n", "extends": [] }, { "name": "SiteHeaderComponent", "id": "component-SiteHeaderComponent-710f1c109f26ae5f1888aa77ac682c58c9534fbba74aeae04b903e169f674c1ce04b8ae9e379a936c8ddef16e53c500e93d132021bcdd4ef743a601e05808f66", "file": "src/app/shared/layout/site-header/site-header.component.ts", "encapsulation": [], "entryComponents": [], "inputs": [], "outputs": [], "providers": [], "selector": "app-site-header", "styleUrls": [], "styles": [ ":host{display:block}" ], "template": "Organism: site header with Rijksoverheid-style wordmark + title.\nponytail: text wordmark instead of the licensed Rijksoverheid logo.
\n", "rawdescription": "\nOrganism: site header with Rijksoverheid-style wordmark + title.\nponytail: text wordmark instead of the licensed Rijksoverheid logo.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\n/** Organism: site header with Rijksoverheid-style wordmark + title.\n ponytail: text wordmark instead of the licensed Rijksoverheid logo. */\n@Component({\n selector: 'app-site-header',\n imports: [RouterLink],\n // :host display:block so the full-bleed bar fills the flex column (custom\n // elements default to display:inline, which collapsed the bar to its content).\n styles: [':host{display:block}'],\n template: `\nAtom: skeleton placeholder (grey shimmer). Delay-gated so it never flashes\non fast responses. Render count lines shaped roughly like the content.
Atom: spinner that only appears after delay ms — fast responses never\nflash a spinner, slow ones get feedback.
Atom: a coloured dot + label. Purely presentational and domain-free — the\ncaller decides what colour and label mean (e.g. via registration.policy).\nThis keeps the shared UI kernel free of any domain knowledge.
\n", "rawdescription": "\nAtom: a coloured dot + label. Purely presentational and domain-free — the\ncaller decides what colour and label mean (e.g. via registration.policy).\nThis keeps the shared UI kernel free of any domain knowledge.", "type": "component", "sourceCode": "import { Component, input } from '@angular/core';\n\n/** Atom: a coloured dot + label. Purely presentational and domain-free — the\n caller decides what colour and label mean (e.g. via registration.policy).\n This keeps the shared UI kernel free of any domain knowledge. */\n@Component({\n selector: 'app-status-badge',\n template: `\n \n \n {{ label() }}\n \n `,\n})\nexport class StatusBadgeComponent {\n label = input.requiredAtom: text input. Utrecht textbox wired up as a form control (ngModel/reactive).
\n", "rawdescription": "\nAtom: text input. Utrecht textbox wired up as a form control (ngModel/reactive).", "type": "component", "sourceCode": "import { Component, forwardRef, input } from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\n/** Atom: text input. Utrecht textbox wired up as a form control (ngModel/reactive). */\n@Component({\n selector: 'app-text-input',\n template: `\n \n `,\n providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextInputComponent), multi: true }],\n})\nexport class TextInputComponent implements ControlValueAccessor {\n type = input<'text' | 'password' | 'email'>('text');\n placeholder = input('');\n invalid = input(false);\n inputId = inputConvenience: import this array to get the wrapper + all slot directives.
\n" }, { "name": "authGuard", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/auth/auth.guard.ts", "deprecated": false, "deprecationMessage": "", "type": "CanActivateFn", "defaultValue": "() => {\n const store = inject(SessionStore);\n const router = inject(Router);\n return store.isAuthenticated() ? true : router.createUrlTree(['/login']);\n}", "rawdescription": "Route guard: only let authenticated users in; otherwise redirect to /login.", "description": "Route guard: only let authenticated users in; otherwise redirect to /login.
\n" }, { "name": "err", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "Below this many NL-hours we ask whether extra scholing was followed.
\n" }, { "name": "ok", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "Demo-only: rewrites the timing/outcome of mock data requests based on\n?scenario= so loading / empty / error states can be shown on demand.\nReal requests are untouched.
\n" }, { "name": "STORAGE_KEY", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/herregistratie/ui/intake-wizard/intake-wizard.component.ts", "deprecated": false, "deprecationMessage": "", "type": "string", "defaultValue": "'intake-v1'" }, { "name": "VALID", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/infrastructure/scenario.ts", "deprecated": false, "deprecationMessage": "", "type": "Scenario[]", "defaultValue": "['default', 'slow', 'loading', 'empty', 'error']" } ], "functions": [ { "name": "andThen", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Chain a second source that depends on the first one's value.
\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataTiny native-TS functional toolkit. No dependency — this is the whole "library".\nReused by every "impossible states" concept in the POC.
\n", "args": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "" } ], "returnType": "never", "jsdoctags": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "back", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "back", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "createStore", "file": "src/app/shared/application/store.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "init", "type": "Model", "deprecated": false, "deprecationMessage": "" }, { "name": "update", "deprecated": false, "deprecationMessage": "" } ], "returnType": "StoreReads ?scenario= from the URL so a demo can force each async state.
\n", "args": [], "returnType": "Scenario" }, { "name": "currentStep", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Which step the cursor currently points at (clamped to the live step list).
\n", "args": [ { "name": "s", "type": "Extract", "deprecated": false, "deprecationMessage": "" } ], "returnType": "StepId", "jsdoctags": [ { "name": "s", "type": "Extract", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "fakeResource", "file": "src/app/showcase/concepts.page.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Minimal fake Resource so
Exhaustive fold: you must handle every case, checked at compile time.
\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "h", "deprecated": false, "deprecationMessage": "" } ], "returnType": "R", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "h", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "fromResource", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Project Angular's loosely-typed Resource into a RemoteData value.
\n", "args": [ { "name": "r", "type": "Resource", "deprecated": false, "deprecationMessage": "" }, { "name": "isEmpty", "deprecated": false, "deprecationMessage": "", "defaultValue": "() => false" } ], "returnType": "RemoteDataThe herregistratie deadline, if the status has one (only the active state does).
\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Date | null", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "isAuthenticated", "file": "src/app/auth/domain/session.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Session", "jsdoctags": [ { "name": "s", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "isHerregistratieEligible", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "A registration may apply for herregistratie only while active and within the\nwindow before its deadline. A struck-off or suspended registration may not.
\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "" }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12" } ], "returnType": "boolean", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12", "tagName": { "text": "param" } } ] }, { "name": "isStatusConsistent", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Invariant check used in tests/demos: a non-active status must not carry a\nherregistratie date. The union already enforces this structurally; this is\nthe runtime statement of the same rule.
\n", "args": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "" } ], "returnType": "boolean", "jsdoctags": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "lageUren", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "boolean", "jsdoctags": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "map", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Transform the value inside a Success; pass other states through unchanged.
\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataCombine two sources into one. Use this to merge e.g. a BIG-register call\nand a BRP call into a single state the page can render.
\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataCombine three sources (built on map2).
\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "c", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataStep 1 → 2: advance only when BOTH step-1 fields parse. Illegal elsewhere = no-op.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "next", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "parseBigNummer", "file": "src/app/registratie/domain/value-objects/big-nummer.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultResolve the async submit. Only meaningful while Submitting.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "resolve", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "setAnswer", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" }, { "name": "key", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "key", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "setField", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Update one draft field while editing; ignored in any other state.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "key", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "key", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusColor", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Brand colour token for a status. assertNever forces a colour for every new\nstatus variant at compile time.
\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusLabel", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Domain logic for a registration — pure functions, NO Angular. This is where\n"what the business rules say" lives, separate from "how it looks" (UI) and\n"where the data comes from" (infrastructure). Keeping it framework-free means\nit is trivial to read and unit-test.
\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submit", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Step 2 submit: parse everything; move to Submitting only with Valid data.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submit", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submitHerregistratie", "file": "src/app/herregistratie/application/submit-herregistratie.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "The mutation/command: send a herregistratie application to the backend.\nReturns a Result so the caller can branch on success/failure without\ntry/catch. ponytail: faked with a timer; swap for a real POST when there's\nan API. The "uren must be > 0" rule lets the demo show a failure path.
\n", "args": [ { "name": "data", "type": "Valid", "deprecated": false, "deprecationMessage": "" } ], "returnType": "PromiseCommand: send the intake questionnaire to the backend. Returns a Result so the\ncaller branches on success/failure without try/catch. ponytail: faked with a\ntimer; swap for a real POST when there's an API. The "uren must be > 0" rule\nlets the demo show the failure path.
\n", "args": [ { "name": "data", "type": "ValidIntake", "deprecated": false, "deprecationMessage": "" } ], "returnType": "PromiseParse every field; on success hand back a Valid, else the per-field errors.
\n", "args": [ { "name": "draft", "type": "Draft", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultParse the whole questionnaire into a ValidIntake (called on submit).
\n", "args": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultValidate ONE step's fields. Returns the per-field error keyed by StepId.
\n", "args": [ { "name": "step", "type": "StepId", "deprecated": false, "deprecationMessage": "" }, { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultTHE branching, as one pure function. The step list is recomputed on every\ntransition, so changing an earlier answer immediately adds/removes later steps.
\n", "args": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "StepId[]", "jsdoctags": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "typealiases": [ { "name": "AantekeningType", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"Specialisme\" | \"Aantekening\"", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "A note is either a recognised specialism or a plain annotation — a closed set,\nnot an open string, so a typo can't slip through.
\n", "kind": 193 }, { "name": "AlertType", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"info\" | \"ok\" | \"warning\" | \"error\"", "file": "src/app/shared/ui/alert/alert.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "BigNummer", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "BrandValue object: a BIG registration number — 11 digits.
\n", "kind": 184 }, { "name": "Brand", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "unknown", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "description": "Nominal typing: Brand<string, 'Postcode'> is assignable from a plain string\nonly through an explicit cast — so a smart constructor is the only minter.
\n", "kind": 194 }, { "name": "Err", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Error | undefined", "file": "src/app/registratie/application/big-profile.store.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "IntakeMsg", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type | literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "IntakeState", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "JaNee", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"ja\" | \"nee\"", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "A BRANCHING wizard. Unlike herregistratie.machine (fixed 2 steps), the set of\nsteps here is NOT stored — it's derived from the answers by visibleSteps.\nAnswer "buiten Nederland gewerkt? → ja" and two extra steps appear; report few\nhours and a scholing-question appears. The progress bar's denominator changes\nas you type. "Which question comes next" is a pure function, so it's trivial\nto test and impossible to get out of sync with the data.
Value object: a Dutch postcode. "Parse, don't validate" — a Postcode is a\ndistinct type from a raw string, mintable only via parsePostcode, so holding\none is proof it is well-formed.
\n", "kind": 184 }, { "name": "RegistrationStatus", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "Registration status as a discriminated union: each variant owns exactly the\ndata that makes sense for it. Only an active (Geregistreerd) registration has\na herregistratie date; a struck-off (Doorgehaald) one cannot carry one. The\nold flat interface allowed that impossible combination — this makes it\nunrepresentable.
\n", "kind": 193 }, { "name": "RemoteData", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/shared/application/remote-data.ts", "deprecated": false, "deprecationMessage": "", "description": "The four mutually-exclusive states of an async fetch, as a tagged union.\nCrucially the data lives ON the state: only Failure has an error, only\nSuccess has a value. "Loaded but no value" or "error with stale value"\nare unrepresentable — Richard Feldman's RemoteData.
A computation that either succeeded with a value or failed with an error.\nPlain objects (no classes) to match the signal/httpResource ergonomics.
\n", "kind": 193 }, { "name": "Scenario", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"default\" | \"slow\" | \"loading\" | \"empty\" | \"error\"", "file": "src/app/shared/infrastructure/scenario.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "StatusTag", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "RegistrationStatus", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "Just the discriminant — for atoms that only need the label/color.
\n", "kind": 200 }, { "name": "StepId", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"buitenland\" | \"buitenlandDetails\" | \"uren\" | \"scholing\" | \"punten\" | \"review\"", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "Every possible question, as a union — never a bare string.
\n", "kind": 193 }, { "name": "Uren", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "BrandValue object: a non-negative whole number of hours.
\n", "kind": 184 }, { "name": "Variant", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"primary\" | \"secondary\" | \"subtle\" | \"danger\"", "file": "src/app/shared/ui/button/button.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "WizardMsg", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type | literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "Every event that can happen to the wizard, as one message type. The component\nsends a WizardMsg; reduce decides the next state. This is the Elm\nModel+Msg+update pattern: ONE pure function describes all state changes.
The whole wizard as one tagged union. step and errors exist ONLY while\nEditing; Submitting/Submitted/Failed carry a Valid payload and nothing else.\nSo "submitting while a field is invalid" or "showing the success screen with\nerrors set" are unrepresentable — the bug class is gone by construction.
Convenience: import this array to get the wrapper + all slot directives.
\n" } ], "src/app/auth/auth.guard.ts": [ { "name": "authGuard", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/auth/auth.guard.ts", "deprecated": false, "deprecationMessage": "", "type": "CanActivateFn", "defaultValue": "() => {\n const store = inject(SessionStore);\n const router = inject(Router);\n return store.isAuthenticated() ? true : router.createUrlTree(['/login']);\n}", "rawdescription": "Route guard: only let authenticated users in; otherwise redirect to /login.", "description": "Route guard: only let authenticated users in; otherwise redirect to /login.
\n" } ], "src/app/shared/kernel/fp.ts": [ { "name": "err", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "type": "unknown", "defaultValue": "Below this many NL-hours we ask whether extra scholing was followed.
\n" } ], "src/app/herregistratie/ui/intake-wizard/intake-wizard.component.ts": [ { "name": "JA_NEE", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/herregistratie/ui/intake-wizard/intake-wizard.component.ts", "deprecated": false, "deprecationMessage": "", "type": "[]", "defaultValue": "[{ value: 'ja', label: 'Ja' }, { value: 'nee', label: 'Nee' }]" }, { "name": "STORAGE_KEY", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/herregistratie/ui/intake-wizard/intake-wizard.component.ts", "deprecated": false, "deprecationMessage": "", "type": "string", "defaultValue": "'intake-v1'" } ], "src/app/app.routes.ts": [ { "name": "routes", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/app.routes.ts", "deprecated": false, "deprecationMessage": "", "type": "Routes", "defaultValue": "[\n {\n path: '',\n component: ShellComponent, // persistent header/footer; only children swap\n children: [\n { path: '', pathMatch: 'full', redirectTo: 'login' },\n { path: 'login', loadComponent: () => \"import('@auth/ui/login.page').then(m => m.LoginPage)\" },\n { path: 'dashboard', canActivate: [authGuard], loadComponent: () => \"import('@registratie/ui/dashboard.page').then(m => m.DashboardPage)\" },\n { path: 'registratie', canActivate: [authGuard], loadComponent: () => \"import('@registratie/ui/registration-detail.page').then(m => m.RegistrationDetailPage)\" },\n { path: 'herregistratie', canActivate: [authGuard], loadComponent: () => \"import('@herregistratie/ui/herregistratie.page').then(m => m.HerregistratiePage)\" },\n { path: 'intake', canActivate: [authGuard], loadComponent: () => \"import('@herregistratie/ui/intake.page').then(m => m.IntakePage)\" },\n { path: 'concepts', loadComponent: () => \"import('./showcase/concepts.page').then(m => m.ConceptsPage)\" },\n { path: '**', redirectTo: 'login' },\n ],\n },\n]" } ], "src/app/shared/infrastructure/scenario.interceptor.ts": [ { "name": "scenarioInterceptor", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/infrastructure/scenario.interceptor.ts", "deprecated": false, "deprecationMessage": "", "type": "HttpInterceptorFn", "defaultValue": "(req, next) => {\n if (!req.url.includes('mock/')) return next(req);\n\n switch (currentScenario()) {\n case 'slow':\n return next(req).pipe(delay(2500));\n case 'loading':\n return next(req).pipe(delay(600_000)); // effectively never resolves\n case 'empty':\n return of(new HttpResponse({ status: 200, body: [] })).pipe(delay(400));\n case 'error':\n return timer(400).pipe(\n switchMap(() => throwError(() =>\n new HttpErrorResponse({ status: 500, statusText: 'Demo-fout', url: req.url }))),\n );\n default:\n return next(req);\n }\n}", "rawdescription": "Demo-only: rewrites the timing/outcome of mock data requests based on\n?scenario= so loading / empty / error states can be shown on demand.\nReal requests are untouched.", "description": "Demo-only: rewrites the timing/outcome of mock data requests based on\n?scenario= so loading / empty / error states can be shown on demand.\nReal requests are untouched.
\n" } ], "src/app/shared/infrastructure/scenario.ts": [ { "name": "VALID", "ctype": "miscellaneous", "subtype": "variable", "file": "src/app/shared/infrastructure/scenario.ts", "deprecated": false, "deprecationMessage": "", "type": "Scenario[]", "defaultValue": "['default', 'slow', 'loading', 'empty', 'error']" } ] }, "groupedFunctions": { "src/app/shared/application/remote-data.ts": [ { "name": "andThen", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Chain a second source that depends on the first one's value.
\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataExhaustive fold: you must handle every case, checked at compile time.
\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "h", "deprecated": false, "deprecationMessage": "" } ], "returnType": "R", "jsdoctags": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "h", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "fromResource", "file": "src/app/shared/application/remote-data.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Project Angular's loosely-typed Resource into a RemoteData value.
\n", "args": [ { "name": "r", "type": "Resource", "deprecated": false, "deprecationMessage": "" }, { "name": "isEmpty", "deprecated": false, "deprecationMessage": "", "defaultValue": "() => false" } ], "returnType": "RemoteDataTransform the value inside a Success; pass other states through unchanged.
\n", "args": [ { "name": "rd", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataCombine two sources into one. Use this to merge e.g. a BIG-register call\nand a BRP call into a single state the page can render.
\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataCombine three sources (built on map2).
\n", "args": [ { "name": "a", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "b", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "c", "type": "RemoteData", "deprecated": false, "deprecationMessage": "" }, { "name": "f", "deprecated": false, "deprecationMessage": "" } ], "returnType": "RemoteDataTiny native-TS functional toolkit. No dependency — this is the whole "library".\nReused by every "impossible states" concept in the POC.
\n", "args": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "" } ], "returnType": "never", "jsdoctags": [ { "name": "x", "type": "never", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/herregistratie/domain/herregistratie.machine.ts": [ { "name": "back", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "next", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Step 1 → 2: advance only when BOTH step-1 fields parse. Illegal elsewhere = no-op.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "reduce", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "m", "type": "WizardMsg", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "m", "type": "WizardMsg", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "resolve", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Resolve the async submit. Only meaningful while Submitting.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "setField", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Update one draft field while editing; ignored in any other state.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" }, { "name": "key", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "key", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submit", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Step 2 submit: parse everything; move to Submitting only with Valid data.
\n", "args": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "WizardState", "jsdoctags": [ { "name": "s", "type": "WizardState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "validate", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Parse every field; on success hand back a Valid, else the per-field errors.
\n", "args": [ { "name": "draft", "type": "Draft", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultWhich step the cursor currently points at (clamped to the live step list).
\n", "args": [ { "name": "s", "type": "Extract", "deprecated": false, "deprecationMessage": "" } ], "returnType": "StepId", "jsdoctags": [ { "name": "s", "type": "Extract", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "lageUren", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "boolean", "jsdoctags": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "next", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "reduce", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" }, { "name": "m", "type": "IntakeMsg", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "m", "type": "IntakeMsg", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "resolve", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "r", "type": "Result", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "setAnswer", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" }, { "name": "key", "deprecated": false, "deprecationMessage": "" }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "key", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "value", "type": "string", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "submit", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "" } ], "returnType": "IntakeState", "jsdoctags": [ { "name": "s", "type": "IntakeState", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "validateAll", "file": "src/app/herregistratie/domain/intake.machine.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Parse the whole questionnaire into a ValidIntake (called on submit).
\n", "args": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultValidate ONE step's fields. Returns the per-field error keyed by StepId.
\n", "args": [ { "name": "step", "type": "StepId", "deprecated": false, "deprecationMessage": "" }, { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultTHE branching, as one pure function. The step list is recomputed on every\ntransition, so changing an earlier answer immediately adds/removes later steps.
\n", "args": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "" } ], "returnType": "StepId[]", "jsdoctags": [ { "name": "a", "type": "Answers", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/shared/application/store.ts": [ { "name": "createStore", "file": "src/app/shared/application/store.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "init", "type": "Model", "deprecated": false, "deprecationMessage": "" }, { "name": "update", "deprecated": false, "deprecationMessage": "" } ], "returnType": "StoreReads ?scenario= from the URL so a demo can force each async state.
\n", "args": [], "returnType": "Scenario" } ], "src/app/showcase/concepts.page.ts": [ { "name": "fakeResource", "file": "src/app/showcase/concepts.page.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Minimal fake Resource so
The herregistratie deadline, if the status has one (only the active state does).
\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Date | null", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "isHerregistratieEligible", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "A registration may apply for herregistratie only while active and within the\nwindow before its deadline. A struck-off or suspended registration may not.
\n", "args": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "" }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "" }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12" } ], "returnType": "boolean", "jsdoctags": [ { "name": "reg", "type": "Registration", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "today", "type": "Date", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } }, { "name": "windowMonths", "type": "number", "deprecated": false, "deprecationMessage": "", "defaultValue": "12", "tagName": { "text": "param" } } ] }, { "name": "isStatusConsistent", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Invariant check used in tests/demos: a non-active status must not carry a\nherregistratie date. The union already enforces this structurally; this is\nthe runtime statement of the same rule.
\n", "args": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "" } ], "returnType": "boolean", "jsdoctags": [ { "name": "status", "type": "RegistrationStatus", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusColor", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Brand colour token for a status. assertNever forces a colour for every new\nstatus variant at compile time.
\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] }, { "name": "statusLabel", "file": "src/app/registratie/domain/registration.policy.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "Domain logic for a registration — pure functions, NO Angular. This is where\n"what the business rules say" lives, separate from "how it looks" (UI) and\n"where the data comes from" (infrastructure). Keeping it framework-free means\nit is trivial to read and unit-test.
\n", "args": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "" } ], "returnType": "string", "jsdoctags": [ { "name": "tag", "type": "StatusTag", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/auth/domain/session.ts": [ { "name": "isAuthenticated", "file": "src/app/auth/domain/session.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "s", "deprecated": false, "deprecationMessage": "" } ], "returnType": "Session", "jsdoctags": [ { "name": "s", "deprecated": false, "deprecationMessage": "", "tagName": { "text": "param" } } ] } ], "src/app/registratie/domain/value-objects/big-nummer.ts": [ { "name": "parseBigNummer", "file": "src/app/registratie/domain/value-objects/big-nummer.ts", "ctype": "miscellaneous", "subtype": "function", "deprecated": false, "deprecationMessage": "", "description": "", "args": [ { "name": "raw", "type": "string", "deprecated": false, "deprecationMessage": "" } ], "returnType": "ResultThe mutation/command: send a herregistratie application to the backend.\nReturns a Result so the caller can branch on success/failure without\ntry/catch. ponytail: faked with a timer; swap for a real POST when there's\nan API. The "uren must be > 0" rule lets the demo show a failure path.
\n", "args": [ { "name": "data", "type": "Valid", "deprecated": false, "deprecationMessage": "" } ], "returnType": "PromiseCommand: send the intake questionnaire to the backend. Returns a Result so the\ncaller branches on success/failure without try/catch. ponytail: faked with a\ntimer; swap for a real POST when there's an API. The "uren must be > 0" rule\nlets the demo show the failure path.
\n", "args": [ { "name": "data", "type": "ValidIntake", "deprecated": false, "deprecationMessage": "" } ], "returnType": "PromiseA note is either a recognised specialism or a plain annotation — a closed set,\nnot an open string, so a typo can't slip through.
\n", "kind": 193 }, { "name": "RegistrationStatus", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "Registration status as a discriminated union: each variant owns exactly the\ndata that makes sense for it. Only an active (Geregistreerd) registration has\na herregistratie date; a struck-off (Doorgehaald) one cannot carry one. The\nold flat interface allowed that impossible combination — this makes it\nunrepresentable.
\n", "kind": 193 }, { "name": "StatusTag", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "RegistrationStatus", "file": "src/app/registratie/domain/registration.ts", "deprecated": false, "deprecationMessage": "", "description": "Just the discriminant — for atoms that only need the label/color.
\n", "kind": 200 } ], "src/app/shared/ui/alert/alert.component.ts": [ { "name": "AlertType", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"info\" | \"ok\" | \"warning\" | \"error\"", "file": "src/app/shared/ui/alert/alert.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 } ], "src/app/registratie/domain/value-objects/big-nummer.ts": [ { "name": "BigNummer", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "BrandValue object: a BIG registration number — 11 digits.
\n", "kind": 184 } ], "src/app/shared/kernel/fp.ts": [ { "name": "Brand", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "unknown", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "description": "Nominal typing: Brand<string, 'Postcode'> is assignable from a plain string\nonly through an explicit cast — so a smart constructor is the only minter.
\n", "kind": 194 }, { "name": "Result", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type", "file": "src/app/shared/kernel/fp.ts", "deprecated": false, "deprecationMessage": "", "description": "A computation that either succeeded with a value or failed with an error.\nPlain objects (no classes) to match the signal/httpResource ergonomics.
\n", "kind": 193 } ], "src/app/registratie/application/big-profile.store.ts": [ { "name": "Err", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "Error | undefined", "file": "src/app/registratie/application/big-profile.store.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 } ], "src/app/herregistratie/domain/intake.machine.ts": [ { "name": "IntakeMsg", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type | literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "IntakeState", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 }, { "name": "JaNee", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"ja\" | \"nee\"", "file": "src/app/herregistratie/domain/intake.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "A BRANCHING wizard. Unlike herregistratie.machine (fixed 2 steps), the set of\nsteps here is NOT stored — it's derived from the answers by visibleSteps.\nAnswer "buiten Nederland gewerkt? → ja" and two extra steps appear; report few\nhours and a scholing-question appears. The progress bar's denominator changes\nas you type. "Which question comes next" is a pure function, so it's trivial\nto test and impossible to get out of sync with the data.
Every possible question, as a union — never a bare string.
\n", "kind": 193 } ], "src/app/registratie/domain/value-objects/postcode.ts": [ { "name": "Postcode", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "BrandValue object: a Dutch postcode. "Parse, don't validate" — a Postcode is a\ndistinct type from a raw string, mintable only via parsePostcode, so holding\none is proof it is well-formed.
\n", "kind": 184 } ], "src/app/shared/application/remote-data.ts": [ { "name": "RemoteData", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type", "file": "src/app/shared/application/remote-data.ts", "deprecated": false, "deprecationMessage": "", "description": "The four mutually-exclusive states of an async fetch, as a tagged union.\nCrucially the data lives ON the state: only Failure has an error, only\nSuccess has a value. "Loaded but no value" or "error with stale value"\nare unrepresentable — Richard Feldman's RemoteData.
Value object: a non-negative whole number of hours.
\n", "kind": 184 } ], "src/app/shared/ui/button/button.component.ts": [ { "name": "Variant", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "\"primary\" | \"secondary\" | \"subtle\" | \"danger\"", "file": "src/app/shared/ui/button/button.component.ts", "deprecated": false, "deprecationMessage": "", "description": "", "kind": 193 } ], "src/app/herregistratie/domain/herregistratie.machine.ts": [ { "name": "WizardMsg", "ctype": "miscellaneous", "subtype": "typealias", "rawtype": "literal type | literal type | literal type | literal type | literal type | literal type | literal type | literal type", "file": "src/app/herregistratie/domain/herregistratie.machine.ts", "deprecated": false, "deprecationMessage": "", "description": "Every event that can happen to the wizard, as one message type. The component\nsends a WizardMsg; reduce decides the next state. This is the Elm\nModel+Msg+update pattern: ONE pure function describes all state changes.
The whole wizard as one tagged union. step and errors exist ONLY while\nEditing; Submitting/Submitted/Failed carry a Valid payload and nothing else.\nSo "submitting while a field is invalid" or "showing the success screen with\nerrors set" are unrepresentable — the bug class is gone by construction.