--- name: new-ssp description: Bootstrap a new self-service portal from this repo as a template — what to keep, strip, rename, and re-seed. Use when starting a new SSP for a different domain/register. --- # New SSP from this template The template's value is the **enforced architecture** (layer fences, token gate, a11y gate, API-drift gate) and the shared building blocks — not the BIG-register business content. Keep the machinery, replace the domain. ## Run the script Clone this repo, `npm ci`, then mechanise the mechanical parts (WP-45): ```bash node scripts/create-frontend.mjs --name Kvk --context inschrijving ``` `--name` (PascalCase) replaces `BigRegister.*` everywhere; `--context` (lowercase Dutch ubiquitous term) is passed straight to `gen:context` (`plop context`, WP-44) to seed the new portal's first real context. Add `--dry-run` to preview file operations first, `--keep ` to leave one business context in place temporarily as a worked example, and `--skip-backend` if no .NET SDK is available yet (skips `gen:api`). It strips the four business contexts and their wiring, renames the backend, re-runs `gen:api`, and seeds the first context — then **prints a checklist** for what it deliberately doesn't script: backend business rules and real branding can't be generated from nothing. Work through that checklist, keeping the GREEN gate below passing at every step. ## Keep as-is - `src/app/shared/` — kernel (`fp.ts`), application (`remote-data`, `store`, `submit`), ui atoms/molecules, layout templates, upload subtree — **except** `shared/ui/debug-state/`, which the script deletes (see below). - Tooling: `eslint.config.mjs`, `.dependency-cruiser.js` (edited by the script, not hand-stripped — see below), `scripts/check-tokens.sh`, `.github/workflows/ci.yml`, `nswag.json`, `.storybook/`, `proxy.conf.json`, `.npmrc` (`legacy-peer-deps` — and never `npm audit fix --force`, it downgrades Angular). - `src/app/auth/` (fake auth shell) and `src/app/shared/infrastructure/scenario.interceptor.ts` (dev-only). - `docs/reference/architecture/` ADRs 0001–0003 — the decisions still apply; amend, don't delete. - `CLAUDE.md`, `docs/reference/architecture/ARCHITECTURE.md`, `docs/reference/fp-tea-atomic-design.md` — update names/examples as contexts change. - `.claude/skills/` — these recipes are the point of the template. - `src/app/beheer/` — its frontend is genuinely generic (data-driven off a `StamdataTable`/ `AuditEntry` shape, nothing BIG-specific). Its _backend_ Stamdata catalog is not — see below. ## Strip / replace — what the script does - Business contexts `registratie/`, `herregistratie/`, `brief/`, `showcase/`: deleted (or one kept temporarily via `--keep` as the worked example while building the first real context — **new-context** + **new-feature** skills; if kept, update the worked-example paths in those skills to the new flagship context once you drop it for real). - `app.routes.ts` route blocks and `tsconfig.json` aliases for removed contexts, and their `CONTEXT_ALLOWED` entry in **`.dependency-cruiser.js`** — boundary rules moved there in WP-38 and are no longer in `eslint.config.mjs` (which only keeps `no-explicit-any` + a11y template rules). Route stripping matches on the _import alias_ a route uses, not its own path segment — `beheer/zaken` imports `@registratie/ui/admin-cases.page` and gets dropped along with `registratie` even though its own path doesn't say so. - `src/app/shared/ui/debug-state/` (the dev `⚙ state` panel): imports `@registratie/application/big-profile.store` directly and is the one path `.dependency-cruiser.js`'s `shared-no-features` rule exempts — there's no generic way to re-target it at an arbitrary new context, so it's deleted alongside `registratie`, along with its three wiring lines in `shell.component.ts` (import, `imports:` entry, template tag). - The `dashboard` route is **not** deleted even though it currently imports `@registratie/ui/dashboard.page` — too much else hardcodes `/dashboard` (login's post-auth redirect, `authGuard`'s fallback, header nav/logo, breadcrumb trail, several stories/specs). The script rewrites its `loadComponent` to point at the freshly scaffolded `--context` page instead (a `TODO(create-frontend)` stopgap landing page, not a real overview). - `scripts/gen-snippets.mjs` (showcase-only) + its `package.json` script entry + its CI/ `ci-local.sh` "showcase snippets drift" steps: deleted alongside `showcase/` — they run unconditionally, so leaving them breaks `npm run ci` immediately once `showcase/` is gone. - Backend: keep the skeleton (`Program.cs` minimal-API style, ProblemDetails 422, `X-Correlation-Id` audit line, `/api/v1` versioning, `Contracts/`/`Domain/`/`Data/` split, test project, and the generic `Stamdata/StamdataFile.cs`+`StamdataTable.cs` reflection-driven `/stamdata` endpoint machinery, ADR-0004) — replace `Data/SeedData.cs`, `Domain/*` rules, `Contracts/*` DTOs, and the three concrete Stamdata catalog entries (`Beroep`/`Opleiding`/`Specialisme`/`ProfessionMapping` + their JSON) with the new register's. The script renames the solution/projects from `BigRegister.*` (and updates `package.json`'s `gen:api`, `ci.yml`'s paths, `docker-compose.yml`) — it does not rewrite business content; that's the printed checklist. - Regenerate the seam: `npm run gen:api` (commits `backend/swagger.json` + `src/app/shared/infrastructure/api-client.ts`) — only reflects a new shape once the backend content above is actually rewritten. - Branding: the script swaps `src/index.html`'s stylesheet `` + `` to a placeholder path and creates an empty `public/<name>-huisstijl/` — it cannot generate a real house style. Vendor your CSS there, then re-point the `--rhc-*` bridge in `src/styles.scss` (ADR-0003 pattern: bridge, don't rewrite tokens), then `npm run check:tokens`. - `docs/project/backlog/` WPs, PRDs, and memory-specific docs — new portal, new backlog (keep `docs/project/backlog/README.md`'s WP process/template if you like the workflow). `docs/reference/scaffolding.md` also names `BigRegister.Api` in prose — update by hand. - `e2e/*.spec.ts` (`smoke.spec.ts`, `brief-v2.spec.ts`, `error-state.spec.ts`): full BIG-register user-flow tests (BSN login → registration wizard → submission assertions). Not touched by the script (they don't block `npm run ci` — the `e2e` job runs separately) but are 100% stale business content; rewrite once you have real flows to test. ## Verify — the GREEN gate must pass at every step ```bash npm run lint && npm run check:tokens && npm test && npm run build npm run build-storybook && npm run test-storybook:ci cd backend && dotnet test && cd .. npm run gen:api && git diff --exit-code backend/swagger.json src/app/shared/infrastructure/api-client.ts ``` Or just `npm run ci` for the non-storybook subset. Strip incrementally and keep this green — the fences are only worth having if they never go red.