refactor(auth): land Session -> Principal, add MedewerkerAdapter (RB-13)
ADR-0002 SS3 models Zorgverlener/Medewerker as different Principal variants with different login flows. Actor #2 (apps/behandelportal) landed in WP-61/67 and the union never followed: grep -rn "Principal" returned one hit, a comment. Both apps' auth/domain/session.ts stayed byte-identical (`{ bsn, naam }`), so the backoffice's Behandelaar carried a BSN and logged into the backoffice as a citizen, by DigiD, under a fabricated citizen's name (login.page.ts). The divergence ADR-0002 predicted took an orthogonal side door instead (medewerker.interceptor.ts's X-Medewerker/X-Rollen stamp, which never touches SessionStore) -- which is why ssp/auth and bhp/auth still measured as 100%/84% duplicated after ADR-C-006 shared the route guards. RB-09 (landed the day before) made the backend's IIdentityProvider able to say "no identity" and fail closed; this ticket is its named FE half. Each app's auth/domain/session.ts becomes principal.ts, holding the one Principal variant that app actually has an actor for: ssp keeps `{ kind: 'zorgverlener', bsn, naam }` (G1 still strips the BSN before persisting); behandelportal gets `{ kind: 'medewerker', medewerkerId, naam, rollen }` (no BSN to strip -- G2 shape validation only). A new MedewerkerAdapter replaces DigidAdapter in behandelportal, resolving the existing MEDEWERKER_ID/currentRollen() dev stand-in into a Principal; because there is no credential to check, it returns Principal directly rather than a Result whose error variant could never occur. login.page.ts stops being a BSN/wachtwoord form -- one explainer line and an "Inloggen met SSO" button -- and its dead error-handling branch goes with the Result wrapper that justified it. Measured with tools/baseline-scan.mjs --dup: auth duplication drops from 168/168 (ssp) and 168/200 (bhp) to 32/179 and 32/259 -- under the backlog's <40 target. What remains is the ADR-C-006 route-guard re-export (deliberately identical), generic test/story-file boilerplate, and one shared fragment of the root-singleton-store idiom -- not re-converged identity or login-flow logic. SS3's prediction that the two actors would authenticate differently enough to justify not sharing auth has now actually been tested, not just asserted, and held. Also: renamed Session.bsn to Principal.bsn in two doc comments (libs/shared/src/infrastructure/subject.ts, subject.interceptor.ts) that cited the old type name; regenerated libs/shared/docs/behaviour-spec.mdx (generated file, per its own banner); recorded the resolution in ADR-0002 as a new amendment, replacing its "Known debt" section. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,7 +12,7 @@ import { currentSubject } from './subject';
|
||||
* middleware resolves a `CallerIdentity` for every request, not just some endpoints.
|
||||
*
|
||||
* **BSN source — a deliberate compromise, read before changing:** the "obvious"
|
||||
* source would be the authenticated `Session.bsn` held by each app's own
|
||||
* source would be the authenticated `Principal.bsn` held by each app's own
|
||||
* `SessionStore`, but `libs/shared` may not depend on an app-local `auth` context
|
||||
* (the import-direction rule), and the one sanctioned cross-context seam —
|
||||
* `SessionPort` (`@shared/application/session.port`) — deliberately exposes only
|
||||
|
||||
@@ -3,7 +3,7 @@ import { isDevMode } from '@angular/core';
|
||||
/**
|
||||
* Dev-only role stand-in's sibling (the reading MECHANISM for `X-Subject`; see
|
||||
* `role.ts`'s own doc comment for the twin `X-Role` mechanism this mirrors). This
|
||||
* POC has no real DigiD identity — `Session.bsn` lives only in each app's own
|
||||
* POC has no real DigiD identity — `Principal.bsn` lives only in each app's own
|
||||
* in-memory `SessionStore` and is deliberately never persisted (see that store's G1
|
||||
* comment) — so `subject.interceptor.ts` can't reach it without a layering
|
||||
* violation (`libs/shared` may not depend on an app-local `auth` context). Instead a
|
||||
|
||||
Reference in New Issue
Block a user