Files
atomic-design-poc/docs/project/archive/refactor-backlog-setup/refactor-backlog/implementation/rb-06.md
T
ehoandClaude Opus 5 12f17d9d73 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>
2026-09-08 23:00:38 +02:00

3.7 KiB

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:

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

"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.