feat(bff): owner-scoped self-service withdraw endpoint (S-11c-1, refs #12) #90

Merged
not merged 3 commits from feat/12-withdrawal-bff into main 2026-07-16 12:20:44 +00:00
Contributor

What & why

Third sub-slice of S-11 · Withdrawal (Flow 3) (#12) — the owner-scoped BFF withdraw endpoint (backend). S-11a/b made a withdrawal transition the aggregate and cancel the workflow; this adds the citizen-facing entry point through the BFF, gated to the registration's owner.

  • Domain: WithdrawRegistrationCommand carries the caller's bsn; the handler returns a WithdrawOutcome and refuses a bsn that doesn't own the registration. Unknown and not-owned are both 404 (indistinguishable — ownership isn't revealed). POST /registrations/{id}/withdraw takes {bsn} and maps the outcome (204/404).
  • BFF: POST /self-service/registrations/{id}/withdraw (DigiD-authenticated) forwards the token's bsn to the domain and relays 204/404. The BFF authenticates; the domain owner-scopes (an aggregate invariant, not the domain doing auth).
  • OpenAPI spec + Angular client regenerated for the new endpoint.
  • run-domain-check.sh withdrawal step now sends the owner bsn (verify-stack).

Refs #12 — the self-service "trek aanvraag in" button + e2e (S-11c-2) closes it.

Definition of Done

  • Linked Gitea issue (#12).
  • Failing tests committed before the implementation.
  • Implementation makes the tests pass.
  • Conventional Commits referencing the issue (refs #12).
  • CI green — all Gitea Actions jobs.
  • docker compose up unaffected.
  • No ADR needed (owner-scoping is an aggregate invariant; no boundary change).
  • Docs — the user-visible demo note lands with S-11c-2.

Notes for reviewers

  • Full local gate run before pushing this time (lessons from #89): dotnet format --verify-no-changes clean; make unit green — Acl 27, EventSubscriber 19, BFF 30, Acceptance 9, Big 95; api-client lint+test green.
  • Owner mismatch returns 404 (not 403) so the portal can't be used to probe which references exist.
## What & why Third sub-slice of **S-11 · Withdrawal (Flow 3)** (#12) — the **owner-scoped BFF withdraw endpoint** (backend). S-11a/b made a withdrawal transition the aggregate and cancel the workflow; this adds the citizen-facing entry point through the BFF, gated to the registration's owner. - **Domain**: `WithdrawRegistrationCommand` carries the caller's `bsn`; the handler returns a `WithdrawOutcome` and refuses a bsn that doesn't own the registration. Unknown and not-owned are **both 404** (indistinguishable — ownership isn't revealed). `POST /registrations/{id}/withdraw` takes `{bsn}` and maps the outcome (204/404). - **BFF**: `POST /self-service/registrations/{id}/withdraw` (DigiD-authenticated) forwards the token's `bsn` to the domain and relays 204/404. The BFF authenticates; the domain owner-scopes (an aggregate invariant, not the domain doing auth). - OpenAPI spec + Angular client regenerated for the new endpoint. - `run-domain-check.sh` withdrawal step now sends the owner `bsn` (verify-stack). Refs #12 — the self-service "trek aanvraag in" button + e2e (S-11c-2) closes it. ## Definition of Done - [x] Linked Gitea issue (#12). - [x] Failing tests committed before the implementation. - [x] Implementation makes the tests pass. - [x] Conventional Commits referencing the issue (`refs #12`). - [ ] CI green — all Gitea Actions jobs. - [x] `docker compose up` unaffected. - [x] No ADR needed (owner-scoping is an aggregate invariant; no boundary change). - [x] Docs — the user-visible demo note lands with S-11c-2. ## Notes for reviewers - **Full local gate run before pushing this time** (lessons from #89): `dotnet format --verify-no-changes` clean; `make unit` green — Acl 27, EventSubscriber 19, BFF 30, Acceptance 9, Big 95; `api-client` lint+test green. - Owner mismatch returns 404 (not 403) so the portal can't be used to probe which references exist.
not added 3 commits 2026-07-16 11:55:21 +00:00
The withdraw handler returns an outcome and refuses a bsn that doesn't own the registration; the

BFF endpoint requires a digid token, forwards id+bsn, and relays the domain's 404.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The domain withdraw command carries the caller's bsn and owner-scopes the aggregate; unknown or

not-owned is 404 (indistinguishable). The BFF forwards the DigiD token's bsn and relays 204/404.

Regenerate the OpenAPI spec + Angular client for the new endpoint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test(verify): the domain withdrawal check sends the owner bsn (refs #12)
All checks were successful
CI / lint (pull_request) Successful in 1m16s
CI / build (pull_request) Successful in 1m13s
CI / unit (pull_request) Successful in 1m17s
CI / frontend (pull_request) Successful in 2m33s
CI / mutation (pull_request) Successful in 5m29s
CI / verify-stack (pull_request) Successful in 11m48s
3afa5a552a
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
not added the type:slicearea:domainarea:bff labels 2026-07-16 11:55:23 +00:00
not merged commit 2397d9196a into main 2026-07-16 12:20:44 +00:00
Sign in to join this conversation.