Restructures into apps/ssp + apps/behandelportal (two Angular projects)
plus libs/shared + libs/beheer (cross-app libraries), replacing WP-61's
separate sibling repo. That split had already produced real drift: a
hand-vendored copy of the backend's OpenAPI doc, a shared/ui+layout tree
forked and silently diverging (7 files), and beheer + the styles.scss
token bridge duplicated byte-for-byte across both repos.
- git mv the SSP's src/app/* into apps/ssp/; fold shared/, beheer/,
environments/, the Storybook docs/*.mdx, and styles.scss into
libs/shared + libs/beheer (all confirmed identical between the two
repos before merging). auth stays deliberately duplicated per
ADR-0002 (actor-specific, expected to diverge) - amended there.
- One generated API client (libs/shared), no more vendored swagger.json.
- .dependency-cruiser split into a base factory + one config per app,
and Storybook into .storybook-ssp/.storybook-behandelportal - both
forced by the @auth/* alias resolving to different directories per app.
- SiteHeaderComponent/ShellComponent gained HEADER_NAV_ITEMS/
HEADER_ADMIN_LINKS/DEBUG_PANEL injection tokens so each app supplies
its own nav/admin-links/dev-panel instead of one being hardcoded.
- CLAUDE.md, ARCHITECTURE.md, dependencies.md, and ADR-0002 updated;
WP-67 backlog entry documents the full decision trail.
npm run ci green (lint, dep:check x2, 360 tests across ssp/
behandelportal/shared/beheer, both localized builds, backend tests,
snippet + api-client drift); both dev servers, both Storybook
instances, and docker compose verified working.
The old sibling repo (/home/eho/repos/behandelportal) is left
untouched, not deleted.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every `npm run storybook` start ran a full Compodoc TypeScript-program
analysis over the whole app (not just the 62 stories), regenerating a
9MB documentation.json and spiking memory/CPU enough to crash the
machine. build-storybook (what CI/docs actually ship) keeps compodoc;
the interactive dev loop just serves the last-committed
documentation.json.
Serve the source locale (nl) at / instead of /nl/: angular.json sourceLocale is now
{ code: 'nl', subPath: '' } → nl output at browser/ root (base href /), en stays /en/.
Rework localeLinks (nl → bare path, en → /en/…) + spec, and serve-i18n.mjs (nl assets at
root, en under /en/, / serves the nl index). And build the docker demo (+ serve:i18n) with
`--configuration development --localize` so isDevMode() stays true and the dev `⚙ state`
panel + role/scenario switchers render in the localized compose demo (they were correctly
gated off in the previous production build). Verified: nl base href /, en /en/, ngDevMode present.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Enable coverage via the @angular/build:unit-test builder's first-class options: a
`coverage` configuration on the test target (v8 provider, text-summary/html/lcov,
excludes for specs/stories/contracts/generated client) + `npm run test:coverage`.
Report-only (no thresholds) — visibility first. CI's test step now runs test:coverage
(strict superset: fails on a failing test, never on coverage). Baseline ~71% stmts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
angular.json gains an i18n block (sourceLocale nl, en translation file) and
an `en` build/serve configuration with i18nMissingTranslation: "error" so a
new $localize string without an English unit fails the build, not silently
falls back. CI now runs `ng build --localize` to build both locales every
run. Verified end-to-end, not just "the build succeeded": the nl bundle
ships "Inloggen met DigiD", the en bundle ships "Log in with DigiD".
Incidental: prettier/compodoc regen noise in docs/wcag-checklist.md,
src/docs/a11y.mdx, documentation.json from the same working session.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Domain reference data already lives in the backend (per ADR-0001); the only
residual "move" was ~90 inlined Dutch UI strings with no i18n layer.
- Wire @angular/localize ($localize) — Angular first-party, no third-party lib
- Pin the pattern on shared/ui/async: Dutch fallbacks → language-agnostic
input()s with localizable $localize defaults (English-shared-UI rule)
- CLAUDE.md: drop i18n (now in scope) + stale "real backend"/"OpenAPI codegen"
(both already shipped); document the $localize convention
Bulk string sweep deferred to Step 2 to avoid touching ~36 files twice.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Fix full-bleed header/footer (align-items:stretch + block hosts; centered
content column via shared --app-content-max).
- New templates/page-shell (back-link + heading + intro + content, narrow mode);
all pages refactored to compose it.
- Async state management with native httpResource + <app-async> wrapper that
renders exactly one of loading/empty/error/loaded (impossible states
unrepresentable); delayed spinner + skeleton atoms for slow/fast connections.
- Scenario interceptor (?scenario=slow|loading|empty|error) to demo every state.
- Storybook: spinner/skeleton/page-shell/async-states stories.
- README rewritten as a guide (atomic design, reuse benefits, state handling).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Atoms/molecules/organisms/templates/pages composing the NL Design System
(Utrecht) CSS themed Rijkshuisstijl via @rijkshuisstijl-community tokens.
Login -> dashboard -> registration detail, mock JSON over HttpClient, Storybook
organized by atomic layer.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>