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,69 @@
|
||||
# RB-06 — delete the dead `POST /registrations`
|
||||
|
||||
Status: **implemented** · 2026-08-27 · Source findings: `07-bio2-compliance.md` BIO-010 · `99-backlog.md` RB-06
|
||||
|
||||
## What was wrong
|
||||
|
||||
`POST /registrations` took a `Documents` list and passed it straight to `Submit`, which
|
||||
calls `DocumentStore.Link(...)` on every digital `documentId` in it. Linking a document
|
||||
**blocks its owner from deleting it** (`DeleteOwned` → 409 `Linked`).
|
||||
|
||||
There was no `ForeignIds` ownership check on that path. The real submit endpoint,
|
||||
`POST /applications/{id}/submit`, has had one since it was written:
|
||||
|
||||
```csharp
|
||||
if (documentIds is { Count: > 0 } && DocumentStore.ForeignIds(documentIds, ctx.Zorgverlener().Bsn) is { Count: > 0 } foreignIds)
|
||||
return Results.Problem(detail: $"Onbekend of niet-eigen document(en): …", statusCode: 400);
|
||||
```
|
||||
|
||||
So any authenticated citizen could post another citizen's document id and permanently
|
||||
block them from deleting their own diploma scan.
|
||||
|
||||
## Deleted rather than guarded
|
||||
|
||||
The ticket allowed either. Deleted, because the endpoint is dead: no frontend caller (the
|
||||
generated client's `registrations` method was unreferenced), and the whole registratie flow
|
||||
goes through `POST /applications/{id}/submit`.
|
||||
|
||||
| File | Change |
|
||||
| -------------------------------------------- | ------------------------------------------------- |
|
||||
| `Program.cs` | endpoint deleted |
|
||||
| `Contracts/Dtos.cs` | `RegistratieRequest` deleted (no other reference) |
|
||||
| `Domain/Submissions/SubmissionRules.cs` | `RejectRegistratie` deleted — see below |
|
||||
| `backend/swagger.json`, `api-client.ts` | regenerated (`npm run gen:api`) |
|
||||
| `EndpointTests.cs`, `SubmissionRuleTests.cs` | retargeted, see below |
|
||||
|
||||
### Why `RejectRegistratie` went with it
|
||||
|
||||
It was reachable only from this endpoint, and the live path deliberately **contradicts**
|
||||
it. `RejectRegistratie("handmatig")` returned a 422 rejection; the modern submit does
|
||||
|
||||
```csharp
|
||||
"registratie" => (null, req.DiplomaHerkomst == "duo"),
|
||||
```
|
||||
|
||||
— a manual diploma is not rejected, it simply does not auto-approve and goes to a
|
||||
behandelaar. Its own message even said so ("doorgestuurd voor handmatige beoordeling")
|
||||
while being returned as a rejection. Leaving it behind would have left an obsolete rule
|
||||
with a passing spec, which is exactly how it gets reintroduced.
|
||||
|
||||
**This is the one judgement call in this ticket** — the backlog row says "delete the dead
|
||||
endpoint", not "delete the rule". Reverting just the `SubmissionRules`/`SubmissionRuleTests`
|
||||
hunks restores it without touching anything else.
|
||||
|
||||
### Test coverage that moved rather than vanished
|
||||
|
||||
- `Registration_with_manual_diploma_is_rejected_with_problem_details` was the only test
|
||||
asserting the `Submit` helper's `application/problem+json` rejection shape. That assertion
|
||||
moved into `Change_request_with_bad_phone_is_rejected_with_problem_details` —
|
||||
`/change-requests` is the other endpoint on the same helper.
|
||||
- `User_delete_blocked_with_409_once_linked_to_submission` covered `DocumentStore.Link`
|
||||
blocking a delete. Retargeted to `POST /applications/{id}/submit`, i.e. the path that is
|
||||
actually in use. `POST /registrations` was the only other caller of `Link`.
|
||||
- `Registration_with_duo_diploma_succeeds` was deleted outright — `Change_request_with_valid_phone_succeeds`
|
||||
is the same assertion on the same helper.
|
||||
|
||||
## Verification
|
||||
|
||||
`npm run ci`. `dotnet test`: **249 passed, 1 failed** — the pre-existing
|
||||
`OpenZaakIntegrationTests.Admin_cases_…`, which needs a live container.
|
||||
Reference in New Issue
Block a user