Repository navigation
feat(decision-document): one decision lifecycle configured per kind on the case type (C03) - #3668
Merged
Merged
Conversation
…ction is a numbered successor
Decision 167: one running number per organisation per year (B-2026-000123),
written by compose() through OpenRegister's SequenceService with the case's
organisation in the scope key; no number, no beschikking (503). A correction
or withdrawal is issued through POST /api/beschikkingen/{id}/successor
(per-case mutation access): a new draft with its own number that points at
the original, which gains a write-once supersededBy. reference and supersedes
are frozen after signing. beschikking schema 1.1.0, info.xml bumped.
compose() no longer writes an empty addressee/decision as a JSON list against
type: object (found by validating the payload against the real schema).
Archives frozen-beschikking-and-numbered-successor; the chain on the case page
moves to beschikking-chain-on-the-case (board DqZaakBesluiten, decision 162).
…e, and the change is archived Decision 168 (Q-dossiq-L1-3): who may accept or refuse a hand-over for a unit is whoever has mutation access on the case; no action registry. Collecting that evidence found accept() and refuse() looking the request up by id alone while the controller authorised the caller on the URL's case, so mutation access on one case let a user answer, and on accept move, another. Both now take the authorised caseId and treat a request on another case as unknown. New CaseTakeoverControllerTest; cross-case test mutation-checked. Task 2.4 ticked, REQ-CUS-02 states the rule, deltas folded into case-management and dossiq-sociaal-domein-avg-consent, @SPEC tags repointed, change archived. screens.md: design backlog DqZaakBehandelketen (decision 157).
…ate and the other routes do
… document series (decision 182) DocumentSeriesNumberer issues <prefix>-<year>-<six digits> per series, per organisation, per year; the case type configures the prefix under documentSeries.<series>.prefix (register.d/39-document-series.json). Beschikkingen are the series 'beschikking', default prefix B. The refusal rule is document-number-unavailable. No new procedure-named classes: the successor moves into BeschikkingService::issueSuccessor() and the endpoint into BeschikkingController::successor(); BeschikkingNumberer, BeschikkingSuccession and BeschikkingSuccessorController are gone. Generic requirement in openspec/specs/numbered-document-series.
…any record kind (C04) FreezeDefinition, FreezeRegistry (app config frozen_records), FrozenRecordGuard, RecordSeal and FrozenRecordSuccessor, enforced by FrozenRecordListener on OpenRegister's updating and deleting events. Capability C04 of the procedures-are-configuration refactor (decisions 182, 184, 185); unit tests on a neutral fixture record kind. Nothing moves yet. Stacked on #3624.
…n the case type (C03) DecisionDocumentDefinition (decisionDocuments.<kind>), DecisionDocumentValidator (required fields, remedy clause, OpenRegister named-condition rules, failing closed), DecisionDocumentLifecycle (draft, approve with delegated authority, sign with the series number, send, archive) and the DecisionAuthority seam for lane R9's guard. A signed decision is a frozen record (C04). Capability C03 of the procedures-are-configuration refactor; unit tests on a neutral fixture case type. Nothing moves yet. Stacked on #3665 (C04) and #3624.
rubenvdlinde
requested review from
Rem-Dam,
SudoThijn,
WilcoLouwerse,
bbrands02,
remko48 and
rjzondervan
as code owners
October 10, 2026 21:14
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refactor lane R5, capability C03 (decision document) of hydra
procedures-are-configuration(ADR-118, decisions 182, 184, 185).Stacked on #3665 (C04 frozen record), which is stacked on #3624 (L1,
DocumentSeriesNumberer). Land #3624, then #3665, then this. Until then this diff shows their files too.What it adds
Service/DecisionDocument/DecisionDocumentDefinition:decisionDocuments.<kind>on the case type: template, required fields, rules (OpenRegister conditions, may use namedconditions), remedy clause (required by default), signed, authority act, decidiq decision kind, number series, frozen statuses. An incomplete block is refused.decisionTypes(ZGW besluittype refs) is left alone; see Q-R5-1.DecisionDocumentValidator: lists every problem; a rule that cannot be evaluated counts as failed and says so (ADR-005). Uses OpenRegister'sNamedConditionEvaluator, resolved lazily.DecisionDocumentLifecycle: draft; draft > approved > signed > sent > archived (approved may go back to draft). Approval needs a valid document and, when the kind names an act, the delegated-authority check. Signing needs the signature and issues the series number once. Returns the fields to write; the caller saves through OpenRegister.DecisionAuthority: the seam to lane R9's delegated-authority guard (C17, dossiq#3642). Nothing binds it yet, so approving a kind that names an act is refused with 503decision-authority-unavailable, never let through. R9 binds its guard under this interface when refactor(mandates): one transition guard asks decidiq for delegated authority #3642 lands (noted in refactor STATE).freezeDefinition(): the kind's frozen-record entry (C04), so a signed decision is held still through every writer.register.d/39-decision-documents.json(+ digest), specdecision-document(REQ-DDC-001 to 005), change archived as2026-10-10-decision-document-capability.Nothing moves in this PR.
BeschikkingServiceand family,Subsidie\BeschikkingService,WOODecisionServiceandBezwaar\DecisionServicemove onto this in later R5 PRs, after L10, L4, L6, L1 and #3572 land.Verified (targeted; no check slot started within 10 minutes, so CI is the full check)
Class ... DecisionDocumentLifecycle not found)phpunit tests/Unit/Service/DecisionDocument tests/Unit/Settings: 310 tests, exit 0 (incl. SchemaVersionFloorTest with the new fragment)phpcs,phpmd,phpstan,psalm,php-cs-fixer --dry-runonlib/Service/DecisionDocument: all exit 0composer check:strictnot run locally (memory under the slot's 10 GB floor): CI is the full check.No
.hydra/procedure-names.jsonin dossiq yet, so nothing to shrink.