Files
atomic-design-poc/docs/project/backlog/WP-40-pii-kernel.md
T
ehoandClaude Opus 4.8 a828e604d1 docs(backlog): add Phase 8 — platform/DX/showcase (WP-37..46)
New phase from the 5-item analysis: linked showcase snippets + animations,
runnable scaffolding generators (pages/wizards/context/SSP), dependency graph +
declarative boundaries, PII hardening (branded Bsn VO + masked-value atom +
persisted no-PII audit) doubling as a privacy showcase, and Vitest coverage.
Goal: both a teaching showcase and a production starter template. Sequenced with
priorities + dependencies in the README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 13:34:01 +02:00

1.6 KiB

WP-40 — PII kernel: branded Bsn VO + masked-value atom

Status: todo Phase: 8 — platform/DX/showcase Priority: P2

Why

Masking is real but ad-hoc: pure helpers live in debug-state/mask.ts, the BSN is a bare string in session.ts (no branded VO / checksum, unlike BigNummer/Postcode), and masked state is detected by .includes('*') sniffing — no reusable atomic-design component. For a register this is AVG art. 9 (BSN = special category) territory; the pieces should be first-class and reusable.

Decisions

  • Bsn branded value object + parseBsn with the elfproef (9 digits, weighted mod-11) checksum — parity with the other value objects. Replace the bare string in session.ts.
  • Consolidate the pure maskers into shared/kernel/pii.ts (functional core): maskBsn, maskTail, redactProfile, … Keep the backend MaskTail twin in sync.
  • <app-masked-value> atom (shared/ui) — masked by default, optional reveal affordance + a11y; replaces .includes('*') sniffing and composes into the behandel-scherm reveal.

Files

  • New src/app/shared/kernel/bsn.ts (+spec, elfproef cases) and shared/kernel/pii.ts (+spec).
  • src/app/auth/domain/session.tsbsn: Bsn.
  • New src/app/shared/ui/masked-value/ atom (+ story).
  • src/app/shared/ui/debug-state/mask.ts — re-export/move to the kernel module.

Acceptance criteria

  • parseBsn accepts valid elfproef numbers, rejects bad checksum/length (spec).
  • <app-masked-value> renders masked by default with an accessible reveal; behandel-scherm uses it.
  • Pure maskers have specs (no TestBed); backend MaskTail parity noted; npm run ci green.