From 4a7dc07786485e170780d90070121e8ad9ff7714 Mon Sep 17 00:00:00 2001 From: Niek Otten Date: Fri, 17 Jul 2026 12:05:21 +0200 Subject: [PATCH] docs(workflow): ADR-0016 + demo note for diploma-eligibility DMN (S-13, refs #14) Record the DMN-as-businessRuleTask decision (from proposal #100) and add the S-13 demo walkthrough showing a foreign diploma routing through CBGV-advies. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../adr-0016-diploma-eligibility-dmn.md | 66 +++++++++++++++++++ docs/demo-script.md | 39 +++++++++++ 2 files changed, 105 insertions(+) create mode 100644 docs/architecture/adr-0016-diploma-eligibility-dmn.md diff --git a/docs/architecture/adr-0016-diploma-eligibility-dmn.md b/docs/architecture/adr-0016-diploma-eligibility-dmn.md new file mode 100644 index 0000000..af5e19c --- /dev/null +++ b/docs/architecture/adr-0016-diploma-eligibility-dmn.md @@ -0,0 +1,66 @@ +# ADR-0016: Diploma eligibility is a DMN evaluated inline as a BPMN businessRuleTask + +- **Status:** Accepted +- **Date:** 2026-07-17 +- **Deciders:** Respellion engineering +- **Relates to:** S-13 (#14); proposal #100. Builds on ADR-0009 (external-task worker / Workflow + Client), ADR-0014/0015 (the boundary-event and routing constructs on the registratie process). + +## Context + +S-13 adds flow 4: a foreign diploma must get an extra CBGV-advies assessment before beoordeling +(PRD §5). The eligibility decision — domestic goes straight to beoordeling, foreign routes through +CBGV-advies — needs a home. The Flowable REST app bundles a DMN engine, and the same +`repository/deployments` machinery that deploys `registratie.bpmn` can deploy a `.dmn`. §8.2 makes +the Workflow Client the only code that talks to Flowable; the PRD frames the workflow as "BPMN + DMN +governing the registration workflow" (Flowable as a peer orchestration module). + +The issue's wording ("a DMN decision table evaluated by the Domain Service via Workflow Client") +suggests the domain reaches into Flowable's DMN API to evaluate the decision and feeds the result +back. That is one option; it is not the only one, and it is not the cleanest. + +## Decision + +**The diploma-eligibility DMN is deployed to Flowable and evaluated inline by the registratie process +as a `businessRuleTask`; an exclusive gateway routes on its output. The domain's only new job is to +carry the diploma origin and pass it into the process as a start variable.** + +- **The decision lives in the workflow.** `workflows/diploma-eligibility.dmn` maps `diplomaOrigin` + → `route` (`Buitenlands` ⇒ `CBGV_ADVIES`, otherwise `DIRECT`). A `businessRuleTask` + (`flowable:type="dmn"`, `decisionTableReferenceKey=diploma-eligibility`) runs it between + `OpenZaakAanmaken` and `Beoordelen`, and an exclusive gateway sends `CBGV_ADVIES` through a new + `CBGVAdvies` user task before `Beoordelen`, `DIRECT` straight there. +- **The domain carries the input, not the decision.** The `Registration` aggregate gains a + `DiplomaOrigin` (Binnenlands/Buitenlands); `SubmitRegistration` passes it to + `StartRegistrationProcessAsync`, which sets it as the `diplomaOrigin` start variable. The domain + never evaluates the DMN and never learns the route — that is the process's concern. +- **Deployed like the BPMN.** The DMN is version-controlled in `workflows/` and deployed to the DMN + engine by the same `flowable-init` step (via `dmn-api/dmn-repository/deployments`), staged into the + `fl-bpmn` volume alongside the BPMN. + +## Consequences + +**Positive** + +- The eligibility rule is a first-class, inspectable workflow artefact (matching the PRD's BPMN+DMN + framing); business users can read/adjust the decision table without touching domain code. +- §8.2 stays clean: the Workflow Client remains the only code talking to Flowable, and the decision + runs inside the process the client already started — no domain→Flowable round-trip for a decision. +- The domain change is minimal and additive: one value on the aggregate, one start variable. + +**Negative / costs** + +- Deviates from #14's literal "evaluated by the Domain Service via Workflow Client" wording (noted on + the issue). The outcome — DMN decides eligibility, foreign diplomas get the CBGV step — is unchanged. +- The DMN and its `businessRuleTask` wiring are validated live (verify-domain drives a foreign + registration through CBGV-advies and a domestic one straight to beoordeling, exercising both + branches), not in unit tests — consistent with ADR-0009/0014/0015. The domain unit/acceptance tests + cover only that the origin is carried into the process. + +## Alternatives considered + +- **Domain evaluates the DMN via the Workflow Client** (the issue's wording). Rejected: it couples + the domain to Flowable for a decision and splits the routing across two places (domain computes, + BPMN branches), for no benefit over letting the engine that owns the process own the decision. +- **Eligibility rules in domain C#.** Rejected: it moves a governable business decision out of the + DMN the PRD calls for, and hard-codes what the reference app is meant to demonstrate as data. diff --git a/docs/demo-script.md b/docs/demo-script.md index 5c8b44c..d2fcacb 100644 --- a/docs/demo-script.md +++ b/docs/demo-script.md @@ -343,3 +343,42 @@ candidate group behandelaar → teamlead (§8.2). > Both branches (escalate after 14 days; no-op when completed in time) are covered by the > `Een beoordeling escaleren` acceptance scenarios and the Workflow Client unit tests; the timer firing > and reassignment are asserted live by the verify-domain check. + +## S-13 — Diploma-eligibility: foreign diplomas route through CBGV-advies (#14, ADR-0016) + +A registration's diploma origin decides its route. A DMN `businessRuleTask` in the registratie +process evaluates the `diploma-eligibility` decision on the `diplomaOrigin` start variable: a +**foreign** (Buitenlands) diploma is routed through an extra **CBGV-advies** user task before +beoordeling; a **domestic** (Binnenlands) one goes straight to beoordeling. The decision lives in the +DMN, not in code — a beheerder can read and adjust the decision table directly. + +The self-service portal's eIDAS→foreign wiring is a later slice; for now the origin is submitted to +the domain directly, so the demo drives it through the domain endpoint: + +```bash +# 1. Submit a foreign-diploma registration to the domain (note the returned Location/reference): +DOM=http://localhost:8080 # domain service +curl -s -i -X POST "$DOM/registrations" -H 'Content-Type: application/json' \ + -d '{"bsn":"123456782","diplomaOrigin":"Buitenlands"}' | grep -i '^location:' +# +# 2. Once the zaak is opened, the process parks at the CBGV-advies task (NOT Beoordelen). In Flowable: +FL=http://localhost:8090/flowable-rest/service +curl -s -u rest-admin:test -X POST "$FL/query/tasks" -H 'Content-Type: application/json' \ + -d '{"processDefinitionKey":"registratie","taskDefinitionKey":"CBGVAdvies"}' | python3 -m json.tool +# +# 3. Complete the CBGV-advies task; the case then advances to the regular Beoordelen task: +TID=$(curl -s -u rest-admin:test -X POST "$FL/query/tasks" -H 'Content-Type: application/json' \ + -d '{"processDefinitionKey":"registratie","taskDefinitionKey":"CBGVAdvies"}' \ + | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"][0]["id"])') +curl -s -u rest-admin:test -X POST "$FL/runtime/tasks/$TID" \ + -H 'Content-Type: application/json' -d '{"action":"complete"}' +# A domestic submission (default, or "Binnenlands") skips CBGV-advies and parks straight at Beoordelen. +``` + +**The path:** domain sets the `diplomaOrigin` start variable → registratie process DMN +`businessRuleTask` sets `route` → exclusive gateway → foreign: `CBGVAdvies` user task → `Beoordelen`; +domestic: `Beoordelen` directly (§8.2, ADR-0016). + +> The domestic/foreign paths are covered by the `Een diploma op herkomst routeren` acceptance +> scenarios and unit tests (the origin is carried into the process); the DMN decision and the +> foreign→CBGV routing are asserted live by the verify-domain check.