Skip to content

chore: dossiq integration batch 24 - #4128

Merged
rubenvdlinde merged 51 commits into
developmentfrom
integration/dq-batch-24
Oct 21, 2026
Merged

rubenvdlinde merged 51 commits into
developmentfrom
integration/dq-batch-24

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Dossiq integration batch 24, on @conduction/nextcloud-vue ^2.119.0 (library batch 24c: macrosFrom, L4 record widgets, L6 dashboards). Every head was merged with --no-ff, with no rebase.

Included

  • R21-DQ-INDEX:
    • fix/r21-lhs-advice-board c80849f
    • fix/r21-tenant-history-title 2b75aa4
    • fix/r21-procurement-portal-accounts-tab b3a5caa
    • fix/r21-list-search-labels b517eb8
  • R21-FEATURES r21/seed-pieter-view a03332d. It needs OpenRegister #4735 at runtime; the dossiq tests read the example set only.
  • CASETABS r20/case-macros-per-type a2b61c3. 2.119.0 ships macrosFrom.
  • L4 feature/dq-abstract-l4-record d60a7a0: the record widgets as library config.
  • L6 feature/dq-abstract-l6-dash f56fece: processing time, process mining, deadline and Woo reports as library dashboards.

Split off to batch 25

  • L7 feature/dq-abstract-l7-rename 38339ee. Its rename commit alone touches 86 files and conflicts in 15, including routes, l10n, the manifest, the registry and the settings tabs. It also carries part of L6. It goes in its own batch on top of this one.

Conflicts

L4 sits on batch 20 and L6 on batch 21. In both cases only the branch's own change is applied over development.

L4:

  • The registry drops every entry and import L4 retires and adds its two dialogs.
  • The work-instruction side card becomes the library facts card and keeps its notTabs.
  • CaseRedaction is counted as retired in the ratchet, because it is now the library redaction page.
  • Specs take L4's removals.

L6:

  • The registry drops the Dt, Td, Pm and WooReports components and adds MailPartiesReportWidget.
  • The lag spec checks both newer schema paths: the redaction page type and the quarter and year filters.
  • The Woo reports spec takes the branch's report page, without the admin switches development had already moved to declared fields.
  • The substituted-work e2e and specs keep development's queue-based state.

After the merges:

  • The l10n catalogues are re-sorted (npm run test:l10n:write) and the JS catalogues rebuilt.
  • Two specs follow L4: simpleListAndDashboard allows a dashboard with no slots, and wooReports drops imports that became unused.

Versions

The macros branch moves the case schema to 1.47.0, caseType to 1.28.0 and the Woo-verzoek case type to 1.4.12. The register moves once, 0.20.62 -> 0.20.63, and the app version is bumped in its own commit.

Verification (local)

  • Revert trap. Every head was diffed against HEAD, file by file:
    • No file a branch deleted came back, and nothing a branch added is missing.
    • The manifest and menu layouts were checked per JSON path, including the case side column, configAppend widgets and the tab strip.
    • Registry keys and imports, and the l10n keys, match each branch.
    • The remaining mismatches are only the hand-resolved files above.
  • composer check:strict: ALL CHECKS PASSED. That covers psalm, phpstan, phpmd and phpcs, plus PHPUnit (9241 tests, no failures).
  • npm run lint: green. npm run test:l10n: OK.
  • vitest with --maxWorkers=2 on the touched specs (39 files, 545 tests) is green after the spec fix.

AI disclosure: Claude Code (claude-opus-5-5) assembled this integration branch.

🤖 Generated with Claude Code

DqZaakAssistent draws the assistant inside the case page, in the
AI-toezicht tab; it was reachable only through the launcher's floating
window. The simple case page gets an AI oversight tab holding the same
AI Chat Companion, embedded through nextcloud-vue's `ai-chat` widget,
with the case as its context and hermiq required. It waits under Acties
with the other panels and joins the strip while open. The hex and the
Assistant sidebar tab stay.

Assisted-by: ClaudeCode:claude-opus-5-5
…e macros

DqZaakAssistent draws the AI-toezicht tab with a table of the
assistant's suggestions on the case, a Macro's card and the chat. The
tab held only the chat. It now stacks an object list over hermiq's
advisory approvals for this case (moment, user, question, outcome,
model), the library macros widget over the case schema's macros, and
the chat. Both sources exist; dossiq does not yet report decisions to
hermiq and the case schema declares no macros, so both cards say so.

Assisted-by: ClaudeCode:claude-opus-5-5
DqZaakAssistent draws the chat in the side column beside the AI-toezicht
panel, not inside it. The tab gets an id, its panel stacks the activity
list and the macros, and the chat moves to the side column with `tabs:
["ai-oversight"]`, so it shows only while that tab is open. It follows
the four generic side cards, which keeps a case type's own side-card
list valid.

Assisted-by: ClaudeCode:claude-opus-5-5
DqZaakAssistent's Macro's card lists "Woo-verzoek afronden" and
"Opschorten voor aanvulling", and the case schema declared no macros.
It now declares both as actions with macro: true, bound by name to two
manual flows it declares: status to Besluit and the Publiceren task;
and the term suspended, then the handler asked to send the message
Aanvullende gegevens. Suspending needed a flow step, so a generic
dossiq.suspendTerm node runs the same pause the Termijn card registers,
under the case type's rules. Every changing step carries a label for
the card's last-run line.

Assisted-by: ClaudeCode:claude-opus-5-5
DqZaakAssistent draws the Assistent card alone beside AI-toezicht, but
the four generic side cards showed beside every tab. They now declare
notTabs ["ai-oversight"] (nextcloud-vue side-card-not-on-tabs) and stand
aside while that tab is open.

Assisted-by: ClaudeCode:claude-opus-5-5
hermiq#1172 makes AI oversight records readable only through their
subject, so the AI-toezicht list reads GET
/apps/hermiq/api/ai-oversight/subject for the case (object-list
endpointSource) instead of the OpenRegister list. It names hermiq's new
unused status "Niet gebruikt" and carries the board's subtitle.

Assisted-by: ClaudeCode:claude-opus-5-5
The case schema declares its macros, so every case type offered every
one: Woo-verzoek afronden on an objection. caseType gets `macros`, the
keys its cases offer in order; the Woo request lists both; and the
Macro's card reads the list through nextcloud-vue macrosFrom. A case
type that lists none offers none.

Assisted-by: ClaudeCode:claude-opus-5-5
The queue-source architecture test lists every flow node that may ask
a person. dossiq.suspendTerm registers a pause and asks nobody; in a
macro the askPerson step after it does the asking. Classified in the
allowlist with that reason.

Assisted-by: ClaudeCode:claude-opus-5-5
The macros and their flows live in the case schema's configuration,
which OpenRegister's importer does not compare, so an instance that
already had 1.45.0 would skip them on import. The version moves and the
digest record is updated.

Assisted-by: ClaudeCode:claude-opus-5-5
Ruben decided who may run the macros: whoever may edit the case. The
two macro actions had no rule of their own, so OpenRegister's default
decided. Each now carries the case's update rule, the same groups and
assignee match, and a test keeps the two equal.

Assisted-by: ClaudeCode:claude-opus-5-5
CaseBannerStack bound only objectId on CaseAttentionPanel. The strip reads
attentionMarkers and riskAssessment off objectData, so on the live case
page neither the markers nor the risk assessment were ever drawn.

Assisted-by: ClaudeCode:claude-opus-5-5
CaseProgrammeSection declared a prop `object`, but CnDetailWidgetHost
binds the loaded case as `objectData`, so the link dialog always got an
empty case title.

Assisted-by: ClaudeCode:claude-opus-5-5
…w widget

dossiq registered DocumentReviewPanel under `document-review`, the key of
nextcloud-vue's library widget (CnDocumentReviewWidget). The app registry
resolves first, so the app key replaced the library widget for any page
of this app asking for it. Register the panel as
`document-relevance-review` and point the case Review tab at it. The
widget id `case-document-review` is unchanged, so saved arrangements and
the menu layout keep finding it.

Assisted-by: ClaudeCode:claude-opus-5-5
…n the server

Add GET /api/reports/processing-time?period&caseType&view&threshold. It
answers the blocks the processing-time dashboard drew from every case,
case type and status loaded into the browser: sla (+ slaSummary),
distribution (+ distributionTarget), trend, throughput, atRisk and
breakdown, each in the shape a chart, stat or object-table widget reads
through responsePath. Rows carry severity and status words beside the
colour keys. A case type filter matches id or slug, `truncated` says the
load hit its limit, and the reporting audience gate refuses everyone else
with its sentence. The unfiltered figures are handed to the OpenRegister
analytics leaf under the existing procest-sla-* keys.

/api/reports/process-mining accepts `period` (preset) and `view`, and
answers the summary, dwell, throughput, bottlenecks and byAssignee blocks
plus the clock-disclosing column labels beside the existing report.

The quarterly deadline report adds `rows`, the per-type figures as a list
named by case-type title, with the penalty total in euros.

The JS shaping specs (doorlooptijdHelpers, doorlooptijdChartShaping,
processMiningShaping, dwellTimeClock) are ported to PHPUnit.

Assisted-by: ClaudeCode:claude-opus-5-5
…s as library widgets

The three report dashboards are now manifest config over chart, stat and
object-table widgets on the server-shaped report endpoints; the dossiq
widget components, their mixins, the shaping modules, the doorlooptijd and
processMining stores and their API clients are deleted.

- Processing time: four charts (compliance by type, distribution, monthly
  trend, weekly throughput) on /api/reports/processing-time, one view
  each. The cases at risk and the deadline list of one case type are the
  same at-risk object-table; the second is narrowed to its case type by
  configuration (id or slug), not by "title contains woo". Severity is a
  translated enum badge, so text sits beside the colour, and rows open the
  case. The breakdown is a sortable table that names each status band.
- Process mining: four stat tiles, a dwell chart, a throughput chart and
  two tables on /api/reports/process-mining views. The duration headings
  and the dwell series name come from the report's `labels`, so they still
  say which clock the numbers are on; the hint sentences are subtitles.
- Deadline reports: the quarterly report is an object-table over the
  report's `rows` with CSV export, percent and euro formats and English
  column text; the annual audit is three stat tiles. Quarter and year are
  page filters.
- The mail parties report is nextcloud-vue's CnCountTablesReport,
  configured in mailPartiesReport.js.
- The substituted-work card on My work is dropped (Ruben, 20 Oct): the
  work queue carries covered work.

The annual audit summary adds totalEuros and warningCount; the at-risk
severity reads "at risk" from fourteen days left, as the deadline list
did. Depends on the unreleased nextcloud-vue branch
feature/dq-abstract-l6-dash (endpoint notices, exportCsv, labelPath,
namePath, quarter/year page filters, CnCountTablesReport).

Assisted-by: ClaudeCode:claude-opus-5-5
…term

Assisted-by: ClaudeCode:claude-opus-5-5
…read on request

The reports page is a dashboard: a date range, the throughput table on
/api/woo/reports/throughput with `loadOn: "request"`, the mail parties
report as a registered CnCountTablesReport widget, and the CSV as a
header link carrying the page's period. The throughput endpoint records
every read on the audit trail of the cases it counts, so the table reads
only when the reader presses Show: a plain visit records nothing.

Each half shows only while its report is offered, read from the new
GET /api/reports/offered (the same answer the menu reads). The throughput
endpoint reads a moment from the date range as the tenant's calendar day.
The custom WooReportsView is deleted.

Assisted-by: ClaudeCode:claude-opus-5-5
The case page's record widgets are declared in the manifest over
nextcloud-vue widgets, and dossiq's sixteen copies are gone:

- banner row: a `sections` widget over a `banner` (archived, on
  @self.archived), a `status-explainer` (/available-transitions) and an
  `attention-flag` (/attention). New-since-you-looked is counted on the
  tabs (`badgeSource: readState`, files and notes) and cleared on open;
  CnDetailPage keeps the read stamp and Mark as unread.
- followers: the header popover only (Ruben, 20 Oct 2026); the People tab
  section and the simple profile's Followers card are gone.
- location map (`map`), parties (`parties`), contact moments in the
  customer record (`record-list` with row actions and an "Also on" line),
  family plan (`sections`: review-due banner and grouped cards),
  related cases (`related` with endpoint sections, the parent and Plan
  follow-up), programme and work instruction (`facts`), Notes tab (the
  notes leaf with mentionUrl and the push action), redaction page
  (`redaction` page type), First today (`banner` naming the first row).
- Widget ids users may have stored are unchanged (family-plan,
  case-pipelinq-contact-moments and the rest); L7 renames them.
- FileContactMomentDialog and LinkProgrammeDialog are registry modals the
  widgets open; both ask the page to refresh on success.
- Helpers only the deleted components used are pruned; the reading moved
  to nextcloud-vue (objectParties, statusDeclaration, fieldRules).
- Specs: the declarations are asserted here
  (recordPageLibraryWidgets and the rewritten specs); the behaviour specs
  moved to the nextcloud-vue widgets. The DQ-BUGS specs for the attention
  strip and the programme title assert the fixed declarations.
- check:manifest treats a page type only the newer schema lists as a
  library lag; the vendored schema is 2.137.0.

Depends on nextcloud-vue feature/dq-abstract-l4-record and
feature/dq-abstract-l4-record-b (unreleased): with the installed 2.114.0
one spec, the note push, waits for that release.

Assisted-by: ClaudeCode:claude-opus-5-5
…tract-l4-record

# Conflicts:
#	src/components/case/CaseBannerStack.vue
#	src/components/case/CaseProgrammeSection.vue
#	tests/vitest/caseBannerStackAttention.spec.js
#	tests/vitest/caseProgrammeCaseTitle.spec.js
…ma 2.138.0

The reports page's header link drops its `_note`, which $defs/action
refuses. The validator now also asks the vendored newer schema about a
path when the installed one refuses a value or an anyOf branch there (the
generated quarter and year page filters): with nothing refused near that
path in the newer schema, the error is the library lagging. The vendored
schema is the nextcloud-vue branch's 2.138.0, ahead of the installed
2.136.0 until that release lands.

Assisted-by: ClaudeCode:claude-opus-5-5
…ue schema 2.139.0; vendor it

Assisted-by: ClaudeCode:claude-opus-5-5
…tract-l6-dash

# Conflicts:
#	src/registry.js
#	tests/schemas/app-manifest-v2.schema.json
Conflicts resolved: the AI oversight tab, its widgets and the case page
spec keep this branch's version (development carried an earlier form of
the same tab); the l10n catalogues keep both sides' keys; the schema
digests are regenerated. Versions renumbered past development's: the
case schema to 1.47.0, caseType to 1.28.0 (the macros fragment renamed
to 99-case-type-which-macros.json so it merges last), the Woo case type
seed to 1.4.12.

Assisted-by: ClaudeCode:claude-opus-5-5
The saved-view boards (DqFilterBeheren, -Bewerken, -Delen, -InMenu,
-Verwijderen) draw the case list's side panel on Weergaven with the
reader's own views and their row menu: edit, share, add to the menu,
delete. That menu exists only on a view the reader owns, and the example
data gave the boards' handler none.

The Zuiddrecht set now gives him "Termijn deze week": his open cases with
a deadline within seven days, sorted on deadline, scoped to the case
list. Its conditions are the shipped default view "Mine, due this week",
so it names no status or case type id. Needs OpenRegister's example-set
views and Pieter in the cast (openregister r21/cast-pieter). Sharing and
the menu entry are not seeded: an example-set view writes name,
description, owner, isPublic, query, presentation and alert only.

Assisted-by: ClaudeCode:claude-opus-5-5
The enforcement advice page drew a Follow toggle the board does not, put
the recommendation and the deviation as full-width data panels where the
board has side cards, and titled its history card Geschiedenis where the
board and the other record pages say Historie.

- follow: false on LhsRecommendationDetail
- Aanbeveling and Afwijking en definitief become side cards with every
  field the panels showed; deviating stays the header's edit action
- the main column holds the matrix and the violation
- the history card uses "Record history" (nl Historie)

Assisted-by: ClaudeCode:claude-opus-5-5
Board DqTenant titles the side card Historie, as the contact and
organisation record pages do; the organisation page used "History",
which reads Geschiedenis in Dutch.

Assisted-by: ClaudeCode:claude-opus-5-5
… set of tabs

Board DqContracten draws Contracten | Leveranciers | Portaalaccounts.
The procurement pages now link the supplier portal accounts as a third
tab, shown to an admin only and without a count there (the library still
requests a hidden tab's count). The accounts page gets the same three
tabs; it stays admin-only on its own.

Assisted-by: ClaudeCode:claude-opus-5-5
…ktypen

The simple profile's task list searched "Zoeken..." and headed its due
column Termijn; board DqTaken says "Zoek op taak of zaaknummer" and
Deadline. The case type list searched "Zoeken in deze lijst"; board
DqZaaktypen says "Zoek een zaaktype".

Assisted-by: ClaudeCode:claude-opus-5-5
…ion/dq-batch-24

The branch sits on batch 20, so its one new commit (842971a, the record
widgets as library config) is applied over batches 21 to 23:
- the registry drops every entry and import the branch retires and adds its
  two dialogs;
- the work-instruction side card becomes the library facts card and keeps
  its notTabs from the AI oversight tab;
- the ratchet counts CaseRedaction as retired (the library redaction page);
- the specs take the branch's removals over development's state;
- the JS catalogues are rebuilt from the merged JSON.

# Conflicts:
#	l10n/en.js
#	l10n/nl.js
#	src/menu-layout.simple.json
#	src/registry.js
#	tests/l10n/language-neutral-keys.json
#	tests/schemas/app-manifest-v2.schema.json
#	tests/vitest/caseTabConsolidation.spec.js
#	tests/vitest/gemachtigdeRole.spec.js
#	tests/vitest/manifestCaseTaskPane.spec.js
#	tests/vitest/simpleCasePage.spec.js
…n/dq-batch-24

The branch sits on batch 21, so its dashboards are applied over batches 22
and 23:
- the registry drops the processing-time, deadline, process-mining and Woo
  report components and adds the mail parties report widget;
- the lag spec asks about both newer schema paths, the redaction page type
  (L4) and the generated quarter and year filters (this branch);
- the Woo reports spec takes the branch's report page over development's,
  without the admin switches development already moved to declared fields;
- the substituted-work e2e and specs keep development's state: covered work
  already lists in the personal queue, and substitutedWorkOnMyWork.spec.js
  stays deleted.

# Conflicts:
#	src/registry.js
#	tests/e2e/spec-coverage/handler-vervanging-waarneming.spec.ts
#	tests/schemas/app-manifest-v2.schema.json
#	tests/vitest/listViewOverrides.spec.js
#	tests/vitest/substitutedWorkOnMyWork.spec.js
#	tests/vitest/validateManifestLag.spec.js
#	tests/vitest/wooReports.spec.js
Syncs the vendored manifest schema to the installed one for the lag check.

Assisted-by: ClaudeCode:claude-opus-5-5
The macros branch moves the case schema to 1.47.0, caseType to 1.28.0 and the
Woo-verzoek case type to 1.4.12, so the register moves once over
development's 0.20.62.

Assisted-by: ClaudeCode:claude-opus-5-5
The batch's merges appended keys out of order; npm run test:l10n:write sorts
them (no key added or dropped) and the JS catalogues are rebuilt.

Assisted-by: ClaudeCode:claude-opus-5-5
feature/dq-abstract-l4-record moves First today onto the library banner, the
last slot the simple dashboard named, so its slots map can be absent.

Assisted-by: ClaudeCode:claude-opus-5-5
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/dossiq @ 9cce52b

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 ✅
check-debt-ratchet ❌
check-types-e2e ✅
composer ✅ ✅ 109/109
npm ✅ ✅ 658/658
app:check-code ⏭️
info.xml ✅
REUSE ❌
lockfile sync ✅
PHPUnit ❌ 9238/9238 · 3 skipped (no test failed, the job failed for another reason — see its log)
Newman ⏭️
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ❌

Quality workflow — 2026-10-21 06:56 UTC

Download the full PDF report from the workflow artifacts.

… components

Development held 104 registry entries; this batch retires 28 (the L4 record
widgets and the L6 report dashboards, now library config) and adds 3, so 79
remain. Every name the manifests still use resolves (the registers-every-name
case passes), and none of the retired keys is a type, component, handler,
widget or target in any manifest.

Assisted-by: ClaudeCode:claude-opus-5-5
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/dossiq @ 844dc13

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 ✅
check-debt-ratchet ❌
check-types-e2e ✅
composer ✅ ✅ 109/109
npm ✅ ✅ 658/658
app:check-code ⏭️
info.xml ✅
REUSE ❌
lockfile sync ✅
PHPUnit ❌ 9238/9238 · 3 skipped (no test failed, the job failed for another reason — see its log)
Newman ⏭️
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ❌

Quality workflow — 2026-10-21 07:13 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit ae7ba59 into development Oct 21, 2026
44 of 50 checks passed
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