diff --git a/.claude/skills/new-ssp/SKILL.md b/.claude/skills/new-ssp/SKILL.md index 6924fc9..1adac8d 100644 --- a/.claude/skills/new-ssp/SKILL.md +++ b/.claude/skills/new-ssp/SKILL.md @@ -62,7 +62,7 @@ Work through that checklist, keeping the GREEN gate below passing at every step. 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 + `@overzicht/ui/overzicht.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). diff --git a/apps/ssp/src/app/overzicht/ui/overzicht.page.ts b/apps/ssp/src/app/overzicht/ui/overzicht.page.ts index ad66f00..567136a 100644 --- a/apps/ssp/src/app/overzicht/ui/overzicht.page.ts +++ b/apps/ssp/src/app/overzicht/ui/overzicht.page.ts @@ -1,15 +1,15 @@ import { Component } from '@angular/core'; import { PageShellComponent } from '@shared/layout/page-shell/page-shell.component'; -import { MijnAanvragenSection } from '@registratie/ui/dashboard/mijn-aanvragen.section'; -import { WatMoetIkRegelenSection } from '@registratie/ui/dashboard/wat-moet-ik-regelen.section'; -import { MijnRegistratieSection } from '@registratie/ui/dashboard/mijn-registratie.section'; -import { SpecialismenSection } from '@registratie/ui/dashboard/specialismen.section'; +import { MijnAanvragenSection } from '@registratie/ui/overzicht-secties/mijn-aanvragen.section'; +import { WatMoetIkRegelenSection } from '@registratie/ui/overzicht-secties/wat-moet-ik-regelen.section'; +import { MijnRegistratieSection } from '@registratie/ui/overzicht-secties/mijn-registratie.section'; +import { SpecialismenSection } from '@registratie/ui/overzicht-secties/specialismen.section'; import { WatWiltUDoenSection } from './wat-wilt-u-doen.section'; import { BeheerLinksSection } from './beheer-links.section'; /** Page: "Mijn overzicht" — the portal home, following the NL Design System "Mijn omgeving" pattern. Composition only: each section below answers its own data - question (own store, own async state) — four sections stay in `registratie/ui/dashboard/` + question (own store, own async state) — four sections stay in `registratie/ui/overzicht-secties/` (they render registratie data), two live here (cross-context navigation). */ @Component({ selector: 'app-overzicht-page', diff --git a/apps/ssp/src/app/registratie/ui/dashboard/mijn-aanvragen.section.stories.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-aanvragen.section.stories.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/mijn-aanvragen.section.stories.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-aanvragen.section.stories.ts diff --git a/apps/ssp/src/app/registratie/ui/dashboard/mijn-aanvragen.section.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-aanvragen.section.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/mijn-aanvragen.section.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-aanvragen.section.ts diff --git a/apps/ssp/src/app/registratie/ui/dashboard/mijn-registratie.section.stories.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-registratie.section.stories.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/mijn-registratie.section.stories.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-registratie.section.stories.ts diff --git a/apps/ssp/src/app/registratie/ui/dashboard/mijn-registratie.section.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-registratie.section.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/mijn-registratie.section.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-registratie.section.ts diff --git a/apps/ssp/src/app/registratie/ui/dashboard/specialismen.section.stories.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/specialismen.section.stories.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/specialismen.section.stories.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/specialismen.section.stories.ts diff --git a/apps/ssp/src/app/registratie/ui/dashboard/specialismen.section.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/specialismen.section.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/specialismen.section.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/specialismen.section.ts diff --git a/apps/ssp/src/app/registratie/ui/dashboard/wat-moet-ik-regelen.section.stories.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/wat-moet-ik-regelen.section.stories.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/wat-moet-ik-regelen.section.stories.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/wat-moet-ik-regelen.section.stories.ts diff --git a/apps/ssp/src/app/registratie/ui/dashboard/wat-moet-ik-regelen.section.ts b/apps/ssp/src/app/registratie/ui/overzicht-secties/wat-moet-ik-regelen.section.ts similarity index 100% rename from apps/ssp/src/app/registratie/ui/dashboard/wat-moet-ik-regelen.section.ts rename to apps/ssp/src/app/registratie/ui/overzicht-secties/wat-moet-ik-regelen.section.ts diff --git a/docs/project/readable-codebase/RD-36-overzicht-secties.md b/docs/project/readable-codebase/RD-36-overzicht-secties.md new file mode 100644 index 0000000..759ac58 --- /dev/null +++ b/docs/project/readable-codebase/RD-36-overzicht-secties.md @@ -0,0 +1,114 @@ +# RD-36 — `ui/dashboard/` becomes `ui/overzicht-secties/` + +Status: done +Phase: 5 — fix the docs that describe this flow + +## Why + +RD-03 moved the dashboard page to `overzicht/ui/overzicht.page.ts` and left four data sections +in `registratie/ui/dashboard/`. The folder is now named after a page that lives somewhere else. +A reader who opens `registratie/ui/dashboard/` finds four sections that are not the dashboard, +and the page it is named for is in another context. + +RD-04 recorded the name as stale and left it. This ticket fixes it. + +## Read first + +- `docs/project/readable-codebase/PLAN.md:267-282` — the decision and its measured cost. +- `apps/ssp/src/app/overzicht/ui/overzicht.page.ts` — the only importer. + +## Decisions (pre-made, do not relitigate) + +1. **The new name is `overzicht-secties/`.** It says what the four files are: registratie's + sections for the overzicht page. It keeps the Dutch that CLAUDE.md requires of a domain + context. +2. **Flattening into `registratie/ui/` is rejected.** That directory holds one folder per + component. Eight loose files would break its shape. +3. **The alias does not change.** The four sections stay in the `registratie` context, so the + imports stay `@registratie/ui/…`. Only the folder segment changes. +4. **Story titles do not change.** They are `Domein/Registratie/`, which is a context + name, not a folder name. Both Storybook globs are recursive, so no config changes. +5. **Fold in the two stale `dashboard.page` paths named in PLAN.** `docs/reference/feature-flags.md:55` + and `.claude/skills/new-ssp/SKILL.md:65` both cite `registratie/ui/dashboard.page`, a file + that no longer exists. The flag logic they describe lives in + `apps/ssp/src/app/overzicht/ui/wat-wilt-u-doen.section.ts` now. +6. **Fix the other live citations of the deleted file too.** Same defect, same commit: + `docs/reference/architecture/ARCHITECTURE.md:55` (the pages node in the Mermaid diagram) and + `:79` (the `ui/` row of the layer table), and `libs/shared/docs/remote-data.mdx:64`. Each + names `dashboard.page.ts` as a live example. The current name is `overzicht.page.ts`. +7. **Leave `docs/project/archive/` and the shipped RD ticket records alone.** They describe the + tree as it was when they ran. A historical record that cites a path from its own time is + correct, not stale. + +## Files + +The move — 8 files, `git mv` the directory: + +`apps/ssp/src/app/registratie/ui/dashboard/` → `apps/ssp/src/app/registratie/ui/overzicht-secties/` + +``` +mijn-aanvragen.section.ts mijn-aanvragen.section.stories.ts +mijn-registratie.section.ts mijn-registratie.section.stories.ts +specialismen.section.ts specialismen.section.stories.ts +wat-moet-ik-regelen.section.ts wat-moet-ik-regelen.section.stories.ts +``` + +The importer — one file, four import lines plus one comment: + +- `apps/ssp/src/app/overzicht/ui/overzicht.page.ts:3-6`, and the comment at line 12 that says + "four sections stay in `registratie/ui/dashboard/`". + +**RD-31 added two more.** Its rewrite of `ARCHITECTURE.md` §6a links the read walkthrough to +`registratie/ui/dashboard/mijn-registratie.section.ts` and +`registratie/ui/dashboard/wat-moet-ik-regelen.section.ts` by full path. Both move here. Fix +them, or §6a's links break the day this ticket lands. + +The five doc citations: `docs/reference/feature-flags.md:55`, +`.claude/skills/new-ssp/SKILL.md:65`, `docs/reference/architecture/ARCHITECTURE.md:55` and `:79`, +`libs/shared/docs/remote-data.mdx:64`. + +## Steps + +1. `git mv` the directory. +2. Fix the four imports and the comment in `overzicht.page.ts`. +3. Fix the five doc citations per decisions 5 and 6. +4. `npm run ci --full`. + +## Acceptance criteria + +- [x] `apps/ssp/src/app/registratie/ui/dashboard/` no longer exists. +- [x] `grep -rn "ui/dashboard" apps libs docs/reference libs/shared/docs .claude` returns + nothing outside the `.xlf` extraction metadata named in Out of scope. +- [x] No live document cites `dashboard.page`. Historical records under + `docs/project/archive/` and the shipped `RD-*.md` files are exempt. +- [x] `git diff --stat -M` shows renames plus small edits, no rewritten files. +- [x] `npm run ci --full` is green. + +## Verification + +1. `npm run ci --full`. The four story files move, and only `build-storybook` proves that both + Storybook globs still pick them up. +2. `npm run storybook` — the four `Domein/Registratie/…` stories are still in the sidebar under + the same titles. +3. `npm start`, open `http://localhost:4200/dashboard`. All six sections render. + +## Out of scope + +- The `` metadata in `apps/*/src/locale/messages*.xlf`. + It still names `src/app/registratie/ui/dashboard.page.ts`, which RD-03 renamed. That + metadata comes from `ng extract-i18n` and no build reads it, so it is stale extraction + output from before RD-03, not a citation this ticket created. Regenerating it is its own + job. +- Renaming the `/dashboard` **route** to `/overzicht`. `PLAN.md` puts it under "Deliberately + out of scope": it needs a redirect and it is user-visible. +- Moving the four sections into the `overzicht` context. They read `BigProfileStore` and belong + to `registratie`; `overzicht` composes them. That is RD-03's decision and it stands. + +## Risks + +1. **A missed specifier fails the typecheck, not the build.** Run `npm run ci --full`, which + typechecks all four tsconfigs. +2. **`git mv` of a directory, then edits, can look like deletes and adds.** Commit the rename + and the edits together and check `git diff --stat -M` before you push. +3. **The route stays `/dashboard`.** Do not "tidy" it while renaming the folder. The folder name + and the URL are separate decisions, and only one of them is in this ticket. diff --git a/docs/project/readable-codebase/README.md b/docs/project/readable-codebase/README.md index ab306b8..57bac66 100644 --- a/docs/project/readable-codebase/README.md +++ b/docs/project/readable-codebase/README.md @@ -130,7 +130,7 @@ two. Note that RD-15 exists because 22 abandoned agent worktrees are still on di | RD-33 | CLAUDE.md + `atomic-design.mdx` + the `ui-component` skill | 03, 27, 29 | yes | done | | RD-34 | _(optional)_ `NO_SUBORGS`/`NO_TABLES` become `RemoteData.Empty` | 11 | | todo | | RD-35 | _(optional, last, alone)_ upload `type:` discriminant to `tag:` | 27 | | todo | -| RD-36 | `ui/dashboard/` → `ui/overzicht-secties/` + 2 stale `dashboard.page` paths | 04 | yes | todo | +| RD-36 | `ui/dashboard/` → `ui/overzicht-secties/` + 2 stale `dashboard.page` paths | 04 | yes | done | | RD-37 | **a11y:** 5 suppressions name a closed ticket — decide the `li[…]` host | 01 | yes | done | | RD-38 | One member order for the 3 wizard containers + 2 pure extractions | 22, 23 | | done | | RD-39 | **Bug:** the wizards' `seed` input never arrived (21 stories) | 38 | yes | done | diff --git a/docs/reference/architecture/ARCHITECTURE.md b/docs/reference/architecture/ARCHITECTURE.md index d1ea3ce..be4ae91 100644 --- a/docs/reference/architecture/ARCHITECTURE.md +++ b/docs/reference/architecture/ARCHITECTURE.md @@ -52,7 +52,7 @@ ever uses the level(s) below it — so anything you build is reusable by everyth ```mermaid graph TD - P["Pages
dashboard.page · login.page · intake.page"] + P["Pages
overzicht.page · login.page · intake.page"] T["Templates
page-shell · shell"] O["Organisms
login-form · registration-table · intake-wizard"] M["Molecules
form-field · data-row · async"] @@ -76,7 +76,7 @@ questions: | `application/` | How do we coordinate a task / state? | Yes (signals) | `big-profile.store.ts` | | `infrastructure/` | Where does data come from? | Yes (HTTP) | `big-register.adapter.ts`, `brp.adapter.ts` | | `contracts/` | What's the FE⇄BE wire shape? | **No** (pure DTOs) | `dashboard-view.dto.ts` | -| `ui/` | How does it look? | Yes (components) | `dashboard.page.ts` | +| `ui/` | How does it look? | Yes (components) | `overzicht.page.ts` | **The one rule that keeps it sane: dependencies only point _inward_.** UI may use application, application may use domain, everyone (in either app) may use `libs/shared` @@ -590,7 +590,7 @@ no longer hand-written DTOs — it's an **NSwag-generated typed client** toggle) and `role.interceptor.ts` (`X-Role` on role-aware endpoints). **A read (dashboard):** `` in -[`mijn-registratie.section.ts`](../../../apps/ssp/src/app/registratie/ui/dashboard/mijn-registratie.section.ts) +[`mijn-registratie.section.ts`](../../../apps/ssp/src/app/registratie/ui/overzicht-secties/mijn-registratie.section.ts) (`MijnRegistratieSection`) → [`BigProfileStore`](../../../apps/ssp/src/app/registratie/application/big-profile.store.ts) → `DashboardViewAdapter.dashboardViewResource()` = `resource({ loader: () => @@ -598,7 +598,7 @@ client.dashboardView() })` ([`dashboard-view.adapter.ts`](../../../apps/ssp/src/app/registratie/infrastructure/dashboard-view.adapter.ts)) → GET `/api/v1/dashboard-view` → `httpClientFetch` → proxy → backend → back through the `parseDashboardView(json): Result` trust boundary → `RemoteData` → rendered. -[`wat-moet-ik-regelen.section.ts`](../../../apps/ssp/src/app/registratie/ui/dashboard/wat-moet-ik-regelen.section.ts) +[`wat-moet-ik-regelen.section.ts`](../../../apps/ssp/src/app/registratie/ui/overzicht-secties/wat-moet-ik-regelen.section.ts) reads the same store. **A write (change address):** the `Submitting` effect (§2d) → `createSubmitChangeRequest` diff --git a/docs/reference/feature-flags.md b/docs/reference/feature-flags.md index b8d521d..b721b29 100644 --- a/docs/reference/feature-flags.md +++ b/docs/reference/feature-flags.md @@ -52,7 +52,7 @@ Each UI consumer injects `FeatureFlagStore`, imports the flag-key constant, and its own gating predicate inline: - `shared/layout/site-header/site-header.component.ts` — filters the "Inschrijven" nav item. -- `registratie/ui/dashboard.page.ts` — hides the "Inschrijven" dashboard action. +- `overzicht/ui/wat-wilt-u-doen.section.ts` — hides the "Inschrijven" dashboard action. So a second flag with a second consumer **repeats the pattern by hand** — there's no shared "gate this thing by flag" abstraction. That's fine at one flag / two consumers (a helper for diff --git a/libs/shared/docs/remote-data.mdx b/libs/shared/docs/remote-data.mdx index b6af9f2..3154941 100644 --- a/libs/shared/docs/remote-data.mdx +++ b/libs/shared/docs/remote-data.mdx @@ -61,7 +61,7 @@ even though they're nested in the same template. Angular types it `unknown`, and `AsyncComponent`/`AsyncLoadedDirective` pair is properly generic internally, but that genericity stops at the component's own boundary. -The idiom this repo uses instead — see `brief.page.ts`, `dashboard.page.ts`, +The idiom this repo uses instead — see `brief.page.ts`, `overzicht.page.ts`, `registration-detail.page.ts` — is a small **typed `computed()`** that unwraps the `Success` value, narrowed locally in the template with `@if (x(); as p)`: