feat(workflow): document-wait task + 30-day timeout cancellation (S-10a, closes #102) #105

Merged
not merged 23 commits from feat/102-document-wait-timeout into main 2026-07-20 09:42:03 +00:00
2 changed files with 21 additions and 9 deletions
Showing only changes of commit 5402bc179c - Show all commits
@@ -42,9 +42,16 @@ worker expires the correlated aggregate to a new terminal status `Verlopen`.**
- **Documents-in-time transition.** `IWorkflowClient.CompleteDocumentWaitAsync(processInstanceId)`
completes the `WachtOpDocumenten` task (the Workflow Client remains the only code that talks to
Flowable, §8.2). It is best-effort — a no-op if the instance already left the wait (continued, or
timed out). The *trigger* that calls it (the portal upload) is wired in S-10b; S-10a builds and tests
the completion path with the trigger stubbed (the live check completes the task directly to prove the
in-time branch, and the domain acceptance drives the worker against an in-memory stand-in).
timed out). The trigger is wired end-to-end in S-10a: a `ProvideDocuments` application use case behind
an owner-scoped domain endpoint `POST /registrations/{id}/documents`, a BFF passthrough
`POST /self-service/registrations/{id}/documents` (bsn from the DigiD token), and a "Documenten
aanleveren" action on the self-service page — so the walking-skeleton e2e stays green (a registration
can still reach the behandelaar). **S-10b replaces the stub trigger with a real file upload stored in
the ZGW Documenten (DRC) API via the ACL**; the completion of the wait is unchanged.
- *Why the trigger lives here, not in S-10b:* inserting the `WachtOpDocumenten` gate without any way
to pass it breaks the submit→beoordeling e2e (a merge gate). Splitting "gate" from "means to pass
the gate" across slices would leave `main` red, so S-10a owns both; S-10b is purely the ZGW storage
behind the same action.
## Consequences
@@ -60,12 +67,16 @@ worker expires the correlated aggregate to a new terminal status `Verlopen`.**
**Negative / costs**
- Every registration now parks at `WachtOpDocumenten` before Beoordelen, so the other live-check blocks
(S-11/S-12b/S-13/S-14) must complete that task first — a small, explicit step standing in for the
S-10b upload until it lands.
- Every registration now parks at `WachtOpDocumenten` before Beoordelen, so the other flows must supply
documents first: the live-check blocks (S-11/S-12b/S-13/S-14) complete the task via Flowable, and the
registration e2e clicks "Documenten aanleveren". A small, explicit step, but it touches every path
through the process.
- On expiry S-10a cancels the *process* and marks the aggregate `Verlopen` but does **not** set the ZGW
*zaak* to a cancellation status — that needs a new ACL method + statustype seeding, which overlaps
S-10b's ACL/infra work. Deferred to S-10b (or a follow-up); noted here as the S-10a/S-10b boundary.
- Withdrawing while parked at `WachtOpDocumenten` marks the aggregate `Ingetrokken` but does not cancel
the process (the withdrawal message boundary is on `Beoordelen`); the timeout worker tolerates this
by no-op'ing on an already-resolved aggregate. Extending withdrawal to the wait state is a follow-up.
## Alternatives considered
+4 -3
View File
@@ -395,9 +395,10 @@ for the citizen's documents (their diploma). Two things can happen:
`RegistratieVerlopen` external task, and the domain expires the registration to the terminal status
**VERLOPEN** (the case is cancelled).
The real upload trigger (portal → BFF → domain → ACL → Documenten API) is S-10b; until then the
"documents received" step is completing the task in Flowable, and the timeout is demonstrated by
firing the timer early via the management API.
The "documents received" trigger is wired end-to-end in S-10a: the self-service page shows a
**"Documenten aanleveren"** button after submit (portal → BFF → domain → completes the wait). S-10b
turns that into a real file upload stored in the ZGW Documenten API via the ACL. The timeout branch is
demonstrated by firing the 30-day timer early via the management API.
```bash
DOM=http://localhost:8080 # domain service