Each status variant now owns its own data: only Geregistreerd carries a
herregistratieDatum; Geschorst/Doorgehaald carry their own dates + reason.
A struck-off registration can no longer hold a future herregistratie date —
that impossible combination is gone from the type.
- status-badge keys color off the tag via a switch + assertNever
- registration-summary renders only the rows a variant's data supports
- registration.json nests the status; stories cover all three variants
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduce RemoteData<E,T> (Loading | Empty | Failure | Success) plus
fromResource and an exhaustive foldRemote. The data lives ON the state,
so "loaded without value" or "error with stale value" are unrepresentable.
AsyncComponent now derives a single rd() and pulls value/error out via the
fold instead of a loose State string. Public API (resource/isEmpty inputs,
the four slot directives, the ASYNC array) is unchanged, so the dashboard,
detail page, and async stories need no edits.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The shared foundation for the "make impossible states impossible" work:
- assertNever for compile-time exhaustiveness in union switches
- Result<E,T> + ok/err constructors (plain objects, no classes)
- Brand<T,B> for nominal types
No runtime dependency — this is the whole "library".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>