import { assertNever } from '@shared/kernel/fp'; import { Registration, RegistrationStatus, StatusTag } from './registration'; /** * Domain logic for a registration — pure functions, NO Angular. This is where * "what the business rules say" lives, separate from "how it looks" (UI) and * "where the data comes from" (infrastructure). Keeping it framework-free means * it is trivial to read and unit-test. */ /** Human-readable label for a status. */ export function statusLabel(tag: StatusTag): string { return tag; // the tag already reads as Dutch; kept as a function so labels can diverge later } /** Brand colour token for a status. assertNever forces a colour for every new status variant at compile time. */ export function statusColor(tag: StatusTag): string { switch (tag) { case 'Geregistreerd': return 'var(--rhc-color-groen-500)'; case 'Doorgehaald': return 'var(--rhc-color-rood-500)'; case 'Geschorst': return 'var(--rhc-color-oranje-500)'; default: return assertNever(tag); } } /** The herregistratie deadline, if the status has one (only the active state does). */ export function herregistratieDeadline(reg: Registration): Date | null { return reg.status.tag === 'Geregistreerd' ? new Date(reg.status.herregistratieDatum) : null; } /** A registration may apply for herregistratie only while active and within the window before its deadline. A struck-off or suspended registration may not. SERVER-OWNED RULE: this now runs on the backend (BFF), which ships the result as `decisions.eligibleForHerregistratie` in the dashboard view. Kept here as the reference implementation + unit test; the frontend no longer calls it. */ export function isHerregistratieEligible( reg: Registration, today: Date, windowMonths = 12, ): boolean { const deadline = herregistratieDeadline(reg); if (!deadline) return false; const windowStart = new Date(deadline); windowStart.setMonth(windowStart.getMonth() - windowMonths); return today >= windowStart; } /** Invariant check used in tests/demos: a non-active status must not carry a herregistratie date. The union already enforces this structurally; this is the runtime statement of the same rule. */ export function isStatusConsistent(status: RegistrationStatus): boolean { return status.tag === 'Geregistreerd' ? typeof status.herregistratieDatum === 'string' : true; }