Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
c56a26c
chore(release): sync beta back into development
github-actions[bot] Aug 31, 2026
d6075fa
fix(kpi): drop hardcoded KPI colours so the cards follow the theme (#…
rubenvdlinde Aug 31, 2026
80a3580
fix(composer): declare ext-xsl so dependabot can resolve (#1569)
rubenvdlinde Aug 31, 2026
3574342
Merge pull request #1571 from ConductionNL/sync/beta-to-development-0…
rubenvdlinde Aug 31, 2026
65ca949
chore(deps): take @conduction/nextcloud-vue 2.27.2 (#1577)
rubenvdlinde Aug 31, 2026
e5f6724
chore(release): 0.3.9-unstable.20260831115159 (#1579)
github-actions[bot] Aug 31, 2026
ac81ed0
fix(deps): make the npm overrides follow their direct dependency (#1580)
rubenvdlinde Aug 31, 2026
e1571a4
chore(release): 0.3.10-unstable.20260831161807 (#1581)
github-actions[bot] Aug 31, 2026
8adf646
feat(parafering): an approval route is a flow, not a schema (#1582)
rubenvdlinde Aug 31, 2026
d1f1403
refactor(organisations): retire the menu entry that outlived the migr…
rubenvdlinde Aug 31, 2026
6de3e5e
chore(icons): adopt the Tier B vocabulary, except for the objection P…
rubenvdlinde Aug 31, 2026
a10a978
chore(register): retire catalog, rename location to case-location (#1…
rubenvdlinde Sep 1, 2026
5007151
fix(dashboard): drop the second Refresh from the dashboard header (#1…
rubenvdlinde Sep 1, 2026
3f0f353
refactor(committees): a committee is maintained in decidiq, not in do…
rubenvdlinde Sep 1, 2026
63e140b
fix(lhs): the overheid actor type had no reachable cell in the matrix…
rubenvdlinde Sep 1, 2026
a15f07e
feat(lhs): an enforcement matrix is a decision table (#1598)
rubenvdlinde Sep 1, 2026
5b860a7
feat(flow): finish case-flow-human-steps, fix the document step that …
rubenvdlinde Sep 1, 2026
666fc78
feat(parafering): a flow can ask for a paraaf, not just a task (#1602)
rubenvdlinde Sep 1, 2026
880642d
feat(reassignment): reassign from the cases page, not from a settings…
rubenvdlinde Sep 1, 2026
ce45b95
feat(reports): one Reports page of cards, in the footer (#1583)
rubenvdlinde Sep 1, 2026
b5efa1b
fix(parafering): a returned voorstel goes back, and the paraaf node s…
rubenvdlinde Sep 1, 2026
2db479a
chore(lint): let the linter see tests/ and scripts/ (#1614)
rubenvdlinde Sep 1, 2026
ba79721
feat(case): show the case's own flow run on the case detail page (#1615)
rubenvdlinde Sep 1, 2026
dc66f63
fix(e2e): the navigation spec still asserted the Reports submenu (#1617)
rubenvdlinde Sep 1, 2026
431cdda
feat(parafering): enabling a projected route is what moves it onto th…
rubenvdlinde Sep 1, 2026
32d24d6
feat(partners): a ketenpartner is an organisation, so migrate it onto…
rubenvdlinde Sep 1, 2026
cdac07f
feat(parafering): a given paraaf resumes the run that asked for it (#…
rubenvdlinde Sep 1, 2026
f975eee
test(flow): live case-flow journeys for a disposable instance, and ho…
rubenvdlinde Sep 1, 2026
b408b90
fix: five live defects that stopped the seeded case flow (#1625)
rubenvdlinde Sep 1, 2026
1838806
test(apphost): the catch-all no longer answers unmatched API paths (#…
rubenvdlinde Sep 1, 2026
3f6238e
fix(e2e): skip the adopted-flow journeys when the flow is not adopted…
rubenvdlinde Sep 1, 2026
46273fe
chore(deps): take nextcloud-vue 2.29.0, so the Reports page speaks Du…
rubenvdlinde Sep 1, 2026
305fdd2
feat(parafering): a projected approval route now drives parafering, e…
rubenvdlinde Sep 1, 2026
8479940
feat(parafering): retire the approval-route design screen, now that a…
rubenvdlinde Sep 1, 2026
626272d
fix(case-flow): the e2e journeys walk the task lifecycle, and the cas…
rubenvdlinde Sep 1, 2026
5a1bee7
build(guard): fail the build when two Dexie versions ship in one chun…
rubenvdlinde Sep 1, 2026
3850b4d
fix(e2e): drive the live journeys the way the API actually behaves (#…
rubenvdlinde Sep 1, 2026
d612c07
feat(case-detail): a KPI row, tabbed panels, and hours that come from…
rubenvdlinde Sep 1, 2026
3391b3b
chore(release): 0.3.11-unstable.20260901211251 (#1642)
rubenvdlinde Sep 1, 2026
82d0ee6
fix(flow): run every flow step's storage work as the run's acting ide…
rubenvdlinde Sep 2, 2026
52a7ef2
fix(flow): a handler's save no longer clobbers writes made after its …
rubenvdlinde Sep 2, 2026
3c2f1bf
fix(flows): point the flows page's row navigation at the FlowDetail p…
rubenvdlinde Sep 2, 2026
48c642b
feat(case-types): gather the work surfaces under My work, and let oth…
rubenvdlinde Sep 2, 2026
3ba4a28
refactor(decisions): dossiq stops authoring decisions; decidiq owns t…
rubenvdlinde Sep 2, 2026
32c329e
spec: open retire-cmmn-caseplanstate (drain the CMMN runtime onto ope…
rubenvdlinde Sep 2, 2026
80798de
feat(case-detail): one strip for the case's collections, one data blo…
rubenvdlinde Sep 2, 2026
72aacff
Termijnbewaking op engine timers, fase 1: de kern-termijnmotor (#1663)
rubenvdlinde Sep 2, 2026
b442e44
fix(e2e): follow the nav labels #1646 renamed (#1662)
rubenvdlinde Sep 2, 2026
abaf59e
feat(publication): dossiq delivers nothing — besluit publication trav…
rubenvdlinde Sep 2, 2026
eb68bb1
feat(parafering): move the runtime to the decision app; dossiq raises…
rubenvdlinde Sep 2, 2026
3318ca4
chore(deps): take nextcloud-vue 2.31.1, so a hovered KPI tile stops n…
rubenvdlinde Sep 2, 2026
daac508
fix(case-detail): put back the showTitle flags the layout rewrite dro…
rubenvdlinde Sep 2, 2026
5a4be54
refactor(dossiq): say cases, adopt the store, and stop keeping privat…
Sep 2, 2026
52fea5e
feat(kcc+flow): KCC routing onto OR decision tables; adopt the engine…
rubenvdlinde Sep 2, 2026
d066f82
refactor(enforcement): the decision table is the lookup, and the page…
Sep 2, 2026
3c7bf5a
refactor(enforcement): the implementation the previous commit described
Sep 2, 2026
6717020
Merge origin/development into fix/case-vocabulary-and-store
Sep 2, 2026
47a17ba
style(store): run prettier over the three files it had not seen
Sep 2, 2026
7751682
refactor(status): the wave-5 status-machinery sweep onto the engine l…
rubenvdlinde Sep 2, 2026
c0d71b4
feat(cases): a New case dialog a case handler can actually fill (#1653)
rubenvdlinde Sep 2, 2026
60186c4
test: cover the three classes this change added without tests
Sep 2, 2026
2c52038
Merge pull request #1677 from ConductionNL/fix/case-vocabulary-and-store
rubenvdlinde Sep 2, 2026
20f6c7e
test(visual): the cases baseline WAS the dashboard, and the store had…
Sep 2, 2026
33a5b10
fix(store): an install creates, and can never replace a local object
Sep 2, 2026
0e2ee75
fix(e2e): the task list spec required an empty register to pass (#1683)
rubenvdlinde Sep 2, 2026
cbe429f
Merge pull request #1685 from ConductionNL/chore/store-visual-baseline
rubenvdlinde Sep 2, 2026
567d717
fix(security): a client-supplied identity cannot address an existing …
Sep 2, 2026
282c881
Merge pull request #1687 from ConductionNL/fix/store-install-cannot-o…
rubenvdlinde Sep 2, 2026
d8d3d75
The OpenRegister calls that only the fakes believed: saveObject's ret…
rubenvdlinde Sep 2, 2026
5754610
Finish the is_array-on-find sweep: 24 dead not-found guards and 22 en…
rubenvdlinde Sep 2, 2026
06bf927
Merge pull request #1690 from ConductionNL/fix/client-supplied-identi…
rubenvdlinde Sep 3, 2026
2e059d8
fix(store): label the store save, which reddened development's e2e
Sep 3, 2026
4344c30
Merge pull request #1697 from ConductionNL/fix/store-settings-save-label
rubenvdlinde Sep 3, 2026
f355412
refactor(nav): retire five superseded pages instead of only hiding th…
rubenvdlinde Sep 3, 2026
355d1ec
feat(demo): a demo caseload, and the three silent defects that kept i…
rubenvdlinde Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
51 changes: 51 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,57 @@ npm run dev # Development build (watch mode)
npm run build # Production build
```

## Demo data

The dashboard widgets, the Tasks page and My Work all filter on the current
user, so a fresh instance shows empty panels even when the register imported
cleanly. Seed a working caseload:

```bash
occ dossiq:demo:seed # 18 cases across the four case types, 32 tasks
occ dossiq:demo:seed --verify-only # report the buckets without creating anything
```

Safe to re-run. A case whose title is already present is skipped, and its tasks
with it.

The dates in `lib/Settings/demo_caseload_seed_data.json` are relative day
offsets, resolved when the seed runs, so the overdue and at-risk buckets stay
correct however long the file sits in the repo. Give a case either
`deadlineInDays` or `startInDays`, never both: `deadline` is a materialised
calculation over `startDate` plus the case type's `processingDeadline`, so the
seed reaches a deadline by backdating the start date.

`--verify-only` counts what the dashboard will read by querying the register
back, not by counting the seed file. A count taken from the input agrees with
the input whatever the materialiser did.

## Demo email

The Nextcloud dashboard's mail widget needs a mail server and an account. The
shared dev environment ships both.

```bash
docker compose -f .github/docker-compose.yml --profile mail up -d greenmail
bash .github/docker/mail/seed-mail.sh localhost 3025

occ app:enable mail
occ mail:account:create admin "Gemeente Demo" admin@test.local \
conduction-greenmail 3143 none admin@test.local admin@test.local \
conduction-greenmail 3025 none admin@test.local admin@test.local
occ mail:account:sync 1
```

Then put the widgets on the dashboard:

```bash
occ user:setting admin dashboard layout \
"procest_my_tasks_widget,procest_task_reminders_widget,mail-unread,procest_overdue_cases_widget,procest_deadline_alerts_widget,procest_cases_overview_widget"
```

The widget ids still carry the `procest_` prefix. Renaming them would drop the
widget out of every layout that already names it, so they stay.

## Code Quality

```bash
Expand Down
74 changes: 71 additions & 3 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Vrij en open source onder de EUPL-1.2-licentie.

**Ondersteuning:** Voor ondersteuning, neem contact op via support@conduction.nl. Voor een Service Level Agreement (SLA), neem contact op via sales@conduction.nl.
]]></description>
<version>0.3.8-unstable.20260831052324</version>
<version>0.3.11-unstable.20260901211251</version>
<licence>EUPL-1.2</licence>
<author mail="info@conduction.nl" homepage="https://www.conduction.nl/">Conduction</author>
<namespace>Dossiq</namespace>
Expand Down Expand Up @@ -128,12 +128,23 @@ Vrij en open source onder de EUPL-1.2-licentie.

<background-jobs>
<job>OCA\Dossiq\BackgroundJob\AdviceDeadlineJob</job>
<job>OCA\Dossiq\BackgroundJob\VergaderingDeadlineJob</job>
<!--
VergaderingDeadlineJob is RETIRED as dead machinery: it scanned
for cases with a literal status 'planned', which case.status
(a statusType reference) can never hold, and the only writer of
such cases was removed earlier. Nothing migrated to a timer.
See openspec/changes/case-status-onto-engine-lifecycle.
-->
<job>OCA\Dossiq\BackgroundJob\WOODeadlineCheckJob</job>
<job>OCA\Dossiq\BackgroundJob\BezwaarTermijnJob</job>
<job>OCA\Dossiq\BackgroundJob\DsoDeadlineJob</job>
<job>OCA\Dossiq\BackgroundJob\ResetMonthlyQuotasJob</job>
<job>OCA\Dossiq\BackgroundJob\DailyDeadlineScanJob</job>
<!--
The daily termijn scan (DailyDeadlineScanJob) is RETIRED: the
OpenRegister FlowTimerWorker sweep fires the armed termijn
timers, and TermijnTimerFiredListener does the domain side.
See openspec/changes/termijnbewaking-op-engine-timers.
-->
<job>OCA\Dossiq\BackgroundJob\InboundEmailJob</job>
<job>OCA\Dossiq\BackgroundJob\EmailPdfRetryJob</job>
<job>OCA\Dossiq\BackgroundJob\SentimentAnalysisJob</job>
Expand Down Expand Up @@ -270,6 +281,21 @@ Vrij en open source onder de EUPL-1.2-licentie.
an install without it keeps working on its local routes.
-->
<step>OCA\Dossiq\Repair\MigrateParafeerroutesToDecidiq</step>
<!--
Re-raises every voorstel still in parafering (in_parafering /
ter_accordering) in the decision app, so the engine that now
owns the runtime has a chain to finish. Runs AFTER
MigrateParafeerroutesToDecidiq: a subject can only travel a
route the decision app already holds. post-migration ONLY —
a fresh install has no in-flight voorstellen. Idempotent (the
decision app leaves a subject that already has stages alone),
and it FAILS rather than no-ops when it can establish no
system identity. The chain resumes from the start there: a
partial local history the retired runtime never sent cannot be
imported, which is the honest cost of moving the runtime after
voorstellen were already travelling.
-->
<step>OCA\Dossiq\Repair\RaiseInFlightParaferingenInDecidiq</step>
<!--
Raises each local bezwaaradviescommissie as a GovernanceBody in
the decision app and notes the id back on the local row.
Expand Down Expand Up @@ -305,6 +331,16 @@ Vrij en open source onder de EUPL-1.2-licentie.
-->
<step>OCA\Dossiq\Repair\RenameDutchDirectionValues</step>
<step>OCA\Dossiq\Repair\MigrateArchivalToOpenRegister</step>
<!--
A ketenpartner is an organisation, and OpenRegister owns
Organisation. This moves the rows BEFORE the Partners settings
page that used to write them is gone, which is why it is a
repair step and not the occ command it also ships as: an
administrator who never ran the command would be left with rows
behind a surface that no longer exists. Idempotent by the
partner's own uuid, so re-running an upgrade adds nothing.
-->
<step>OCA\Dossiq\Repair\MigratePartnersToOrganisations</step>
<step>OCA\Dossiq\Repair\SeedKccWerkplekData</step>
<step>OCA\Dossiq\Repair\BackfillInformatieobjectMetadata</step>
<step>OCA\Dossiq\Repair\LinkInFlightContractDecisionsRepair</step>
Expand Down Expand Up @@ -333,6 +369,24 @@ Vrij en open source onder de EUPL-1.2-licentie.
exists to perform.
-->
<step>OCA\Dossiq\Repair\RenameDutchValues</step>
<!--
dossiq#1596, and it runs immediately AFTER the rename above
because that is the step whose output it repairs.

RenameDutchValues translated ONE member of the LHS actorType
axis (overheid -> government). It could not reach the matrix
cells, which live inside a JSON column rather than a column of
their own, so the vocabulary split down the middle: the
recommendation schema offered `government` while every cell
said `overheid`. A quarter of the national enforcement strategy
became unreachable, and it presented as "Geen LHS-cel gevonden"
— which reads like bad input rather than a broken axis.

The mapping is removed at source, so a fresh instance cannot
acquire this. This step is for the instances that already ran
it, and it is idempotent: a repaired row no longer matches.
-->
<step>OCA\Dossiq\Repair\RealignLhsActorTypeVocabulary</step>
<!--
Hermiq owns the EU AI Act Art. 14 oversight record now, and
dossiq's own oversight page is retired. This replays the
Expand All @@ -355,6 +409,17 @@ Vrij en open source onder de EUPL-1.2-licentie.
already have `bezwaar` are skipped) and non-fatal.
-->
<step>OCA\Dossiq\Repair\BackfillAdviceRequestObjection</step>
<!--
One clock: arms an OpenRegister FlowTimer for every in-flight
TermijnInstance that does not carry one yet (engineTimerId),
suspending the timer for paused rows. Idempotent, skips
terminal rows, and never throws — an unreachable engine is a
warning plus a failed count, not a broken upgrade. Catch-up
rung fires after migration are absorbed by the
notificatiesVerstuurd dedup in TermijnTimerFiredListener.
POST-MIGRATION only: a fresh install has no instances to arm.
-->
<step>OCA\Dossiq\Repair\ArmTermijnEngineTimers</step>
</post-migration>
<!--
FRESH INSTALL. Nextcloud does NOT run post-migration on a first install:
Expand Down Expand Up @@ -445,8 +510,11 @@ Vrij en open source onder de EUPL-1.2-licentie.
<command>OCA\Dossiq\Command\BackfillLegalHoldsCommand</command>
<command>OCA\Dossiq\Command\MigrateAutomaticActionsToFlowsCommand</command>
<command>OCA\Dossiq\Command\MigrateWorkflowDefinitionsToFlowsCommand</command>
<command>OCA\Dossiq\Command\MigrateLhsToDecisionTablesCommand</command>
<command>OCA\Dossiq\Command\MigrateTenantsCommand</command>
<command>OCA\Dossiq\Command\MigratePartnersCommand</command>
<command>OCA\Dossiq\Command\SeedBezwaarBeroepCommand</command>
<command>OCA\Dossiq\Command\SeedDemoCaseloadCommand</command>
</commands>

<settings>
Expand Down
20 changes: 17 additions & 3 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,12 @@
['name' => 'assistant#availability', 'url' => '/api/assistant/availability', 'verb' => 'GET'],
['name' => 'assistant#converse', 'url' => '/api/assistant/converse', 'verb' => 'POST'],

// Parafering Actions (must precede any wildcard routes).
['name' => 'parafeerActie#create', 'url' => '/api/parafeer-actie', 'verb' => 'POST'],
['name' => 'parafeerActie#index', 'url' => '/api/parafeer-actie', 'verb' => 'GET'],
// Parafering actions RETIRED with the local runtime. An approver no
// longer signs through a dossiq endpoint that records-and-advances a
// local chain: the decision app runs the chain (parafering moved there
// the way decisions did), and dossiq records the outcome from the
// conclusion event. The parafeeractie objects the case keeps are
// read through OpenRegister's auto-exposed object API for display.

// KCC Klantcontact (kcc-klantcontact-integratie).
// Static/verb routes precede the {id} wildcard routes.
Expand Down Expand Up @@ -596,6 +599,7 @@

// ── Milestone tracking ───────────────────────────────────────────
['name' => 'milestone#progress', 'url' => '/api/cases/{caseId}/milestones/progress/{caseTypeId}', 'verb' => 'GET'],
['name' => 'milestone#caseProgress', 'url' => '/api/cases/{caseId}/milestones/progress', 'verb' => 'GET'],
['name' => 'milestone#mark', 'url' => '/api/cases/{caseId}/milestones/{milestoneId}/mark', 'verb' => 'POST'],
['name' => 'milestone#reverse', 'url' => '/api/cases/{caseId}/milestones/{milestoneId}/reverse', 'verb' => 'POST'],

Expand Down Expand Up @@ -715,6 +719,7 @@
['name' => 'substitution#revoke', 'url' => '/api/substitutions/{id}/revoke', 'verb' => 'POST'],
['name' => 'caseReassignment#reassignPreview', 'url' => '/api/reassignments/preview', 'verb' => 'POST'],
['name' => 'caseReassignment#reassignExecute', 'url' => '/api/reassignments/execute', 'verb' => 'POST'],
['name' => 'caseReassignment#reassignSelection', 'url' => '/api/reassignments/selection', 'verb' => 'POST'],

// ── Termijnbewaking + dwangsom engine (AWB 4:13/4:14/4:17) ─────────
// Public webhook for openconnector/ERP payment confirmation callbacks.
Expand Down Expand Up @@ -780,6 +785,15 @@
// from a different app is worse than one that stops, because a
// subscriber cannot tell it has moved.

// Case-configuration store (ADR-080). Consume-only: dossiq browses a
// remote OpenRegister registry through AppHost's GenericStoreService and
// installs locally. It never publishes, and it builds no registry URL of
// its own — discovery belongs to the engine.
['name' => 'store#search', 'url' => '/api/store/items', 'verb' => 'GET'],
['name' => 'store#install', 'url' => '/api/store/items/{slug}/install', 'verb' => 'POST', 'requirements' => ['slug' => '[a-z0-9][a-z0-9-]*[a-z0-9]']],
['name' => 'store#getSettings', 'url' => '/api/store/settings', 'verb' => 'GET'],
['name' => 'store#saveSettings', 'url' => '/api/store/settings', 'verb' => 'PUT'],

// NOTE: dashboard#page (`/`) and the SPA catch-all (`/{path}`,
// dashboard#catchAll) are supplied by Routes::standard(); both resolve to
// dossiq's DashboardController, which implements them locally.
Expand Down
8 changes: 5 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
},
"autoload-dev": {
"psr-4": {
"OCA\\OpenRegister\\": "tests/Stubs/"
"OCA\\OpenRegister\\": "tests/Stubs/",
"OCA\\Dossiq\\Tests\\": "tests/"
}
},
"require": {
Expand All @@ -25,7 +26,7 @@
},
"require-dev": {
"conduction/coding-standard": "^1.0",
"conduction/hydra-gates": "^1.8.2",
"conduction/hydra-gates": "^1.11.0",
"cyclonedx/cyclonedx-php-composer": "^6.2",
"edgedesign/phpqa": "^1.27",
"nextcloud/ocp": "^34.0",
Expand Down Expand Up @@ -93,7 +94,8 @@
"optimize-autoloader": true,
"sort-packages": true,
"platform": {
"php": "8.3"
"php": "8.3",
"ext-xsl": "1"
}
}
}
17 changes: 9 additions & 8 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading