feat(behandel): behandel-portal — werkbak + beoordeling (closes #13) (#87)
All checks were successful
All checks were successful
## What & why
Finishes **S-12 · Behandel-portal — werkbak + beoordeling**. The backend sub-slices (S-12a/b/c-1/c-2) were merged, but the slice's stated outcome — a behandel *portal* with medewerker login, a werkbak, and decide — had no frontend. This adds it.
- **`libs/auth`**: `MedewerkerAuthService` + `provideMedewerkerAuth` (Keycloak `medewerker` realm), a `roles`/`hasRole` surface on the shared `AuthService`, and a realm-roles protocol mapper so the SPA can read `behandelaar`/`teamlead` from the token. The BFF remains the security boundary (ADR-0013).
- **`apps/behandel`**: a new Nx Angular app mirroring self-service — medewerker OIDC login and a **werkbak** page listing registrations awaiting beoordeling (`GET /behandel/werkbak`) with per-row **Goedkeuren/Afwijzen** actions (`POST /behandel/registrations/{id}/decide`) that refresh the list. NL DS/Utrecht, standalone + signals.
- **e2e**: the walking-skeleton happy path now approves through the real portal (behandelaar logs in, finds the row by reference, clicks Goedkeuren) instead of the temporary admin endpoint.
- **infra/docs**: behandel service in compose (`:8142`, depends on Keycloak); added to the smoke `WAIT_SVCS` + CI log dump; `frontend-decisions.md` and `demo-script.md` updated.
Closes #13
## Definition of Done
- [x] Linked Gitea issue (above).
- [x] Failing test committed before the implementation.
- [x] Implementation makes the test pass; refactor commit if structure improved.
- [x] Conventional Commits referencing the issue (`refs #13`).
- [ ] CI green — all Gitea Actions jobs.
- [x] `docker compose up` from a fresh clone reaches green health checks within 3 minutes. *(behandel image + container verified locally; full stack gated in CI.)*
- [x] Docs updated if behaviour, contracts, or operations changed.
- [x] ADR added — ADR-0013 (merged with the backend sub-slices) already covers the wiring; no new decision here.
- [x] Demo note in `docs/demo-script.md`.
## Notes for reviewers
- Verified locally: auth + behandel + all frontend projects pass lint & unit tests (incl. axe WCAG 2.1 AA); production build green; the behandel Docker image builds and serves with the correct baked `medewerker` config + SPA fallback.
- The full compose-up smoke, e2e, and mutation are CI-gated (known local full-stack verify limits).
- **Follow-ups (not in scope):** the `WerkbakItem` contract has no citizen name (werkbak shows the BSN) — adding one is a BFF+domain contract change; and the domain's temporary admin `approve` endpoint is now unused by the e2e and could be removed.
Reviewed-on: #87
This commit was merged in pull request #87.
This commit is contained in:
@@ -248,3 +248,30 @@ curl -fsS "http://localhost:8140/openbaar/register?q=$ref" | jq
|
||||
|
||||
> The openbaar register's "Referentie" column and its search now use this reference — the exact value
|
||||
> the citizen saw on submit. Asserted end-to-end by the Playwright happy path.
|
||||
|
||||
## S-12 — Behandel portal: werkbak + beoordeling (#13, ADR-0013)
|
||||
|
||||
A behandelaar now works submitted registrations in a real portal instead of the temporary admin
|
||||
endpoint. After a citizen submits (as above), the workflow parks the registration at the Flowable
|
||||
`Beoordelen` user task, and it shows up in the **werkbak**. The behandelaar logs in against the
|
||||
Keycloak `medewerker` realm and decides — **goedkeuren** (→ INGESCHREVEN via the ACL, per ADR-0011)
|
||||
or **afwijzen** — which also completes the Beoordelen task so the process advances.
|
||||
|
||||
```text
|
||||
# 1. Open the behandel portal and log in as a behandelaar (medewerker realm):
|
||||
# http://localhost:8142/ → merel-behandelaar / test123
|
||||
#
|
||||
# 2. The werkbak lists the registrations awaiting beoordeling (referentie / bsn / status).
|
||||
# Find the reference from the submit confirmation and click "Goedkeuren" on that row.
|
||||
#
|
||||
# 3. The row drops off the werkbak (its Beoordelen task is completed) and the openbaar register
|
||||
# (http://localhost:8141/) now shows that reference as INGESCHREVEN.
|
||||
```
|
||||
|
||||
**The path:** behandel portal → BFF `POST /behandel/registrations/{id}/decide` (behandelaar policy,
|
||||
`medewerker` realm) → domain applies the decision + completes the Flowable `Beoordelen` task →
|
||||
ACL → NRC → event-subscriber → projection → openbaar register shows INGESCHREVEN.
|
||||
|
||||
> The full round-trip — DigiD submit → public INGEDIEND → behandelaar goedkeurt in the werkbak →
|
||||
> public INGESCHREVEN — is the Playwright happy path (`tests/e2e/registration.spec.ts`), which now
|
||||
> drives the behandel portal in place of the old admin endpoint.
|
||||
|
||||
Reference in New Issue
Block a user