BrpAddressDto's fields are generated as optional, so returning it directly from parseBrpAddress lost the narrowing the runtime check already did. This broke the build once registratie-lookup.store.ts assigned the parsed address into a stricter local type. Map to a proper BrpAddress domain shape at the trust boundary instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
63 lines
2.7 KiB
TypeScript
63 lines
2.7 KiB
TypeScript
import { Injectable, computed, inject } from '@angular/core';
|
|
import { RemoteData, fromResource } from '@shared/application/remote-data';
|
|
import { DuoLookupDto } from '../contracts/duo-diplomas.dto';
|
|
import { BrpAdapter, parseBrpAddress } from '../infrastructure/brp.adapter';
|
|
import { DuoAdapter, parseDuoLookup } from '../infrastructure/duo.adapter';
|
|
|
|
type Err = Error | undefined;
|
|
|
|
/**
|
|
* Application-layer facade for the registratie wizard's two lookups (BRP address,
|
|
* DUO diplomas). It owns the httpResources (created here, in the required injection
|
|
* context), runs the trust-boundary parse, and exposes RemoteData / derived signals
|
|
* — so the UI reaches the network through application/, never infrastructure/
|
|
* directly (CLAUDE.md §1: ui → application → domain). Same facade shape as
|
|
* BigProfileStore.
|
|
*/
|
|
@Injectable({ providedIn: 'root' })
|
|
export class RegistratieLookupStore {
|
|
private brp = inject(BrpAdapter);
|
|
private duo = inject(DuoAdapter);
|
|
|
|
private adresRes = this.brp.adresResource();
|
|
private diplomasRes = this.duo.diplomasResource();
|
|
|
|
/** BRP lookup outcome. A failure or "geen adres" never blocks the wizard — both
|
|
fall back to manual entry (PRD §7). 'geen' covers both no-address-found and a
|
|
malformed response; 'fout' is an unreachable BRP. */
|
|
readonly adresStatus = computed<'laden' | 'gevonden' | 'geen' | 'fout'>(() => {
|
|
const st = this.adresRes.status();
|
|
if (st === 'loading' || st === 'reloading') return 'laden';
|
|
if (st === 'error') return 'fout';
|
|
const json = this.adresRes.value();
|
|
const parsed = json !== undefined ? parseBrpAddress(json) : null;
|
|
return parsed && parsed.ok && parsed.value.gevonden ? 'gevonden' : 'geen';
|
|
});
|
|
|
|
/** The address to prefill the draft with, once BRP resolves with a found address;
|
|
null otherwise (loading, error, no address, malformed). */
|
|
readonly prefillAdres = computed<{ straat: string; postcode: string; woonplaats: string } | null>(
|
|
() => {
|
|
const json = this.adresRes.value();
|
|
if (json === undefined) return null;
|
|
const parsed = parseBrpAddress(json);
|
|
return parsed.ok && parsed.value.adres ? parsed.value.adres : null;
|
|
},
|
|
);
|
|
|
|
/** The DUO lookup (diplomas + manual fallback), validated at the trust boundary. */
|
|
readonly duoLookup = computed<RemoteData<Err, DuoLookupDto>>(() => {
|
|
const rd = fromResource(this.diplomasRes);
|
|
if (rd.tag !== 'Success') return rd;
|
|
const parsed = parseDuoLookup(rd.value);
|
|
return parsed.ok
|
|
? { tag: 'Success', value: parsed.value }
|
|
: { tag: 'Failure', error: new Error(parsed.error) };
|
|
});
|
|
|
|
/** Reload the BRP lookup (e.g. when the wizard restarts) so the address re-prefills. */
|
|
reloadAdres() {
|
|
this.adresRes.reload();
|
|
}
|
|
}
|