Files
atomic-design-poc/docs/project/backlog/WP-63-aanvraag-status-lifecycle.md
T
ehoandClaude Sonnet 5 d3f3b13345
CI / changes (push) Successful in 8s
CI / lint (push) Successful in 50s
CI / frontend (push) Successful in 1m32s
CI / backend (push) Successful in 1m50s
CI / e2e (push) Successful in 3m7s
CI / storybook-a11y (push) Successful in 6m53s
CI / semgrep (push) Successful in 1m12s
CI / api-client-drift (push) Successful in 1m43s
feat(behandelportal): WP-63 aanvraag status lifecycle enum
Model the full ADR-0002 lifecycle (Ingediend/InBehandeling/
MeerInfoGevraagd/Goedgekeurd/Afgewezen) as a backend enum backing the
existing AanvraagStatusDto.Tag string, and widen the FE union/parse
boundary/switches to match. Ingediend/MeerInfoGevraagd aren't reachable
yet (no behandelaar transition exists) — that's WP-65. Zero DTO shape
change, so gen:api has no drift.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-01 08:56:47 +02:00

4.2 KiB

WP-63 — Backend: aanvraag status lifecycle as a published DTO

Status: done Phase: 11 — Behandelportal

Why

The FE currently infers "in behandeling" from a single boolean, pendingHerregistratie (big-profile.store.ts:53) — explicitly called out in ADR-0002 as "a temporary stand-in for a real, backend-owned status." The full lifecycle (Ingediend → In behandeling → (Meer info gevraagd ⇄) → Goedgekeurd/Afgewezen) needs to become a real backend-published value before either frontend can render it meaningfully — the SSP needs it as a richer read (this WP), the behandelportal needs it as the thing it advances (WP-65).

Read first

Decisions (pre-made, don't relitigate)

  • Status lives on the existing Aanvraag/ApplicationSummaryDto aggregate (extend, don't invent a parallel status resource).
  • The DTO change is additive: the SSP's pendingHerregistratie boolean can be derived from the new status field (or kept as a computed convenience) so this ships with zero required FE behavior change — a pure backend + contract widening.
  • Only the status value is published here; any transition (advancing it) is a separate write endpoint, not part of this slice (that's WP-65's mutation).

Files

  • Data/ApplicationStore.cs (status field/enum)
  • Contracts/Dtos.cs (extend ApplicationSummaryDto/status DTO)
  • The FE infrastructure/*.adapter.ts + parse* boundary consuming it
  • big-profile.store.ts (derive the existing boolean from the new field)

Steps

  1. Model the full status enum backend-side (Ingediend, InBehandeling, MeerInfoGevraagd, Goedgekeurd, Afgewezen) on Aanvraag.
  2. Publish it on the existing DTO the SSP already consumes.
  3. Regenerate the typed client (npm run gen:api); update the FE parse* boundary to read the new field.
  4. Point pendingHerregistratie (or its replacement) at the new field so the SSP's existing behavior is unchanged, just backed by a real value.

Acceptance criteria

  • Backend publishes the full status lifecycle value on the existing aanvraag DTO.
  • npm run gen:api leaves no drift; SSP's existing "pending" display is unchanged in behavior, now backed by the real status.
  • dotnet test + npm run ci green.

Outcome

Implemented as a pure type-system widening, not a behavior change: AanvraagStatusTag (Ingediend | InBehandeling | MeerInfoGevraagd | Goedgekeurd | Afgewezen) is a new C# enum backing Mappers.ToStatusDto's existing string literals — AanvraagStatusDto.Tag stays a plain string, so the OpenAPI schema (and npm run gen:api) don't change at all, satisfying "zero required FE behavior change" trivially. Ingediend/MeerInfoGevraagd aren't reachable from any code path yet (no behandelaar action exists to produce them) — that's WP-65's transition endpoint, exactly per this WP's own Risks note. The FE AanvraagStatus union, parseAanvraagStatus, statusLabel/submittedRow/detailRows, blockActions, and the dashboard's sort order were all widened to the two new tags so TypeScript's exhaustiveness checking forces every switch to handle them once WP-65 starts emitting them. big-profile.store.ts's pendingHerregistratie was deliberately left untouched — it's a pure client-side optimistic UI flag unrelated to any DTO field (not what the WP's "Why" section implied), and the decision text's "or kept as a computed convenience" explicitly allows this.

Verification

cd backend && dotnet test; npm run gen:api (no drift); npm run ci; manual: SSP dashboard still shows the same pending/approved states it does today.

Out of scope

Any endpoint that advances the status (WP-65); the behandelportal consuming it (WP-64).

Risks

If the enum doesn't anticipate a state WP-65 needs (e.g. distinguishing who can transition from what), it gets revised there — acceptable, this slice only needs to cover the states already named in ADR-0002's diagram.