feat(showcase): PII section — mask + elfproef parse (WP-42, mask/parse half)
CI / storybook-a11y (push) Successful in 5m3s
CI / frontend (push) Successful in 1m53s
CI / backend (push) Successful in 1m26s
CI / e2e (push) Successful in 2m46s
CI / semgrep (push) Successful in 59s
CI / api-client-drift (push) Successful in 2m7s

Add a "PII — maskeren & parsen" section to /concepts demonstrating the WP-40 pieces
with FP + atomic design, framed for AVG art. 9 / data-minimisation: a live
<app-masked-value> atom (masked BSN that reveals on click; real reveal is step-up +
audited in behandel-scherm) and a live parseBsn elfproef parse. Both show the real
linked source via the WP-39 snippet mechanism (new showcase regions in bsn.ts + pii.ts,
registered in gen-snippets.mjs). Delivers WP-42's showcase demo; the persisted-audit
half stays pending WP-41.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
eho
2026-07-23 15:43:53 +02:00
co-authored by Claude Opus 4.8
parent 62cb34b60f
commit 8c54ede6eb
7 changed files with 144 additions and 50 deletions
+3 -1
View File
@@ -11,6 +11,7 @@ export type Bsn = Brand<string, 'Bsn'>;
// Positional weights for the elfproef: 9·d1 + 8·d2 + … + 2·d8 1·d9 ≡ 0 (mod 11).
const WEIGHTS = [9, 8, 7, 6, 5, 4, 3, 2, -1];
// #region showcase:parseBsn
export function parseBsn(raw: string): Result<string, Bsn> {
const t = raw.trim();
if (!/^\d{9}$/.test(t)) {
@@ -22,5 +23,6 @@ export function parseBsn(raw: string): Result<string, Bsn> {
$localize`:@@validation.bsnElfproef:Dit is geen geldig BSN (klopt niet met de elfproef).`,
);
}
return ok(t as Bsn);
return ok(t as Bsn); // holding a Bsn is proof it passed the elfproef
}
// #endregion showcase:parseBsn
+2
View File
@@ -5,6 +5,7 @@
*/
export const REDACTED = 'redacted';
// #region showcase:mask
/** Keep the last `keep` characters, mask the rest with `*`. */
export function maskTail(value: string, keep: number): string {
if (value.length <= keep) return '*'.repeat(value.length);
@@ -15,3 +16,4 @@ export function maskTail(value: string, keep: number): string {
export function maskBsn(value: string): string {
return maskTail(value, 3);
}
// #endregion showcase:mask