Add registratie wizard, BFF dashboard-view, contracts/value-objects, and architecture docs

Checkpoint of in-progress work: the registration wizard (address prefill,
DUO diploma lookup, policy questions), decision-DTO contracts, parse-don't-
validate value objects, infrastructure adapters, plus CLAUDE.md and the
architecture/ADR docs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 17:23:52 +02:00
parent 8a8a2f0f29
commit 64385999eb
58 changed files with 7271 additions and 556 deletions

View File

@@ -1,11 +1,34 @@
import { Injectable } from '@angular/core';
import { httpResource } from '@angular/common/http';
import { Person } from '../domain/person';
import { Result, ok, err } from '@shared/kernel/fp';
import { BrpAddressDto } from '@registratie/contracts/brp-address.dto';
/** Infrastructure adapter for the BRP (Basisregistratie Personen) source. */
/**
* Infrastructure adapter for the BRP address lookup, reached only through our own
* ("BFF-lite") endpoint — the anti-corruption boundary. In this POC the endpoint
* is a static mock; pointing at a real backend touches only this file + the DTO.
*/
@Injectable({ providedIn: 'root' })
export class BrpAdapter {
personResource() {
return httpResource<Person>(() => 'mock/brp.json');
// Typed as the DTO for ergonomics, but the value is untrusted JSON until
// parseBrpAddress validates it.
adresResource() {
return httpResource<BrpAddressDto>(() => 'mock/brp-address.json');
}
}
/** Trust-boundary parse: validate the untrusted response shape. "Geen adres" is a
valid outcome (gevonden: false), not a malformed response. ponytail: hand-written;
reach for a schema lib once the contract count grows. */
export function parseBrpAddress(json: unknown): Result<string, BrpAddressDto> {
if (typeof json !== 'object' || json === null) return err('brp-address: not an object');
const dto = json as Partial<BrpAddressDto>;
if (typeof dto.gevonden !== 'boolean') return err('brp-address: missing/invalid gevonden');
if (dto.gevonden) {
const a = dto.adres;
if (!a || typeof a.straat !== 'string' || typeof a.postcode !== 'string' || typeof a.woonplaats !== 'string') {
return err('brp-address: missing/invalid adres');
}
}
return ok({ gevonden: dto.gevonden, adres: dto.adres });
}