Commit Graph

14 Commits

Author SHA1 Message Date
f2d79919c4 fix(e2e): poll the register by reference, not a shared INGEDIEND cell (refs #78)
All checks were successful
CI / lint (pull_request) Successful in 1m23s
CI / build (pull_request) Successful in 1m17s
CI / unit (pull_request) Successful in 1m36s
CI / frontend (pull_request) Successful in 2m30s
CI / mutation (pull_request) Successful in 5m40s
CI / verify-stack (pull_request) Successful in 7m16s
The verify stack is shared: earlier verify-projection/verify-domain checks leave
INGEDIEND rows in the register before the e2e submits. A status-only poll
short-circuited on a stale row, then the reference assertion ran against a
not-yet-reloaded page and timed out. Poll (with reload) on this submission's
reference cell instead — stronger, and it directly proves the #78 correlation.
Scope the INGEDIEND/INGESCHREVEN status checks to that reference row too.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:36:24 +02:00
78e6c1d3d2 docs(architecture): ADR-0012 reference correlation + wire ACL for the subscriber (refs #78)
Some checks failed
CI / lint (pull_request) Successful in 4m33s
CI / build (pull_request) Successful in 1m17s
CI / unit (pull_request) Successful in 1m34s
CI / frontend (pull_request) Successful in 3m8s
CI / mutation (pull_request) Successful in 6m36s
CI / verify-stack (pull_request) Failing after 10m17s
Records the domain->ACL (write) and event-subscriber->ACL (read) boundary for the
single citizen reference, wires Acl__BaseUrl into the subscriber in compose, extends
the e2e happy path to assert confirmation reference == register reference, and adds
the demo note.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:47:03 +02:00
44e6f81f81 feat(portal-openbaar): surface the citizen reference in the public register (refs #78)
The BFF's public view exposes id/status/reference (never bsn/naam) and searches by
id or reference; the openbaar register's Referentie column and search now show the
reference the citizen saw on submit. api-client + openapi.json regenerated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:46:55 +02:00
566fc9bcea feat(event-subscriber): enrich the projection with the zaak reference via the ACL (refs #78)
On each notification the subscriber reads the zaak's reference (identificatie)
through the ACL — the only code allowed to talk to ZGW (§8.1) — and persists it on
the register_projection row and in the processed_notifications replay log. Storing
it in the log keeps rebuild log-only (ADR-0008): no ACL/ZGW access on rebuild.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:46:48 +02:00
7b841d6e62 feat(domain): pass the registrationId to the ACL as the zaak reference (refs #78)
OpenZaakWorker forwards registration.Id to IAclClient.OpenZaakAsync so the zaak's
identificatie equals the reference the citizen sees on the submit confirmation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:46:40 +02:00
ffbd8072b2 feat(acl): set and read the zaak identificatie as the citizen reference (refs #78)
The ACL now writes the domain registrationId as the zaak's identificatie on
POST /zaken, and exposes GET-through POST /zaken/reference to read a zaak's
identificatie back. Only the ACL touches ZGW (§8.1); the reference is the single
value shown on both the self-service confirmation and the openbaar register.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 14:46:32 +02:00
1c185e6686 S-09b: Approval flow — temp admin endpoint + status transition to projection (#77)
All checks were successful
CI / lint (push) Successful in 1m25s
CI / build (push) Successful in 1m13s
CI / unit (push) Successful in 1m26s
CI / frontend (push) Successful in 2m35s
CI / mutation (push) Successful in 6m6s
CI / verify-stack (push) Successful in 7m34s
## What & why

S-09b (#75, split from #10) — the **approval flow** that completes the walking skeleton. A behandelaar can now approve a submitted registration; the entry flips from `INGEDIEND` to `INGESCHREVEN` in the public register. Flow: `POST /registrations/{id}/approve` (domain) → ACL sets the zaak eindstatus (ZGW `/statussen`) → OpenZaak → NRC → event-subscriber → projection → openbaar.

## Changes (bottom-up, each red→green TDD)

- **Domain** — `RegistrationStatus.Ingeschreven` + `Registration.Approve()` (guards: opened zaak, only from INGEDIEND); `ApproveRegistration` use case (idempotent) + temp `POST /registrations/{id}/approve` endpoint; `IAclClient.ApproveZaakAsync`.
- **ACL** — resolves the zaaktype's **eindstatus** from the catalogus (`isEindstatus` / highest volgnummer) and POSTs a ZGW status; exposed as `POST /statussen`. Unit + real-OpenZaak integration test.
- **Event-subscriber** — binds NRC `hoofdObject`, projects a `status`/`create` as `INGESCHREVEN` keyed on the zaak (updates the existing row), **without reading OpenZaak** (§8.1). Retains the ZGW `resource` in the log (new column + EF migration) so a rebuild reproduces the status.
- **e2e** — extended: submit → public INGEDIEND → approve → public INGESCHREVEN.
- **Docs** — ADR-0011 (the two non-obvious decisions + the walking-skeleton assumption) + demo note.

## Key decisions (see ADR-0011)

- **ACL discovers the eindstatus** (chosen over injecting a statustype URL): no new config/seed plumbing, domain stays ZGW-ignorant.
- **Any post-creation status-set ⇒ INGESCHREVEN**: in the walking skeleton the only status ever set after creation is the approval, and the subscriber may not read ZGW — documented to tighten when more transitions arrive (S-12+).

## Verification

- All .NET unit suites green locally (domain 47, acl 11, event-subscriber 14, bff 16, acceptance 7); Release build + `dotnet format` clean.
- No new compose config (the eindstatus-discovery approach avoided it).
- The real-OpenZaak integration test (ACL status-set) and the full submit→approve→visible e2e run in CI `verify-stack` (live NRC→projection + selectielijst egress, not reproducible locally).

closes #75

Reviewed-on: #77
2026-07-14 09:04:57 +00:00
bc9831c113 S-09: Openbaar Register portal — public lookup (#76)
All checks were successful
CI / lint (push) Successful in 1m9s
CI / build (push) Successful in 53s
CI / unit (push) Successful in 1m4s
CI / frontend (push) Successful in 1m57s
CI / mutation (push) Successful in 5m19s
CI / verify-stack (push) Successful in 6m31s
Anonymous openbaar portal completing the walking skeleton (submit → projection → public visibility).

closes #10
2026-07-13 14:35:34 +00:00
39923e0e68 fix(e2e): treat the http portal origin as secure so DigiD PKCE login works (refs #68)
Some checks failed
CI / lint (pull_request) Successful in 1m12s
CI / build (pull_request) Successful in 53s
CI / unit (pull_request) Successful in 1m3s
CI / frontend (pull_request) Successful in 1m47s
CI / mutation (pull_request) Successful in 4m2s
CI / verify-stack (pull_request) Failing after 7m51s
The walking-skeleton e2e timed out waiting for the Keycloak login form
(`#username`). Root cause: in the compose network the portal is served over
plain HTTP on a non-localhost origin (http://self-service), which is not a
secure context, so Web Crypto (`crypto.subtle`) is undefined. angular-auth-
oidc-client needs SubtleCrypto to build the PKCE code challenge, so
`authorize()` threw ("Cannot read properties of undefined (reading 'digest')")
and the login redirect never fired.

Production serves the portal over HTTPS, where this works. Instead of
terminating TLS in the throwaway e2e stack, tell Chromium to treat the origin
as secure via --unsafely-treat-insecure-origin-as-secure. The flag is only
honoured by the full Chromium build (new headless), not Playwright's default
headless-shell, so pin channel: 'chromium'.

Verified against a minimal in-network stack (keycloak + self-service): login
redirect now reaches the Keycloak form, and the full login → token exchange →
authenticated portal renders with no console errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 13:37:31 +02:00
490e7347b0 test(e2e): walking-skeleton Playwright happy path + verify-e2e lane (refs #68)
tests/e2e Playwright spec drives DigiD login (jan-burger/test123) → submit →
confirmation against the compose-served portal. run-e2e-check.sh runs it inside the
compose network (node container, browser installed at runtime) so the token issuer
(keycloak:8080) matches the BFF authority (ADR-0010). Wired as verify-e2e (Makefile +
verify chain + a verify-stack CI step).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 14:08:10 +02:00
5d32d4f15e test(bff): acceptance scenario for BFF access (valid/invalid tokens) (refs #8)
Use-case-level BDD (Reqnroll) driving the real BFF over HTTP with fake downstreams
and locally-minted tokens: a valid DigiD token is accepted and the bsn forwarded
to the domain; a tokenless submit is 401; the openbaar register is anonymous and
never exposes the bsn (ADR-0010). Real Keycloak validation is the verify-bff check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 11:03:37 +02:00
79dcd8f14b test(domain): acceptance scenario for submitting a registration (refs #6)
Use-case-level BDD (Reqnroll) for S-05: a zorgprofessional submits a registration;
the Domain Service starts the registratie process and the OpenZaakAanmaken external
task opens a zaak via the ACL, recorded on the aggregate (ADR-0009). Driven against
in-memory Workflow Client and ACL stand-ins; real Flowable+ACL+OpenZaak delivery is
the live-stack verify-domain check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 17:15:23 +02:00
c70840e5b7 test(event-subscriber): project zaak-created notifications into the read projection (refs #7)
Failing unit + acceptance tests for the Event Subscriber's NotificationProjector:
a zaken/zaak/create notification yields one INGEDIEND projection row, duplicate
deliveries collapse to one row, non-zaak/non-create notifications are ignored, and
a rebuild repopulates the projection from the durable notification log (PRD §8.4).

The projector is a no-op stub so the tests compile and fail on the assertions; the
implementation follows in the green commit. The notification log doubles as the
idempotency guard and rebuild source so a rebuild needs no OpenZaak access (§8.1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 14:47:16 +02:00
28041228bd test(acl): BDD acceptance scenario for opening a zaak (closes #5) (#49)
Some checks failed
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
CI / unit (push) Has been cancelled
CI / compose-smoke (push) Has been cancelled
2026-06-08 11:25:26 +00:00