feat(showcase): PII section — mask + elfproef parse (WP-42, mask/parse half)
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user