Skip to content

feat(case-types): colour, versions, folders and the AVG fields - #1938

Merged
rubenvdlinde merged 19 commits into
developmentfrom
feat/case-type-authoring-extras
Sep 8, 2026
Merged

feat(case-types): colour, versions, folders and the AVG fields#1938
rubenvdlinde merged 19 commits into
developmentfrom
feat/case-type-authoring-extras

Conversation

@rubenvdlinde

@rubenvdlinde rubenvdlinde commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Implements the merged OpenSpec change case-type-authoring-extras (rows A10, A11, A29, A30, A31 of the round 2 placement). One noun: the case type's blueprint — what a status looks like, where a type gets its blueprint from, how types are grouped, what personal data it processes, and how it leaves and enters the system.

Scenario to e2e map

Every @e2e-tagged scenario in the five spec deltas, in tests/e2e/case-type-authoring-extras.spec.ts (13 tests):

Requirement Scenario Test
REQ-CT-01 A coloured status shows on the board a coloured status draws its board column in that colour
REQ-CT-01 A hidden status keeps its cases out of the list a hidden status keeps its cases off the list, and Closed brings them back
REQ-CT-01 (the badge half, on the case page) the case page draws the current status in its status's colour
REQ-CT-02 A child shows its parent's statuses a child that declares nothing shows its parent's four statuses, marked Inherited
REQ-CT-02 A child overrides one deadline a child's own deadline beats its parent's
REQ-CT-02 A cycle is refused a parent that descends from the type is refused, and the message names the cycle
REQ-PDM-01 A folder narrows the index picking a folder narrows the Case types index to that category
REQ-PDM-02 A shared attribute appears on every type an attribute saved without a case type is listed on every type, marked Shared
REQ-AVG-01 The block reads back what you saved the personal data block reads back the categories and the basis
REQ-WIE-01 Export downloads the bundle Export starts a download whose name carries the type's identifier
REQ-WIE-01 Duplicate opens the copy Duplicate lands you on the copy, with the same statuses
REQ-ZV-01 A draft with findings is not published a draft with findings lists them and stays a draft
REQ-ZV-01 A valid draft is published a valid draft is published with its change note, and the version says so

Two scenarios stay @e2e exclude exactly as the deltas wrote them: Import needs an OS file dialog (covered by the controller and service tests), and a verwerkingsactiviteit code cannot be refused until OpenRegister exposes the register as a referenceable schema (task 4.3, still blocked).

Where the design and the code disagree, and why

Five decisions in design.md could not be implemented as written. Each is recorded in tasks.md beside its task.

  • run-action is not a header-action type. The manifest schema enumerates handler, open-modal, open-page, navigate, object-op, export, open-form, refresh, api-call, agent and toggle, and CnActionButtons resolves exactly those. All four actions as designed would have been refused by check:manifest, and had they passed they would have rendered four buttons that dispatch nothing. Export is an api-call with download: true; the other three are dialogs, each for a reason a declarative action cannot meet — Import takes a file, Publish must show its findings before asking for a change note, Duplicate must land on the copy.
  • folderSidebar.source: "facet" does not exist. CnIndexPage resolves register, field, custom and files, and an unknown source falls through to custom — whose folder list is the absent folders array, so the pane renders empty and says nothing. It is source: "field" over category.
  • A filter cannot dot-path into a $ref. status.hiddenInLists is dropped by OpenRegister, which is a default filter that silently lists everything. The case now carries statusHiddenInLists, a materialised x-openregister-calculations entry over @ref.statusType.hiddenInLists — the same shape isFinalStatus already used.
  • The Inherited badge cannot be an object-list column. An object-list fetches OpenRegister itself, so the only question it can ask is caseType = @objectId: a child that inherits its lifecycle would render an empty table. GET /api/case-types/{id}/blueprint merges the chain server-side; case-type-blueprint renders it, and stays out of any tab strip because a type: "custom" widget named as a tab child resolves by registry type and renders an empty panel without logging.
  • Publish could not reuse either existing validate. CaseDefinitionController::validate() validates an uploaded package, and ZgwZtcRulesService::validatePublish() reads the type's own statuses — so a child would be refused with "give it a status" while its page showed four. CaseTypePublishService validates through the resolver.

What the checks found

Five defects that no other check saw, all fixed on the branch:

  • gate-14 route-reachability: appinfo/routes.php still carried caseDefinition#blueprint and caseDefinition#publish after the controller they pointed at was reverted. A route with no target method is a 500 at dispatch.
  • gate-9 semantic-auth: #[NoAdminRequired] over an admin-only body, which is what the change's own task text asked for. Both methods now carry #[AuthorizedAdminSetting(AdminSettings::class)] and the body guard is gone.
  • gate-6 orphan-auth: assertNoCycle() was defined and never called. Wired into CaseTypePublishService::validate(), which is the only write dossiq owns — a case type is saved straight to OpenRegister's object API by the page, so "refused on save" can be met nowhere else. Recorded as a limitation.
  • gate-16 spec-coverage: 44 changed frontend methods with no @spec.
  • ManifestColumnBindingTest: the Versions list bound its Updated column to updated, which workflowTemplate does not declare — a column that renders a dash in every row. It is @self.updated.

Known limitations, recorded in tasks.md

case.status carries an x-relation-filter and case.caseType an x-openregister-prefill; both are OpenRegister's, both read the child's own rows, and neither can express a chain. So the status picker on a new case of a child type offers only the child's own statuses, and the case form does not pick up a shared attribute. effectiveCaseType() inherits initialStatus so every PHP reader is right; the picker is filed as an OpenRegister request.

Checks, by exit code

Run locally on this branch, AFTER merging development in (four l10n files conflicted, both sides having appended entries at the tail of the translations object; resolved as the union and the .js catalogues regenerated). E2E was NOT run: it runs on the development push, and a pull_request check cannot prove an E2E fix.

Check Exit
npm run lint 0
npx vitest run (72 files, 820 tests) 0
npm run check:manifest 0
node tests/l10n/check-l10n.js 0
node scripts/check-schema-l10n.js 0
npm run check:l10n-js 0
npm run format 0
composer lint 0
composer phpcs 0
phpmd, swept per lib/ directory 0, no findings
composer psalm 0
composer phpstan 0
./vendor/bin/phpunit (3262 tests) 0
HYDRA_GATE_BASE_REF=origin/development run-hydra-gates.sh 0 (82 of 82 applicable gates ran; two pre-existing advisory warnings, non-blocking)

composer check:strict was run as its separate legs: as one command it exceeds a 300s budget. phpmd was swept per directory because printing nothing is its OOM signature, so a whole-lib/ pass that says nothing proves nothing.

🤖 Generated with Claude Code

…-authoring-extras

# Conflicts:
#	l10n/en.js
#	l10n/en.json
#	l10n/nl.js
#	l10n/nl.json
@rubenvdlinde
rubenvdlinde merged commit a3be5d4 into development Sep 8, 2026
42 of 48 checks passed
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/dossiq @ f58508e

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-vue3-compile
test-l10n
format
check-schema-l10n
check-l10n-js
composer ✅ 106/106
npm ✅ 541/541
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development
Hydra gates

Quality workflow — 2026-09-08 13:38 UTC

Download the full PDF report from the workflow artifacts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant