e6aaed7c8c4327aa68675bc933932d14acde7a00
11
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0cd70ae8c3 |
S-19a · ACL writes the RegisterRecord to Objecten on approval (closes #149) (#151)
Closes #149. **Outcome:** approving a registration now writes the canonical register record to the **Objecten** API as a `RegisterRecord` object, alongside the ZGW eindstatus. OpenZaak holds the process, Objecten holds the register (ADR-0028). The write goes through the ACL (§8.1) and is idempotent on the zaak id, so a replayed approval updates the existing object rather than creating a second one. S-19 (#20) was split first (CLAUDE.md §13) — it bundled this with re-sourcing the read projection, which is now #150. ### What landed - `IRegisterRecordGateway` + `RegisterRecord` in `Acl.Application`; `ObjectenGateway` in `Acl.Infrastructure` (static Token auth, CRS headers, objecttype resolved by name to its highest **published** version). - `AclService.ApproveZaakAsync` writes the record after the eindstatus, keyed on the zaak UUID with the zaak's identificatie as reference. - Compose wiring for both stacks; `ADR-0028`; demo note; PRD §15 out-of-scope line retired. ### Three things only a live stack found Running the gateway against a real Objecten + Objecttypen pair while writing this turned up blockers CI would have hit after the fact: 1. **Objecten rejects an objecttype it has not been configured with**, by UUID — assigned at seed time by a one-shot that runs *after* Objecten's static setup_configuration. The UUID is now pinned on both sides. 2. **Objecten 500s on every write when its Notificaties config is absent** (`notifications_api_common` raises rather than skipping). Objecten → NRC has no broker, worker, kanaal or abonnement, so notifications are **disabled** rather than wired to drop every message; #150 turns them on for real. 3. **Objecttypen echoes the request Host into the objecttype `url`**, and Objecten only accepts the one matching its configured `api_root` — so the ACL must read Objecttypen at `http://objecttypen:8000`. This is why the new integration test only passes inside the compose network. All three are recorded in ADR-0028. ### Verification - `ObjectenGatewayIntegrationTests` (verify-acl, in-network): two writes for one id leave exactly one object with the second write's status. **Passing locally against live Objecten.** - The **Playwright happy path** asserts, after the behandelaar approves, that Objecten holds exactly one `RegisterRecord` for *that* reference — missing, duplicated, or non-public-safe all fail. - ACL mutation score **92.23%** (baseline 91.37%, break 90). - `make lint` / `make unit` green locally; full-stack `make verify` runs in CI. ## Definition of Done - [x] A linked Gitea issue exists (#149). - [x] Failing test written and committed first. - [x] Implementation makes the test pass. - [x] Refactor commit follows if structure improved. - [x] Conventional Commit messages referencing the issue (`refs #149`). - [x] All Gitea Actions CI jobs green (run 684). - [x] `docker compose up` from a fresh clone reaches green health checks within 3 minutes (verify-stack step 1). - [x] Docs touched — ADR-0028, demo note, PRD §15, BACKLOG. - [x] ADR added: `docs/architecture/adr-0028-objecten-holds-the-register.md`. - [x] Demo note appended to `docs/demo-script.md`. - [x] Closed by the merging PR (`closes #149`). 🤖 Generated with [Claude Code](https://claude.com/claude-code)Reviewed-on: #151 |
||
|
|
5de8c1e292 |
feat(acl): resolve the zaaktype by identificatie, not a pinned URL (S-27, closes #113) (#118)
## What & why The ACL was handed a **pinned zaaktype URL** (`Acl__Defaults__ZaaktypeUrl`) + informatieobjecttype URL. OpenZaak assigns those UUIDs at creation, so every stack had to seed the catalogus and then capture + inject the resulting URLs out of band (CI's `run-domain-check.sh`; the local `local-seed`→`acl.env` bootstrap from ADR-0020). Brittle, and a stale/placeholder URL failed opaquely (OpenZaak 400). Now **the ACL resolves them itself** from OpenZaak's Catalogi API by stable business key: - config `ZaaktypeIdentificatie` (`BIG-REGISTRATIE`) / `InformatieobjecttypeOmschrijving` (`Diploma`); - a `CachedZaaktypeCatalog` resolves **lazily on first use** and caches (success only, so a pre-publish miss is retried — no startup ordering coupling); - a clear "No published … found" error replaces the opaque placeholder 400. Design in **ADR-0021** (proposed in #117). Closes #113 Closes #117 ## Consequences (the payoff) No stack captures/injects a server-assigned URL any more — `docker-compose.yml`/`.local.yml`, `run-domain-check.sh` and `local-seed` all drop it; the local `acl.env` shrinks to a single line. **One thing S-27 can't remove** (confirmed empirically during this work): OpenZaak validates the `zaaktype` field on zaak-create with Django's URLValidator and **rejects a single-label host** (`http://openzaak:8000/…` → `zaaktype: bad-url`). So the ACL's **base URL** must still point at a URL-valid host (a container IP); that base-URL injection from ADR-0020 stays (local `acl.env` now carries only it; CI keeps `ACL_OPENZAAK_BASEURL`). ADR-0021 records this. ## Definition of Done - [x] Linked issues (#113 slice, #117 adr-proposal). - [x] TDD — resolver + gateway-lookup unit tests, updated `AclService` tests (50 unit tests green). - [x] Implementation makes them pass; refactor of both compose stacks + verify scripts follows. - [x] Conventional Commits referencing #113. - [ ] CI green — see below. - [x] `docker compose up` reaches green health — verified: fresh `make local` + `make verify-local` green with **no zaaktype-URL injection**; `acl.env` is base-URL-only. - [x] Docs — ADR-0021 + demo-script S-27 note. - [x] ADR added (ADR-0021). - [x] Demo note appended. ## Verification done locally - **50 unit tests** pass (resolver resolve/cache/retry-on-failure; gateway match/miss/blank-key; all `AclService` paths). - **6 ACL integration tests** pass against a live seeded OpenZaak — incl. resolving the zaaktype + Diploma iot by business key, and a clear error for an unknown identificatie. - **Fresh `make local` + `make verify-local`**: full flow (submit → werkbak → openbaar) green; `acl.env` = `Acl__OpenZaak__BaseUrl` only. - `make lint` clean; ACL mutation ratchet run locally (see checks). ## Notes for reviewers - `IZaakGateway` gains two resolve methods; `AclService` depends on the new `IZaaktypeCatalog` (singleton, so the cache persists). - Supersedes the pinned-URL mechanism; ADR-0021 documents that ADR-0020's `seed-env`/entrypoint shim are **simplified** (base-URL only), not deleted, because of the URLValidator constraint above. Reviewed-on: #118 |
||
|
|
c8fdfbb699 |
feat(acl,domain): cancel the ZGW zaak on document-timeout expiry (S-10c, closes #106) (#109)
## S-10c · Close the ZGW zaak on document-timeout expiry (closes #106) Completes the S-10a/S-10b boundary flagged in ADR-0017: when a registration's 30-day document term lapses, the domain now cancels the **ZGW zaak** as well as marking the aggregate `Verlopen`, so OpenZaak and the register no longer diverge. ### What it does On expiry the `ExpireRegistrationWorker` calls the ACL to set the zaak to a distinct, non-terminal **`Geannuleerd`** status with a **`Vervallen`** resultaat (vs the approval `Afgehandeld` + `Geregistreerd`), resolved **by omschrijving** in the ACL — the ACL-first ordering mirrors approval so a failed ZGW call leaves the job for redelivery rather than diverging the two. **Path:** Flowable P30D timer → `RegistratieVerlopen` job → domain `ExpireRegistrationWorker` → ACL `POST /annuleringen` → ZGW `resultaten` + `statussen` (Geannuleerd) → aggregate `Verlopen`. ### Layers touched (each red→green) - **ACL gateway** — `SetZaakToCancellationStatusAsync` (Geannuleerd + Vervallen by name); approval now resolves its `Geregistreerd` resultaat by name too (a second resultaattype now exists). - **ACL service/API** — `AclService.CancelZaakAsync` + `POST /annuleringen`. - **Domain** — `IAclClient.CancelZaakAsync` + client; expiry worker cancels the zaak before advancing to `Verlopen`, guarded against redelivery double-cancel. - **Seed** — non-terminal `Geannuleerd` statustype (volgnummer 2; `Afgehandeld` → 3) + `Vervallen` resultaattype, both idempotent by omschrijving and sharing the zaaktype's procestype. - **Verify/integration** — ACL↔OpenZaak integration test (live `Geannuleerd` + resultaat); `run-domain-check.sh` fires the real P30D timer and asserts the zaak reaches `Geannuleerd` end-to-end; BDD scenario asserts cancel-on-timeout vs untouched-when-in-time. - **Docs** — ADR-0019 (cancellation modelling decision), demo-script, BACKLOG. ### Design note (ADR-0019) ZGW allows only one eindstatus per zaaktype, so `Geannuleerd` is modelled as a **non-terminal** status (it records a cancellation status + resultaat but does not set `einddatum`). This follows the issue's explicit "distinct statustype + resultaat" outcome; the shared-eindstatus alternative is recorded in the ADR. ### Tests Unit + acceptance all green locally (Acl 38, Big 134, Acceptance 17, Bff 33, EventSubscriber 19). Integration + verify-stack run in CI (need live OpenZaak + selectielijst egress). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #109 |
||
|
|
0904df8db0 |
feat(acl): diploma upload stored in the ZGW Documenten API (S-10b, closes #103) (#108)
## What & why S-10b: the self-service **diploma upload** is now real. After submitting, the citizen picks a PDF and uploads it; the portal base64-encodes it client-side → BFF → domain → **ACL**, which stores it in the ZGW **Documenten (DRC) API** as an `enkelvoudiginformatieobject` and relates it to the zaak, then the `WachtOpDocumenten` wait completes and the case advances to beoordeling. Per §8.1 only the ACL talks to ZGW. Closes #103 Mechanism in **ADR-0018** (proposal #107). Builds on S-10a (#102). The zaak-close-on-expiry item is carved to **#106 (S-10c)**. ## Definition of Done - [x] Linked Gitea issue (above). - [x] Failing test committed before the implementation (red→green per layer). - [x] Conventional Commits referencing the issue (`refs #103`). - [ ] CI green — all Gitea Actions jobs (pending on this PR). - [x] `docker compose up` health unaffected (ACL boots on a placeholder informatieobjecttype URL; the real one is injected by verify-domain). - [x] Docs updated (ADR-0018, demo-script, BACKLOG + S-10c). - [x] ADR added (`docs/architecture/adr-0018-diploma-upload-via-acl-documenten.md`). - [x] Demo note in `docs/demo-script.md`. ## Notes for reviewers - **ACL** (`OpenZaakGateway.StoreDocumentAsync` + `AclService.StoreDiplomaAsync` + `POST /documenten`) reuses the existing gateway patterns (ZGW Bearer, buffered non-chunked body, **no CRS** — Documenten isn't geo). Unit-tested via the stub handler; an **integration test** stores a real document against live OpenZaak (verify-acl). - **Transport:** base64 JSON on every hop (portal encodes client-side) — I deviated from proposal #107's multipart to keep one contract shape and avoid `IFormFile`/antiforgery/multipart-client plumbing; fine at diploma size (ADR-0018 §Alternatives). - **Infra:** `seed_catalogus.py` seeds + publishes a "Diploma" `informatieobjecttype` and relates it to the zaaktype (while both concept); `verify-domain` injects its URL into the ACL. No new ZGW scopes (seed applicatie has `heeft_alle_autorisaties`). - **e2e:** uploads a real PDF (`setInputFiles`) after the openbaar INGEDIEND row confirms the zaak is open (so storage doesn't race the OpenZaak worker). - **Scope boundary:** the ZGW zaak is not set to a cancellation status on 30-day expiry — that's #106 (S-10c). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #108 |
||
|
|
4777ff2b1d |
feat(workflow): document-wait task + 30-day timeout cancellation (S-10a, closes #102) (#105)
## What & why S-10a, the **workflow/timeout spine** of the (split) document-upload slice: the registratie process now parks at a **`WachtOpDocumenten`** user task with an **interrupting `P30D` boundary timer**. When the documents arrive the task completes and the process continues into the diploma routing (S-13) → Beoordelen; if the 30 days lapse, the timer cancels the wait, runs a `RegistratieVerlopen` external-worker task, and the domain expires the aggregate to a new terminal status **`Verlopen`**. Backend only — the real upload trigger (portal → BFF → ACL → Documenten API) is S-10b (#103). Closes #102 Mechanism recorded in **ADR-0017**; opened as proposal #104. Mirrors the S-14 escalation (boundary-timer + external-worker) and S-11 withdrawal (interrupting cancel) patterns. ## Definition of Done - [x] Linked Gitea issue (above). - [x] Failing test committed before the implementation (red→green pairs per layer). - [x] Implementation makes the test pass. - [x] Conventional Commits referencing the issue (`refs #102`). - [ ] CI green — all Gitea Actions jobs (pending on this PR). - [x] `docker compose up` health unaffected (no new services; deploy path unchanged). - [x] Docs updated (ADR-0017, demo-script, BACKLOG split). - [x] ADR added (`docs/architecture/adr-0017-document-wait-timeout-cancellation.md`). - [x] Demo note in `docs/demo-script.md`. ## Notes for reviewers - **Domain** (`Registration.Expire()` + `Verlopen`), **application** (`ExpireRegistrationWorker`), **infra** (`RegistratieVerlopenProcessor`/`Pump`, `IRegistratieVerlopenClient`, Flowable acquire/complete + `CompleteDocumentWaitAsync`) — the timeout counterpart to the OpenZaak/escalation worker trios; idempotent per §8.6. - **BPMN** verified live against a `flowable-rest` probe: complete `WachtOpDocumenten` → routes to Beoordelen; fire the P30D timer → `RegistratieVerlopen` job (carrying `registrationId`) + the wait task cancelled. `verify-domain` exercises both branches in-stack (completes the wait in every existing block; fires the timer and asserts `Verlopen` in a new block). - **Scope boundary:** on expiry the aggregate goes `Verlopen` and the process ends, but the ZGW *zaak* is not yet set to a cancellation status — that needs a new ACL method + statustype seeding and is folded into S-10b (noted in ADR-0017). - `CompleteDocumentWaitAsync` is built and HTTP-tested here but not yet called from a domain endpoint; S-10b wires the upload trigger to it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #105 |
||
|
|
ccae27b3da |
feat(workflow): diploma-eligibility DMN routes foreign diplomas via CBGV-advies (S-13, closes #14) (#101)
## What & why S-13: a diploma's origin decides its route. A **DMN** (`diploma-eligibility`) is evaluated inline by the registratie process as a **`businessRuleTask`**; an exclusive gateway routes a **foreign** (Buitenlands) diploma through a new **CBGVAdvies** user task before `Beoordelen`, a **domestic** one straight there (PRD flow 4). The domain's only new job is carrying the diploma origin and passing it as a process start variable. Chose **Option B (DMN in the BPMN)** over the issue's literal "evaluated by the Domain Service via Workflow Client" wording — keeps the decision a first-class workflow artefact and §8.2 clean. Rationale in **ADR-0016** (proposal #100); noted on this issue. Closes #14 ## Definition of Done - [x] Linked Gitea issue (above). - [x] Failing test committed before the implementation. - [x] Implementation makes the test pass. - [x] Conventional Commits referencing the issue (`refs #14`). - [ ] CI green — all Gitea Actions jobs. - [x] `docker compose up` from a fresh clone reaches green health checks within 3 minutes (additive; DMN deployed by flowable-init). - [x] Docs updated (ADR-0016, demo note). - [x] ADR added (`docs/architecture/adr-0016-diploma-eligibility-dmn.md`). - [x] Demo note in `docs/demo-script.md`. ## How it was built (TDD) - **Domain**: `DiplomaOrigin` on the aggregate + submit command; threaded through the process-start port so the Workflow Client emits a `diplomaOrigin` start variable. Red → green. - **DMN + BPMN**: `workflows/diploma-eligibility.dmn` (origin → route); `businessRuleTask` + exclusive gateway + `CBGVAdvies` user task in `registratie.bpmn`; DMN deployed to Flowable's DMN engine by `flowable-init`. - **Both paths**: `Een diploma op herkomst routeren` acceptance scenarios (origin carried into the process) + unit tests; verify-domain drives a foreign registration through CBGVAdvies→Beoordelen and the domestic one straight to Beoordelen — exercising both DMN branches live. ## Notes for reviewers - Deviation from the issue's Option-A wording is deliberate and recorded (ADR-0016); the outcome is unchanged. - The self-service eIDAS→foreign wiring is out of scope here (this slice is area:domain + area:workflow); the domain submit accepts an optional `diplomaOrigin` so the foreign path is drivable. - Local green: domain unit 109, acceptance 15, `dotnet format`, Release build (0 errors), **domain mutation 95.39%** (break 90). The DMN/`businessRuleTask` REST wiring is CI-verified on verify-stack (no local full-stack run here). Reviewed-on: #101 |
||
|
|
7bcbc726ce |
feat(workflow): beoordeling escalation to teamlead after 14 days (S-14, closes #15) (#99)
## What & why S-14: a beoordeling a behandelaar does not pick up within **14 days** escalates to the **teamlead**. A non-interrupting `P14D` boundary timer on the `Beoordelen` user task fires an external-worker task (`BeoordelingEscaleren`); the domain's escalation worker reassigns the still-open task's candidate group from `behandelaar` to `teamlead`. The task keeps its identity — only who may claim it changes. The escalation-via-external-worker decision is recorded in **ADR-0015** (proposal #98); it upholds §8.2 (the Workflow Client stays the only code that talks to Flowable) and keeps Flowable a stock image. Closes #15 ## 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 #NN`). - [x] CI green — all Gitea Actions jobs. - [x] `docker compose up` from a fresh clone reaches green health checks within 3 minutes (no new services; escalation is additive to the domain worker). - [x] Docs updated (ADR-0015, demo note). - [x] ADR added (`docs/architecture/adr-0015-beoordeling-escalation.md`). - [x] Demo note in `docs/demo-script.md`. ## How it was built (TDD) - **Workflow Client** (`IBeoordelingEscalatieClient`): acquire `BeoordelingEscaleren` jobs → find the open `Beoordelen` task in the instance → add `teamlead`/remove `behandelaar` candidate group → complete the job. Red → green. - **Escalation drain loop** (`BeoordelingEscalatieProcessor`) + hosted `BeoordelingEscalatiePump`, mirroring the OpenZaak worker. Red → green. - **BPMN**: non-interrupting `P14D` boundary timer on `Beoordelen` → external task → escalation end. - **Both branches** (escalate after timeout; no-op when completed in time) covered by the `Een beoordeling escaleren` acceptance scenarios + Workflow Client unit tests. - **Live integration**: `verify-domain` fires the timer early via Flowable's management API and asserts the reassignment to teamlead. ## Notes for reviewers - Interface segregation: escalation is on `IBeoordelingEscalatieClient`, separate from the OpenZaak worker's `IExternalWorkerClient`. - Reassignment is two REST hops (add teamlead, remove behandelaar); idempotent on redelivery — see ADR-0015 consequences. - Local checks green: domain unit tests (104), acceptance (13), `dotnet format --verify-no-changes`, Release build (0 errors), **domain mutation 96.69%** (break 90). The `run-domain-check.sh` escalation path is CI-verified on verify-stack (local full-stack run is constrained here). - `BeoordelingEscalatiePump` excluded from mutation, mirroring the existing `OpenZaakJobPump` exclusion. Reviewed-on: #99 |
||
|
|
2397d9196a |
feat(bff): owner-scoped self-service withdraw endpoint (S-11c-1, refs #12) (#90)
## 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. Reviewed-on: #90 |
||
|
|
a34caba9ea |
feat(domain): withdrawal cancels the registratie process (S-11b, refs #12) (#89)
## What & why Second sub-slice of **S-11 · Withdrawal (Flow 3)** (#12). S-11a (#88) made a withdrawal advance the aggregate to INGETROKKEN; this sub-slice **cancels the running Flowable process** so the withdrawn case leaves the behandelaar's werkbak. - **BPMN** (`registratie.bpmn`): an interrupting message boundary event (`RegistratieIngetrokken`) on the `Beoordelen` task, routing to a dedicated "Registratie ingetrokken" end event. - **Workflow Client**: `WithdrawBeoordelingAsync(executionId)` delivers `messageEventReceived` to the task's execution (PUT); `BeoordelingTask` now carries its `executionId`. - **`WithdrawRegistration` handler**: after the domain transition, finds the open `Beoordelen` task for the registration and delivers the withdrawal message — best-effort, mirroring how the beoordeling completes its task. - **Werkbak**: also filters out registrations that are no longer open, so a withdrawn case never surfaces even in the brief window before cancellation lands. - **ADR-0014** records the decision (message event in BPMN vs. deleting the instance from code). - **verify (`run-domain-check.sh`)**: a second registration parks at `Beoordelen`, is withdrawn via the domain, and the check asserts its `Beoordelen` task disappears — so verify-stack validates the live Flowable message correlation. Refs #12 (S-11c — the BFF + self-service "trek aanvraag in" button + e2e — closes it). ## Definition of Done - [x] Linked Gitea issue (#12). - [x] Failing tests committed before the implementation (red → green per commit). - [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 (BPMN redeploys on a fresh CI DB via flowable-init). - [x] ADR added (ADR-0014). - [x] Docs — the user-visible demo note lands with S-11c. ## Notes for reviewers - Verified locally: `Big.Tests` 94/94 pass; `Big.Api` builds; `registratie.bpmn` is well-formed. - The Flowable message-correlation REST shape is validated **live** by verify-stack (the Workflow Client unit tests stub the exchange and assert only the request shape, per ADR-0009) — the new `run-domain-check.sh` withdrawal step is that live check. - Known gap (ADR-0014): a withdrawal that races ahead of the process reaching `Beoordelen` finds no task to cancel; the aggregate is still INGETROKKEN and the werkbak filter hides it, but that instance parks unattended. A process-level event subprocess would close the gap — deferred. Reviewed-on: #89 |
||
|
|
4085bdead7 |
feat(#13): S-12b — Workflow Client user-tasks + Beoordelen userTask (#83)
## What & why Second sub-slice of **S-12 (#13)** — the **Workflow Client gains behandelaar user-task operations**, and the process model gains the beoordeling step. - **BPMN:** `registratie.bpmn` now parks at a `Beoordelen` **userTask** (candidate group `behandelaar`) after `OpenZaakAanmaken`; `registrationId` rides along as a process variable so the werkbak can correlate each task to its aggregate. - **Workflow Client** (`IUserTaskClient`, the only code that talks to Flowable §8.2): - `GetOpenBeoordelingenAsync()` — the werkbak (open `Beoordelen` tasks + their `registrationId`) - `ClaimAsync(taskId, behandelaar)` - `CompleteBeoordelingAsync(taskId, besluit)` — carries the decision into the process as the `besluit` variable - **Live integration:** `verify-domain` now drives the full user-task lifecycle against a real Flowable — after the worker opens the zaak, it polls for the task, claims it as `merel-behandelaar`, completes it (`goedkeuren`), and asserts the process finishes. This proves the exact REST contract (`service/runtime/tasks/query` + `…/{id}` claim/complete) the client depends on. The walking skeleton is unaffected: the temporary `/approve` path still sets the zaak status directly; wiring the domain decision to *complete this task* (and driving the werkbak from the BFF) lands in **S-12c**. ## Definition of Done - [x] Linked issue: #13 (umbrella; `refs`, does not close) - [x] Tests first; red → green - [x] Unit + acceptance green (`make unit`): domain 76, acceptance 9 (acl/event-subscriber/bff unaffected) - [x] Mutation ≥ break(90): **domain 100%** (killed the new survivors *and* the pre-existing `FlowableWorkflowClient` baseline) - [x] Live Flowable user-task lifecycle asserted in `verify-domain` - [ ] CI green (pending) Part of #13. Reviewed-on: #83 |
||
|
|
5a3f28ac6d |
ci(domain): containerize, wire into compose, and verify end-to-end (refs #6)
Dockerfile (multi-stage, .NET 10) + .dockerignore for the BIG Domain Service; a 'domain' service in infra/docker-compose.yml (health-checked, depends on acl healthy and flowable-init completed). run-domain-check.sh drives the full path against the up stack — seed a published zaaktype, recreate the acl pointed at it (host-consistent), POST /registrations, and assert the worker opens a zaak and records it. Wired as the verify-domain Makefile target + a verify-stack CI step; domain added to WAIT_SVCS and the log dump. seed_catalogus.py now emits a machine-readable ZAAKTYPE_URL line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |