docs: archive the finished backlogs (RD-30)
Two backlog trees are complete: `docs/project/backlog/` (75 files, every WP done) and `docs/project/refactor-backlog-setup/` (the arc before it). Move both under `docs/project/archive/` with `git mv`, so history stays intact through `git log --follow`. `SHOWCASE-ROADMAP.md` moves with them, because it points at the now-archived backlog README. Add `docs/project/archive/README.md`. It states that these trees are historical and names the two directories that are still live. Repoint every inbound reference named in RD-30's Files table: CLAUDE.md, the root README, both backend READMEs, `LetterHtml.cs`, `a11y.mdx`, the `document-feature` and `new-ssp` skills, and the readable-codebase PLAN, README, and RD-19 ticket. Fix two upward-relative links inside the moved WP files (WP-68, WP-69) that gained a directory level and would otherwise break. Repoint `.prettierignore`'s two agent-prompt exclusions to their new path, so prettier keeps leaving those files' exact wording alone. Mark RD-30 done and check off its acceptance criteria; flip its README row to done. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# WP-24 — Letter canvas (edit on the letter)
|
||||
|
||||
Status: done
|
||||
Phase: 6 — Brief v2 (edit-on-the-letter, org templates, server-rendered preview)
|
||||
|
||||
## Why
|
||||
|
||||
The drafter should compose **on the letter** — letterhead above, footer/signature
|
||||
below, content blocks edited in place — instead of in an abstract form next to a
|
||||
separate preview. PRD Brief v2 §4. This is a **presentation rebuild only**: the
|
||||
domain model, `brief.machine.ts`, and every `BriefMsg` stay byte-identical.
|
||||
|
||||
## Read first
|
||||
|
||||
- PRD Brief v2 §2b (fidelity note), §4, §10; the sample `voorbeeldbrief-inschrijving.pdf`
|
||||
- `src/app/brief/ui/letter-composer/letter-composer.component.ts` (the `canEdit` pivot)
|
||||
- `src/app/brief/ui/letter-preview/letter-preview.component.ts` (rendering that migrates in)
|
||||
- `docs/project/backlog/WP-23-org-template-backend.md` (the `orgTemplate` on `BriefViewDto`)
|
||||
|
||||
## Decisions (pre-made, don't relitigate)
|
||||
|
||||
- **One stylesheet is the FE⇄BE rendering contract**: `public/letter.css` — class
|
||||
vocabulary `.letter`, `.letter__letterhead`, `.letter__body`, `.letter__signature`,
|
||||
`.letter__footer`, `.letter__page-break`; margins as `--letter-margin-*` custom
|
||||
props; `@page`/print rules. Loaded via `<link>` in `index.html` (app + Storybook).
|
||||
WP-25's backend renderer inlines the same file; its parity test is the fence.
|
||||
- **`LetterCanvasComponent`** (new organism, `Domein/Brief/Letter Canvas`) with
|
||||
`editableRegions: 'content' | 'template' | 'none'` — one component serves drafter
|
||||
composing, approver review (and in WP-26, the admin editor). Letter typography on
|
||||
the canvas is the letter's, not the portal UI's — but still token-bridged.
|
||||
- `'content'` mode hosts the **existing** `letter-section`/`letter-block` components
|
||||
unchanged; letterhead/footer/signature render read-only with a subtle tint and a
|
||||
first-use caption ("komt uit de huisstijl van de organisatie").
|
||||
- `'none'` mode absorbs `letter-preview`'s rendering (paragraph grouping, placeholder
|
||||
chips, sample-values toggle); **`ui/letter-preview/` is then deleted** — the PRD
|
||||
explicitly supersedes it; no third rendering is maintained.
|
||||
- **Page-break indicator is approximate by design**: a dashed line per A4-content
|
||||
interval with the caption "±pagina-einde — afdrukvoorbeeld is leidend" (PRD §2b
|
||||
honesty requirement).
|
||||
- `brief.machine.ts` and `BriefMsg` are untouched — `git diff` must prove it.
|
||||
|
||||
## Files
|
||||
|
||||
- `public/letter.css` (new), `src/index.html` (link)
|
||||
- `src/app/brief/domain/org-template.ts` (new, pure) — `OrgTemplate` type
|
||||
- `src/app/brief/infrastructure/brief.adapter.ts` (+spec) — parse `orgTemplate`
|
||||
- `src/app/brief/ui/letter-canvas/*` (new: component + stories)
|
||||
- `src/app/brief/ui/letter-composer/letter-composer.component.ts` (pivot swap) + stories
|
||||
- `src/app/brief/ui/brief.page.ts` (pass orgTemplate through)
|
||||
- delete `src/app/brief/ui/letter-preview/*`
|
||||
|
||||
## Steps
|
||||
|
||||
1. `letter.css` from the sample PDF's geometry (A4 proportions, letterhead, address
|
||||
window + reference block, footer rule, signature).
|
||||
2. `OrgTemplate` domain type + `parseOrgTemplate` boundary in the adapter (+spec).
|
||||
3. Canvas organism: three modes, zoom input, page-break indicator.
|
||||
4. Migrate `letter-preview` rendering into `'none'` mode; delete the component,
|
||||
fold its stories into the canvas stories.
|
||||
5. Swap the composer's `@if (canEdit())` pivot for
|
||||
`<app-letter-canvas [editableRegions]="canEdit() ? 'content' : 'none'">`.
|
||||
6. Stories: three modes + zoom + page-break, all axe-gated.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [x] Drafter edits blocks in place on the letter surface; passage picker and
|
||||
diagnostics click-to-locate still work on the canvas.
|
||||
- [x] Approver sees the identical surface read-only with the action bar.
|
||||
- [x] Letterhead/footer/signature come from `orgTemplate` and are visibly non-editable.
|
||||
- [x] `git diff` shows zero changes in `brief.machine.ts` / `brief.ts` Msg surface.
|
||||
- [x] `letter-preview` is gone; no story regression (`test-storybook:ci` green).
|
||||
- [x] Full GREEN + e2e smoke.
|
||||
|
||||
Field notes (landed alongside): the CIBG huisstijl styles bare `<header>`/`<footer>`
|
||||
elements (robijn background), so the canvas regions are `<div>`s — the letter surface
|
||||
must stay letter.css-only. The passage picker's checkboxes now get unique
|
||||
`checkboxId`s (all previously resolved to `id="undefined"`, so labels toggled only
|
||||
the first box — multi-select was broken) and an opaque background; `.letter__body`
|
||||
stacks above the page-break marks so the dashed line never draws through content,
|
||||
while the "±pagina-einde" caption floats above everything for legibility.
|
||||
|
||||
## Verification
|
||||
|
||||
GREEN one-liner; `npm run e2e` (brief flow); manual: `?role=drafter` compose on
|
||||
canvas, `?role=approver` review; `?scenario=slow|error` still degrade gracefully
|
||||
through `<app-async>`.
|
||||
|
||||
## Out of scope
|
||||
|
||||
Server-rendered preview + `[NOG IN TE VULLEN]` resolution (WP-25); admin `'template'`
|
||||
mode wiring beyond the input existing (WP-26 gives it a consumer); zoom controls
|
||||
polish + standaardbrief + diff badges (WP-27).
|
||||
|
||||
## Risks
|
||||
|
||||
The canvas duplicates the letter markup that WP-25's backend renderer will emit —
|
||||
acceptable _only_ because `letter.css` is shared and WP-25 adds the class-parity
|
||||
test; until WP-25 lands, the canvas is the sole consumer, so no drift is possible.
|
||||
Deleting `letter-preview` breaks any deep import of it — repo-wide grep before delete.
|
||||
Reference in New Issue
Block a user