From 88cd0c34d047731e9a3cac94aa962fb8a357f7a5 Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Fri, 4 Sep 2026 07:35:05 +0200 Subject: [PATCH 1/7] fix(jsdoc): merge the orphaned @spec docblocks that were shadowing the real ones 166 functions carried TWO stacked JSDoc blocks: a complete one, and directly beneath it a bare stub that existed only to hold `@spec` and repeated every parameter with no type and no description. JSDoc takes the NEAREST preceding block, so the stub won. The real documentation was invisible to every tool that reads it, and eslint reported each parameter as undocumented. That is 527 of the repo's 823 warnings, and none of them described a missing description: they described a block nobody could see past. The `@spec` line moves into the real block and the stub goes. 599 deletions, zero insertions, because the tag simply ends up inside the block above it. Warnings 823 -> 296, eslint exits 0 (the suppressions file is pruned; entries for warnings that no longer occur are a hard error, not a warning). Two sites are left alone: their stub named a parameter the real block does not document, so merging would have silently dropped it. Those need a human. The script refused anything it could not prove safe, and the check that mattered was counting `@spec` before and after. An earlier revision of it LOST SEVEN TAGS: the pattern for the first block was not anchored, so it swallowed every earlier docblock in the file, and the "is this tag already present" test then matched a different function's `@spec`. The diff looked correct because the swallowed text was written back unchanged. Only the tally (1760 before, 1753 after) showed it. --- eslint-suppressions.json | 9 +- src/App.vue | 3 - src/services/adviceApi.js | 10 -- src/services/aiApi.js | 29 ---- src/services/mapFormatters.js | 9 -- src/services/pdokService.js | 20 --- src/services/taskApi.js | 11 -- src/store/modules/advice.js | 28 ---- src/store/modules/bezwaar.js | 48 ------ src/store/modules/enforcement.js | 33 ---- src/store/modules/inspection.js | 36 ----- src/store/modules/workflow.js | 141 ------------------ src/utils/caseHelpers.js | 36 ----- src/utils/caseTypeValidation.js | 7 - src/utils/caseValidation.js | 18 --- src/utils/dashboardHelpers.js | 43 ------ src/utils/decisionHelpers.js | 9 -- src/utils/doorlooptijdHelpers.js | 31 ---- src/utils/durationHelpers.js | 12 -- src/utils/i18nResolver.js | 15 -- src/utils/taskHelpers.js | 18 --- src/utils/taskLifecycle.js | 16 -- src/utils/taskValidation.js | 10 -- src/views/settings/WorkflowEditor.vue | 13 -- .../settings/components/WorkflowNode.vue | 3 - 25 files changed, 2 insertions(+), 606 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 5567f2ef7..06270f2a0 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -1,9 +1,4 @@ { - "src/App.vue": { - "jsdoc/require-param-type": { - "count": 1 - } - }, "src/components/InspectionChecklistEditor.vue": { "@nextcloud/l10n-enforce-ellipsis": { "count": 1 @@ -698,7 +693,7 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 25 + "count": 20 } }, "src/views/settings/ZgwMappingSettings.vue": { @@ -781,7 +776,7 @@ }, "src/views/settings/components/WorkflowNode.vue": { "jsdoc/require-param-type": { - "count": 7 + "count": 6 }, "vue/custom-event-name-casing": { "count": 12 diff --git a/src/App.vue b/src/App.vue index b64544127..2f85677f4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -175,9 +175,6 @@ export default { * * @param {string} key Translation key. * @return {string} Translated string (or the key on miss). - */ - /** - * @param key * @spec openspec/changes/retrofit-2026-05-25-procest-app-scaffold/tasks.md */ translateForApp(key) { diff --git a/src/services/adviceApi.js b/src/services/adviceApi.js index 900cca37b..d1f2161de 100644 --- a/src/services/adviceApi.js +++ b/src/services/adviceApi.js @@ -51,9 +51,6 @@ function actionUrl(path) { * * @param {string} caseId Case UUID * @return {Promise} List of advice records - */ -/** - * @param caseId * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ export async function getAdviceForCase(caseId) { @@ -85,10 +82,6 @@ export async function getAdviceForCase(caseId) { * @param {string} id Advice UUID * @param {object} body Transition payload (to, adviesDocument, ...) * @return {Promise} Updated record - */ -/** - * @param id - * @param body * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ export async function transitionStatus(id, body) { @@ -101,9 +94,6 @@ export async function transitionStatus(id, body) { * * @param {string} id Advice UUID * @return {Promise} Server confirmation - */ -/** - * @param id * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ export async function dispatchReminder(id) { diff --git a/src/services/aiApi.js b/src/services/aiApi.js index 1f73be8f0..a2404f77f 100644 --- a/src/services/aiApi.js +++ b/src/services/aiApi.js @@ -15,10 +15,6 @@ const baseUrl = generateUrl('/apps/dossiq/api/ai') * @param {string} caseId The case UUID * @param {string} documentId The document UUID * @return {Promise} Classification suggestion with confidence - */ -/** - * @param caseId - * @param documentId * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function classifyDocument(caseId, documentId) { @@ -32,10 +28,6 @@ export async function classifyDocument(caseId, documentId) { * @param {string} caseId The case UUID * @param {string|null} documentId Optional document UUID * @return {Promise} Extracted fields with confidence scores - */ -/** - * @param caseId - * @param documentId * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function extractData(caseId, documentId = null) { @@ -49,10 +41,6 @@ export async function extractData(caseId, documentId = null) { * @param {string} caseId The case UUID * @param {string} question The question to ask * @return {Promise} Answer with source citations - */ -/** - * @param caseId - * @param question * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function askQuestion(caseId, question) { @@ -67,11 +55,6 @@ export async function askQuestion(caseId, question) { * @param {string} type Summary type: case, document, or timeline * @param {string|null} documentId Optional document UUID * @return {Promise} Generated summary - */ -/** - * @param caseId - * @param type - * @param documentId * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function summarize(caseId, type = 'case', documentId = null) { @@ -88,9 +71,6 @@ export async function summarize(caseId, type = 'case', documentId = null) { * * @param {string} caseId The case UUID * @return {Promise} Routing suggestion - */ -/** - * @param caseId * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function suggestRouting(caseId) { @@ -103,9 +83,6 @@ export async function suggestRouting(caseId) { * * @param {string} caseId The case UUID * @return {Promise} Next-step suggestion - */ -/** - * @param caseId * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function suggestNext(caseId) { @@ -118,9 +95,6 @@ export async function suggestNext(caseId) { * * @param {object} filters Query filters (caseId, type, limit, offset) * @return {Promise} Audit log entries - */ -/** - * @param filters * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function getAuditLog(filters = {}) { @@ -144,9 +118,6 @@ export async function getAiSettings() { * * @param {object} settings Settings to update * @return {Promise} Updated settings - */ -/** - * @param settings * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ export async function updateAiSettings(settings) { diff --git a/src/services/mapFormatters.js b/src/services/mapFormatters.js index 9aade4fe0..1db703e25 100644 --- a/src/services/mapFormatters.js +++ b/src/services/mapFormatters.js @@ -26,9 +26,6 @@ * * @param {string} status The case status. * @return {string} CSS variable reference. - */ -/** - * @param status * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ export function statusColor(status) { @@ -51,9 +48,6 @@ export function statusColor(status) { * * @param {string} status The case status. * @return {string} Icon glyph name. - */ -/** - * @param status * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ export function statusIcon(status) { @@ -133,9 +127,6 @@ function extractCoords(geometry) { * * @param {object} caseObj Case object from OpenRegister. * @return {object|null} Marker descriptor or `null` if no geometry. - */ -/** - * @param caseObj * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ export function caseMarkerFormatter(caseObj) { diff --git a/src/services/pdokService.js b/src/services/pdokService.js index 8902beb41..44298006b 100644 --- a/src/services/pdokService.js +++ b/src/services/pdokService.js @@ -90,9 +90,6 @@ function handleNetworkError(error, fallback) { * * @param {string} query Search query (min 3 characters). * @return {Promise} Suggestions array, empty array, or null. - */ -/** - * @param query * @spec openspec/changes/retrofit-2026-05-25-pdok-integration/tasks.md */ export async function suggest(query) { @@ -124,9 +121,6 @@ export async function suggest(query) { * * @param {string} id The PDOK object id. * @return {Promise} The full result object, or null when degraded. - */ -/** - * @param id * @spec openspec/changes/retrofit-2026-05-25-pdok-integration/tasks.md */ export async function lookup(id) { @@ -148,10 +142,6 @@ export async function lookup(id) { * @param {string} query Search query. * @param {number} rows Max results (default 10). * @return {Promise} Results array, empty array, or null. - */ -/** - * @param query - * @param rows * @spec openspec/changes/retrofit-2026-05-25-pdok-integration/tasks.md */ export async function free(query, rows = 10) { @@ -175,10 +165,6 @@ export async function free(query, rows = 10) { * @param {number} lat Latitude (WGS84). * @param {number} lng Longitude (WGS84). * @return {Promise} Nearest address, or null when degraded. - */ -/** - * @param lat - * @param lng * @spec openspec/changes/retrofit-2026-05-25-pdok-integration/tasks.md */ export async function reverse(lat, lng) { @@ -204,9 +190,6 @@ export async function reverse(lat, lng) { * * @param {object|string} resultOrWkt A PDOK result object or a raw WKT string. * @return {{ lat: number, lng: number }|null} Coordinates or null. - */ -/** - * @param resultOrWkt * @spec openspec/changes/retrofit-2026-05-25-pdok-integration/tasks.md */ export function extractCoordinates(resultOrWkt) { @@ -251,9 +234,6 @@ function parseWkt(wkt) { * * @param {object} result A result object. * @return {string} Formatted address. - */ -/** - * @param result * @spec openspec/changes/retrofit-2026-05-25-pdok-integration/tasks.md */ export function formatAddress(result) { diff --git a/src/services/taskApi.js b/src/services/taskApi.js index efcf94b34..af47f292f 100644 --- a/src/services/taskApi.js +++ b/src/services/taskApi.js @@ -43,9 +43,6 @@ function mapCalDavPriority(icalPriority) { * * @param {object} task CalDAV task object from API * @return {object} Normalized work item - */ -/** - * @param task * @spec openspec/specs/task-management/spec.md */ export function normalizeCalDavTask(task) { @@ -102,11 +99,6 @@ export function normalizeCalDavTask(task) { * @param {string|number} schemaId The schema (schema ID) * @param {string} objectId The object UUID * @return {Promise} Array of normalized task work items - */ -/** - * @param registerId - * @param schemaId - * @param objectId * @spec openspec/specs/task-management/spec.md */ export async function fetchTasksForObject(registerId, schemaId, objectId) { @@ -140,9 +132,6 @@ export async function fetchTasksForObject(registerId, schemaId, objectId) { * * @param {object[]} cases Array of case objects (must have id property) * @return {Promise} Array of normalized task work items - */ -/** - * @param cases * @spec openspec/specs/task-management/spec.md */ export async function fetchTasksForCases(cases) { diff --git a/src/store/modules/advice.js b/src/store/modules/advice.js index 03f2a02fe..ab5b6202d 100644 --- a/src/store/modules/advice.js +++ b/src/store/modules/advice.js @@ -23,9 +23,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {object} state Store state * @return {Array} Pending requests - */ - /** - * @param state * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ pendingRequests(state) { @@ -37,9 +34,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {object} state Store state * @return {Array} Overdue requests - */ - /** - * @param state * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ overdueRequests(state) { @@ -57,9 +51,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {object} state Store state * @return {Array} Received requests - */ - /** - * @param state * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ receivedRequests(state) { @@ -71,9 +62,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {object} state Store state * @return {boolean} True if all received - */ - /** - * @param state * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ allAdviceReceived(state) { @@ -92,9 +80,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {string} caseId UUID of the case * @return {Promise} Advice requests - */ - /** - * @param caseId * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ async fetchRequests(caseId) { @@ -125,9 +110,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {object} requestData The request data * @return {Promise} Created request - */ - /** - * @param requestData * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ async createRequest(requestData) { @@ -170,10 +152,6 @@ export const useAdviceStore = defineStore('advice', { * @param {string} requestId UUID of the request * @param {string} documentId Nextcloud file ID of the advice document * @return {Promise} Updated request - */ - /** - * @param requestId - * @param documentId * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ async markReceived(requestId, documentId) { @@ -210,9 +188,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {string} requestId UUID of the request * @return {Promise} Updated request - */ - /** - * @param requestId * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ async markExpired(requestId) { @@ -255,9 +230,6 @@ export const useAdviceStore = defineStore('advice', { * * @param {object} request The advice request * @return {number} Positive = days remaining, negative = days overdue - */ - /** - * @param request * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ getDaysToDeadline(request) { diff --git a/src/store/modules/bezwaar.js b/src/store/modules/bezwaar.js index a011e714c..3194a44b6 100644 --- a/src/store/modules/bezwaar.js +++ b/src/store/modules/bezwaar.js @@ -128,9 +128,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {string} caseId The case UUID * @return {Promise} - */ - /** - * @param caseId * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async loadBezwaarData(caseId) { @@ -187,9 +184,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The objection data * @return {Promise} The created objection - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async createObjection(data) { @@ -215,9 +209,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The updated objection data * @return {Promise} The updated objection - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async updateObjection(data) { @@ -243,9 +234,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {string} objectionId The objection UUID * @return {Promise} Whether the deletion succeeded - */ - /** - * @param objectionId * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async deleteObjection(objectionId) { @@ -273,9 +261,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The hearing session data * @return {Promise} The created hearing - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async createHearingSession(data) { @@ -301,9 +286,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The updated hearing data * @return {Promise} The updated hearing - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async updateHearingSession(data) { @@ -336,9 +318,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The advisory report data * @return {Promise} The created report - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async createAdvisoryReport(data) { @@ -364,9 +343,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The updated report data * @return {Promise} The updated report - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async updateAdvisoryReport(data) { @@ -394,9 +370,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The appeal decision data * @return {Promise} The created decision - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async createAppealDecision(data) { @@ -422,9 +395,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {object} data The updated decision data * @return {Promise} The updated decision - */ - /** - * @param data * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async updateAppealDecision(data) { @@ -452,9 +422,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {string} ontvangstDatum The date the bezwaarschrift was received (ISO string) * @return {object} Calculated deadlines - */ - /** - * @param ontvangstDatum * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ calculateDeadlines(ontvangstDatum) { @@ -486,9 +453,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * * @param {string} currentDeadline The current deadline (ISO string) * @return {string} The new extended deadline (ISO date string) - */ - /** - * @param currentDeadline * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ calculateExtendedDeadline(currentDeadline) { @@ -503,10 +467,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * @param {string} deadline The deadline date (ISO string) * @param {boolean} isSuspended Whether the deadline is currently suspended * @return {object} Deadline status with daysRemaining, isAtRisk, isOverdue - */ - /** - * @param deadline - * @param isSuspended * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ getDeadlineStatus(deadline, isSuspended = false) { @@ -555,10 +515,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * @param {object} bezwaarCase The bezwaar case data * @param {object} options Additional options (voorzieningRequested) * @return {Promise} The created beroep case - */ - /** - * @param bezwaarCase - * @param options * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ async escalateToBeroep(bezwaarCase, options = {}) { @@ -609,10 +565,6 @@ export const useBezwaarStore = defineStore('objectionProceeding', { * @param {string} besluitDate The date the original besluit was published * @param {string} bezwaarReceivedDate The date the bezwaar was received * @return {object} Timeliness assessment - */ - /** - * @param besluitDate - * @param bezwaarReceivedDate * @spec openspec/changes/retrofit-2026-05-24-bezwaar-lifecycle/tasks.md */ checkTimeliness(besluitDate, bezwaarReceivedDate) { diff --git a/src/store/modules/enforcement.js b/src/store/modules/enforcement.js index 2113d468e..801bd3ecb 100644 --- a/src/store/modules/enforcement.js +++ b/src/store/modules/enforcement.js @@ -52,9 +52,6 @@ export const useEnforcementStore = defineStore('enforcement', { * * @param {object} state Store state * @return {object|null} Active action - */ - /** - * @param state * @spec openspec/specs/vth-module/spec.md */ activeAction(state) { @@ -66,9 +63,6 @@ export const useEnforcementStore = defineStore('enforcement', { * * @param {object} state Store state * @return {number} Total verbeurd amount - */ - /** - * @param state * @spec openspec/specs/vth-module/spec.md */ totalVerbeurd(state) { @@ -82,9 +76,6 @@ export const useEnforcementStore = defineStore('enforcement', { * * @param {object} state Store state * @return {Array} Ernst levels - */ - /** - * @param state * @spec openspec/specs/vth-module/spec.md */ ernstLevels(state) { @@ -96,9 +87,6 @@ export const useEnforcementStore = defineStore('enforcement', { * * @param {object} state Store state * @return {Array} Gedrag levels - */ - /** - * @param state * @spec openspec/specs/vth-module/spec.md */ gedragLevels(state) { @@ -113,9 +101,6 @@ export const useEnforcementStore = defineStore('enforcement', { * * @param {string} caseId UUID of the case * @return {Promise} Actions - */ - /** - * @param caseId * @spec openspec/specs/vth-module/spec.md */ async fetchActions(caseId) { @@ -147,10 +132,6 @@ export const useEnforcementStore = defineStore('enforcement', { * @param {string} ernst Severity level (gering/aanzienlijk/ernstig) * @param {string} gedrag Behavior type (goedwillend/onverschillig/calculerend/crimineel) * @return {string|null} Suggested intervention - */ - /** - * @param ernst - * @param gedrag * @spec openspec/specs/vth-module/spec.md */ lookupLhs(ernst, gedrag) { @@ -200,9 +181,6 @@ export const useEnforcementStore = defineStore('enforcement', { * * @param {object} matrix The matrix to save * @return {Promise} Success - */ - /** - * @param matrix * @spec openspec/specs/vth-module/spec.md */ async saveLhsMatrix(matrix) { @@ -232,9 +210,6 @@ export const useEnforcementStore = defineStore('enforcement', { * * @param {object} actionData The action data * @return {Promise} Created action - */ - /** - * @param actionData * @spec openspec/specs/vth-module/spec.md */ async createAction(actionData) { @@ -275,10 +250,6 @@ export const useEnforcementStore = defineStore('enforcement', { * @param {string} actionId UUID of the action * @param {string} newStatus New status (verbeurd/geeffectueerd/ingetrokken) * @return {Promise} Updated action - */ - /** - * @param actionId - * @param newStatus * @spec openspec/specs/vth-module/spec.md */ async updateStatus(actionId, newStatus) { @@ -314,10 +285,6 @@ export const useEnforcementStore = defineStore('enforcement', { * @param {string} caseId UUID of the case * @param {object} action The enforcement action * @return {Promise} Created task - */ - /** - * @param caseId - * @param action * @spec openspec/specs/vth-module/spec.md */ async createBegunstigingTask(caseId, action) { diff --git a/src/store/modules/inspection.js b/src/store/modules/inspection.js index fc0de6187..ff5d332cb 100644 --- a/src/store/modules/inspection.js +++ b/src/store/modules/inspection.js @@ -27,9 +27,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {object} state Store state * @return {Array} Active checklists - */ - /** - * @param state * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ activeChecklists(state) { @@ -41,9 +38,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {object} state Store state * @return {number} Number of completed reports - */ - /** - * @param state * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ completedReportsCount(state) { @@ -55,9 +49,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {object} state Store state * @return {Array} Reports with failed items - */ - /** - * @param state * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ nonConformReports(state) { @@ -73,9 +64,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {string} caseTypeId UUID of the case type * @return {Promise} Checklists - */ - /** - * @param caseTypeId * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async fetchChecklists(caseTypeId) { @@ -106,9 +94,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {object} checklistData The checklist data * @return {Promise} Saved checklist - */ - /** - * @param checklistData * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async saveChecklist(checklistData) { @@ -142,9 +127,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {object} checklist The checklist to version * @return {Promise} New version - */ - /** - * @param checklist * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async createNewVersion(checklist) { @@ -166,9 +148,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {string} checklistId UUID of the checklist * @return {Promise} Success - */ - /** - * @param checklistId * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async deleteChecklist(checklistId) { @@ -191,9 +170,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {string} caseId UUID of the case * @return {Promise} Reports - */ - /** - * @param caseId * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async fetchReports(caseId) { @@ -224,9 +200,6 @@ export const useInspectionStore = defineStore('inspection', { * * @param {object} reportData Report data with items array * @return {Promise} Created report - */ - /** - * @param reportData * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async createReport(reportData) { @@ -293,10 +266,6 @@ export const useInspectionStore = defineStore('inspection', { * @param {string} caseId UUID of the parent case * @param {File} file The photo file * @return {Promise} Nextcloud file ID - */ - /** - * @param caseId - * @param file * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async uploadPhoto(caseId, file) { @@ -324,11 +293,6 @@ export const useInspectionStore = defineStore('inspection', { * @param {number} failedCount Number of failed items * @param {string} reportId UUID of the inspection report * @return {Promise} Created task - */ - /** - * @param caseId - * @param failedCount - * @param reportId * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ async createFollowUpTask(caseId, failedCount, reportId) { diff --git a/src/store/modules/workflow.js b/src/store/modules/workflow.js index 0fe1dc687..210cc900b 100644 --- a/src/store/modules/workflow.js +++ b/src/store/modules/workflow.js @@ -118,9 +118,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {string} caseTypeId UUID of the case type * @return {Promise} Array of workflow templates - */ - /** - * @param caseTypeId * @spec openspec/specs/workflow-definition-model/spec.md */ async listVersions(caseTypeId) { @@ -151,9 +148,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {string} templateId UUID of the workflow template * @return {Promise} The workflow template or null - */ - /** - * @param templateId * @spec openspec/specs/workflow-definition-model/spec.md */ async getTemplate(templateId) { @@ -180,9 +174,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {string} caseTypeId UUID of the case type * @return {Promise} The active workflow template or null - */ - /** - * @param caseTypeId * @spec openspec/specs/workflow-definition-model/spec.md */ async getActiveVersion(caseTypeId) { @@ -215,10 +206,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {string} caseTypeId UUID of the case type * @param {string} title Name of the workflow * @return {Promise} The created template or null - */ - /** - * @param caseTypeId - * @param title * @spec openspec/specs/workflow-definition-model/spec.md */ async createTemplate(caseTypeId, title) { @@ -251,9 +238,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {object} templateData The template data to save * @return {Promise} The saved template or null - */ - /** - * @param templateData * @spec openspec/specs/workflow-definition-model/spec.md */ async saveTemplate(templateData) { @@ -288,9 +272,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {string} templateId UUID of the template * @return {Promise} Success - */ - /** - * @param templateId * @spec openspec/specs/workflow-definition-model/spec.md */ async deleteTemplate(templateId) { @@ -333,10 +314,6 @@ export const useWorkflowStore = defineStore('workflow', { * (`WorkflowTab.vue::publish()`) already validates via the editor's * `validate()` before invoking this action. * @return {Promise} The published template or null - */ - /** - * @param templateId - * @param statusNodes * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-publish-uses-the-canonical-write-path */ async publishVersion(templateId, statusNodes = []) { @@ -390,9 +367,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {string} sourceTemplateId UUID of the source template * @return {Promise} The new draft version or null - */ - /** - * @param sourceTemplateId * @spec openspec/specs/workflow-definition-model/spec.md */ async createDraftFromVersion(sourceTemplateId) { @@ -449,13 +423,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {Array} caseTasks Tasks linked to this case * @param {Array} caseDocuments Documents linked to this case * @return {Array} Available transitions with guard status - */ - /** - * @param caseData - * @param userRoles - * @param workflow - * @param caseTasks - * @param caseDocuments * @spec openspec/specs/workflow-definition-model/spec.md */ computeAvailableTransitions( @@ -538,14 +505,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {Array} steps Workflow steps * @param {string} currentStatus Current status UUID * @return {Array} Array of {met: boolean, message: string} - */ - /** - * @param guards - * @param caseData - * @param caseTasks - * @param caseDocuments - * @param steps - * @param currentStatus * @spec openspec/specs/workflow-definition-model/spec.md */ evaluateGuards( @@ -582,10 +541,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} guard The checklist guard definition * @param {Array} caseTasks Tasks linked to the case * @return {object} {met: boolean, message: string} - */ - /** - * @param guard - * @param caseTasks * @spec openspec/specs/workflow-definition-model/spec.md */ evaluateChecklistGuard(guard, caseTasks) { @@ -629,10 +584,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} guard The required field guard definition * @param {object} caseData The case object * @return {object} {met: boolean, message: string} - */ - /** - * @param guard - * @param caseData * @spec openspec/specs/workflow-definition-model/spec.md */ evaluateRequiredFieldGuard(guard, caseData) { @@ -655,10 +606,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} guard The required document guard definition * @param {Array} caseDocuments Documents linked to the case * @return {object} {met: boolean, message: string} - */ - /** - * @param guard - * @param caseDocuments * @spec openspec/specs/workflow-definition-model/spec.md */ evaluateRequiredDocumentGuard(guard, caseDocuments) { @@ -685,11 +632,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {string} currentStatus Current status UUID * @param {Array} caseTasks Tasks linked to the case * @return {object} {met: boolean, messages: Array} - */ - /** - * @param steps - * @param currentStatus - * @param caseTasks * @spec openspec/specs/workflow-definition-model/spec.md */ evaluateRequiredSteps(steps, currentStatus, caseTasks) { @@ -726,11 +668,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} caseData The case object * @param {object} transition The transition that triggered the actions * @return {Promise} Array of {action, success, error} results - */ - /** - * @param actions - * @param caseData - * @param transition * @spec openspec/specs/workflow-definition-model/spec.md */ async dispatchActions(actions, caseData, transition) { @@ -796,11 +733,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} caseData The case object * @param {object} transition The transition context * @return {Promise} - */ - /** - * @param action - * @param caseData - * @param transition * @spec openspec/specs/workflow-definition-model/spec.md */ async dispatchEmailAction(action, caseData, transition) { @@ -844,10 +776,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} action The task creation action * @param {object} caseData The case object * @return {Promise} - */ - /** - * @param action - * @param caseData * @spec openspec/specs/workflow-definition-model/spec.md */ async dispatchCreateTaskAction(action, caseData) { @@ -868,10 +796,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} action The sub-case creation action * @param {object} caseData The parent case object * @return {Promise} - */ - /** - * @param action - * @param caseData * @spec openspec/specs/workflow-definition-model/spec.md */ async dispatchCreateSubCaseAction(action, caseData) { @@ -895,11 +819,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} caseData The case object * @param {object} transition The transition context * @return {Promise} - */ - /** - * @param action - * @param caseData - * @param transition * @spec openspec/specs/workflow-definition-model/spec.md */ async dispatchWebhookAction(action, caseData, transition) { @@ -938,10 +857,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} action The setField action * @param {object} caseData The case object * @return {Promise} - */ - /** - * @param action - * @param caseData * @spec openspec/specs/workflow-definition-model/spec.md */ async dispatchSetFieldAction(action, caseData) { @@ -958,10 +873,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} action The notify action * @param {object} caseData The case object * @return {Promise} - */ - /** - * @param action - * @param caseData * @spec openspec/specs/workflow-definition-model/spec.md */ async dispatchNotifyAction(action, caseData) { @@ -994,11 +905,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {object} caseData The case object * @param {object} transition The transition context (optional) * @return {string} Interpolated string - */ - /** - * @param template - * @param caseData - * @param transition * @spec openspec/specs/workflow-definition-model/spec.md */ interpolateTemplate(template, caseData, transition) { @@ -1034,9 +940,6 @@ export const useWorkflowStore = defineStore('workflow', { * it through; defaults to [] which yields no NO_FINAL_STATUS-style * findings (nothing to validate against yet). * @return {Array} Array of {type, code, message} issue objects - */ - /** - * @param statusNodes * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-workflow-editor-validation */ validateWorkflow(statusNodes = []) { @@ -1056,12 +959,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {Array} roleTypes Role types of the case type * @param {Array} docTypes Document types of the case type * @return {object} Portable workflow definition - */ - /** - * @param template - * @param statusTypes - * @param roleTypes - * @param docTypes * @spec openspec/specs/workflow-definition-model/spec.md */ exportWorkflow(template, statusTypes, roleTypes, docTypes) { @@ -1134,13 +1031,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {Array} roleTypes Role types of the target case type * @param {Array} docTypes Document types of the target case type * @return {object} {success, template, missingTypes} - */ - /** - * @param importData - * @param caseTypeId - * @param statusTypes - * @param roleTypes - * @param docTypes * @spec openspec/specs/workflow-definition-model/spec.md */ async importWorkflow( @@ -1228,10 +1118,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {string} statusId UUID of the status to add the step to * @param {object} stepData Step properties (optional overrides) * @return {object} The new step - */ - /** - * @param statusId - * @param stepData * @spec openspec/specs/workflow-definition-model/spec.md */ addStep(statusId, stepData = {}) { @@ -1259,9 +1145,6 @@ export const useWorkflowStore = defineStore('workflow', { * Remove a step from the current workflow template. * * @param {string} stepId UUID of the step to remove - */ - /** - * @param stepId * @spec openspec/specs/workflow-definition-model/spec.md */ removeStep(stepId) { @@ -1289,10 +1172,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {string} stepId UUID of the step to update * @param {object} updates Properties to update - */ - /** - * @param stepId - * @param updates * @spec openspec/specs/workflow-definition-model/spec.md */ updateStep(stepId, updates) { @@ -1313,11 +1192,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {string} toStatus UUID of the target status * @param {object} data Optional transition properties * @return {object} The new transition - */ - /** - * @param fromStatus - * @param toStatus - * @param data * @spec openspec/specs/workflow-definition-model/spec.md */ addTransition(fromStatus, toStatus, data = {}) { @@ -1342,9 +1216,6 @@ export const useWorkflowStore = defineStore('workflow', { * Remove a transition from the current workflow template. * * @param {string} transitionId UUID of the transition to remove - */ - /** - * @param transitionId * @spec openspec/specs/workflow-definition-model/spec.md */ removeTransition(transitionId) { @@ -1361,10 +1232,6 @@ export const useWorkflowStore = defineStore('workflow', { * * @param {string} transitionId UUID of the transition to update * @param {object} updates Properties to update - */ - /** - * @param transitionId - * @param updates * @spec openspec/specs/workflow-definition-model/spec.md */ updateTransition(transitionId, updates) { @@ -1384,11 +1251,6 @@ export const useWorkflowStore = defineStore('workflow', { * @param {string} statusId UUID of the status * @param {number} x X coordinate * @param {number} y Y coordinate - */ - /** - * @param statusId - * @param x - * @param y * @spec openspec/specs/workflow-definition-model/spec.md */ updateNodePosition(statusId, x, y) { @@ -1409,9 +1271,6 @@ export const useWorkflowStore = defineStore('workflow', { * `StatusesTab.vue::deleteStatusType()` already enforces. * * @param {string} statusId UUID of the status to remove - */ - /** - * @param statusId * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-drag-and-drop-workflow-canvas */ removeStatusNode(statusId) { diff --git a/src/utils/caseHelpers.js b/src/utils/caseHelpers.js index 9da6013d8..309c957bc 100644 --- a/src/utils/caseHelpers.js +++ b/src/utils/caseHelpers.js @@ -32,10 +32,6 @@ export function parseJsonArray(value) { * @param {string|Date} startDate Start date (ISO string or Date) * @param {string} durationString ISO 8601 duration (e.g., "P56D") * @return {Date|null} The calculated deadline, or null if inputs are invalid - */ -/** - * @param startDate - * @param durationString * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function calculateDeadline(startDate, durationString) { @@ -73,10 +69,6 @@ export function generateIdentifier() { * @param {object} caseObj Case object with deadline property * @param {boolean} isFinal Whether the case is at a final status * @return {boolean} - */ -/** - * @param caseObj - * @param isFinal * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function isCaseOverdue(caseObj, isFinal = false) { @@ -95,10 +87,6 @@ export function isCaseOverdue(caseObj, isFinal = false) { * @param {object} caseObj Case object with deadline property * @param {boolean} isFinal Whether the case is at a final status * @return {boolean} - */ -/** - * @param caseObj - * @param isFinal * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function isCaseDueToday(caseObj, isFinal = false) { @@ -119,10 +107,6 @@ export function isCaseDueToday(caseObj, isFinal = false) { * @param {object} caseObj Case object with deadline property * @param {boolean} isFinal Whether the case is at a final status * @return {boolean} - */ -/** - * @param caseObj - * @param isFinal * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function isCaseDueTomorrow(caseObj, isFinal = false) { @@ -144,10 +128,6 @@ export function isCaseDueTomorrow(caseObj, isFinal = false) { * @param {object} caseObj Case object with deadline property * @param {boolean} isFinal Whether the case is at a final status * @return {string|null} Overdue text or null if not overdue - */ -/** - * @param caseObj - * @param isFinal * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function getCaseOverdueText(caseObj, isFinal = false) { @@ -170,10 +150,6 @@ export function getCaseOverdueText(caseObj, isFinal = false) { * @param {object} caseObj Case object with deadline property * @param {boolean} isFinal Whether the case is at a final status * @return {{ text: string, style: string }} Countdown text and style class - */ -/** - * @param caseObj - * @param isFinal * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function formatDeadlineCountdown(caseObj, isFinal = false) { @@ -205,9 +181,6 @@ export function formatDeadlineCountdown(caseObj, isFinal = false) { * * @param {string} startDate ISO date string * @return {number} Days elapsed (0 if today or invalid) - */ -/** - * @param startDate * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function getDaysElapsed(startDate) { @@ -225,9 +198,6 @@ export function getDaysElapsed(startDate) { * * @param {string} deadline ISO date string * @return {number} Days remaining (negative if overdue) - */ -/** - * @param deadline * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function getDaysRemaining(deadline) { @@ -245,9 +215,6 @@ export function getDaysRemaining(deadline) { * * @param {string} dateString ISO date string * @return {string} Formatted date - */ -/** - * @param dateString * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function formatDate(dateString) { @@ -265,9 +232,6 @@ export function formatDate(dateString) { * * @param {string} dateString ISO date string * @return {string} Formatted date - */ -/** - * @param dateString * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function formatDateShort(dateString) { diff --git a/src/utils/caseTypeValidation.js b/src/utils/caseTypeValidation.js index 034fb8a96..c83bc5d29 100644 --- a/src/utils/caseTypeValidation.js +++ b/src/utils/caseTypeValidation.js @@ -39,9 +39,6 @@ export function getConfidentialityOptions() { * * @param {object} data Case type data * @return {{ valid: boolean, errors: object }} - */ -/** - * @param data * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ export function validateCaseType(data) { @@ -105,10 +102,6 @@ export function validateCaseType(data) { * @param {object} caseType Case type data * @param {Array} statusTypes Array of status type objects linked to this case type * @return {{ valid: boolean, errors: string[] }} - */ -/** - * @param caseType - * @param statusTypes * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ export function validateForPublish(caseType, statusTypes) { diff --git a/src/utils/caseValidation.js b/src/utils/caseValidation.js index d1eb50663..e37bd59b7 100644 --- a/src/utils/caseValidation.js +++ b/src/utils/caseValidation.js @@ -8,9 +8,6 @@ * * @param {object} caseType Case type object * @return {boolean} - */ -/** - * @param caseType * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function isCaseTypeUsable(caseType) { @@ -40,9 +37,6 @@ export function isCaseTypeUsable(caseType) { * * @param {object} caseType Case type object * @return {string|null} Reason why the case type cannot be used, or null if usable - */ -/** - * @param caseType * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function getCaseTypeUnusableReason(caseType) { @@ -93,10 +87,6 @@ export function getCaseTypeUnusableReason(caseType) { * @param {object} form The form data with title, caseType, etc. * @param {object[]} caseTypes Available case types for validation context * @return {{ valid: boolean, errors: object }} Validation result - */ -/** - * @param form - * @param caseTypes * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function validateCaseCreate(form, caseTypes = []) { @@ -131,9 +121,6 @@ export function validateCaseCreate(form, caseTypes = []) { * * @param {object} form The form data with title * @return {{ valid: boolean, errors: object }} Validation result - */ -/** - * @param form * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function validateCaseUpdate(form) { @@ -156,11 +143,6 @@ export function validateCaseUpdate(form) { * @param {object} caseObj The case object * @param {object[]} statusTypes Available status types for the case type * @return {{ valid: boolean, error: string|null }} Validation result - */ -/** - * @param targetStatus - * @param caseObj - * @param statusTypes * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ export function validateStatusChange(targetStatus, caseObj, statusTypes) { diff --git a/src/utils/dashboardHelpers.js b/src/utils/dashboardHelpers.js index a519310ae..e0246cf4a 100644 --- a/src/utils/dashboardHelpers.js +++ b/src/utils/dashboardHelpers.js @@ -28,11 +28,6 @@ function todayString() { * @param {object[]} completedCases Cases completed this month * @param {object[]} myTasks Tasks assigned to current user (available/active) * @return {object} KPI values - */ -/** - * @param openCases - * @param completedCases - * @param myTasks * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function computeKpis(openCases, completedCases, myTasks) { @@ -90,10 +85,6 @@ export function computeKpis(openCases, completedCases, myTasks) { * @param {object[]} openCases Cases with non-final status * @param {object[]} statusTypes All status types * @return {Array<{ name: string, count: number, statusIds: string[] }>} Sorted by status type order - */ -/** - * @param openCases - * @param statusTypes * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function aggregateByStatus(openCases, statusTypes) { @@ -145,10 +136,6 @@ export function aggregateByStatus(openCases, statusTypes) { * @param {object[]} openCases Cases with non-final status * @param {object[]} caseTypes All case types (for name resolution) * @return {Array<{ id, identifier, title, caseTypeName, daysOverdue, handler }>} - */ -/** - * @param openCases - * @param caseTypes * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function getOverdueCases(openCases, caseTypes) { @@ -176,10 +163,6 @@ export function getOverdueCases(openCases, caseTypes) { * @param {object[]} cases All visible cases (with activity arrays) * @param {number} limit Max entries to return * @return {Array<{ date, type, description, user, caseIdentifier }>} - */ -/** - * @param cases - * @param limit * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function getRecentActivity(cases, limit = 10) { @@ -209,11 +192,6 @@ export function getRecentActivity(cases, limit = 10) { * @param {object[]} tasks Tasks assigned to current user (available/active) * @param {number} limit Max items to return * @return {Array<{ type, id, title, reference, deadline, daysText, isOverdue, priority }>} - */ -/** - * @param cases - * @param tasks - * @param limit * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function getMyWorkItems(cases, tasks, limit = 5) { @@ -306,10 +284,6 @@ function endOfWeek() { * @param {object[]} cases Cases assigned to current user (non-final) * @param {object[]} normalizedTasks Already-normalized CalDAV task work items * @return {{ overdue: object[], dueThisWeek: object[], upcoming: object[], noDeadline: object[], totalCount: number }} - */ -/** - * @param cases - * @param normalizedTasks * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function getGroupedMyWorkItems(cases, normalizedTasks) { @@ -411,11 +385,6 @@ export const STALLED_THRESHOLD_DAYS = 7 * @param {object[]} caseTypes All case types (for name resolution) * @param {number} warningDays Number of days before deadline to flag as at-risk * @return {{ overdue: object[], atRisk: object[] }} - */ -/** - * @param openCases - * @param caseTypes - * @param warningDays * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function getDeadlineAlerts( @@ -469,10 +438,6 @@ export function getDeadlineAlerts( * @param {object[]} tasks Tasks assigned to the current user * @param {number} warningDays Number of days before due date to flag as due-soon * @return {{ overdue: object[], dueSoon: object[] }} - */ -/** - * @param tasks - * @param warningDays * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function getTaskDueReminders(tasks, warningDays = DEADLINE_WARNING_DAYS) { @@ -520,11 +485,6 @@ export function getTaskDueReminders(tasks, warningDays = DEADLINE_WARNING_DAYS) * @param {object[]} caseTypes All case types (for name resolution) * @param {number} stalledDays Number of days without activity to consider stalled * @return {Array<{ id, title, identifier, caseTypeName, daysSinceActivity, handler }>} - */ -/** - * @param openCases - * @param caseTypes - * @param stalledDays * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function getStalledCases( @@ -573,9 +533,6 @@ export function getStalledCases( * * @param {string} dateString ISO date string * @return {string} - */ -/** - * @param dateString * @spec openspec/changes/retrofit-2026-05-24-dashboard/tasks.md */ export function formatRelativeTime(dateString) { diff --git a/src/utils/decisionHelpers.js b/src/utils/decisionHelpers.js index 7d84d8bdf..ff829ae57 100644 --- a/src/utils/decisionHelpers.js +++ b/src/utils/decisionHelpers.js @@ -7,9 +7,6 @@ * * @param {object} decision Decision object with effectiveDate and expiryDate * @return {{ status: string, label: string, style: string, remaining: string|null }} - */ -/** - * @param decision * @spec openspec/specs/roles-decisions/spec.md */ export function getDecisionValidity(decision) { @@ -93,9 +90,6 @@ export function getDecisionValidity(decision) { * * @param {string} dateString ISO date string * @return {string} - */ -/** - * @param dateString * @spec openspec/specs/roles-decisions/spec.md */ export function formatDecisionDate(dateString) { @@ -113,9 +107,6 @@ export function formatDecisionDate(dateString) { * * @param {object} form Decision form data * @return {{ valid: boolean, errors: object }} - */ -/** - * @param form * @spec openspec/specs/roles-decisions/spec.md */ export function validateDecision(form) { diff --git a/src/utils/doorlooptijdHelpers.js b/src/utils/doorlooptijdHelpers.js index 31c099ccf..99fb4aaee 100644 --- a/src/utils/doorlooptijdHelpers.js +++ b/src/utils/doorlooptijdHelpers.js @@ -15,9 +15,6 @@ import { translate as t } from '@nextcloud/l10n' * * @param {string} duration ISO 8601 duration (e.g., "P30D") * @return {number|null} Number of days, or null if unparseable - */ -/** - * @param duration * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function parseDurationToDays(duration) { @@ -40,9 +37,6 @@ export function parseDurationToDays(duration) { * * @param {object} caseObj Case object with startDate and endDate * @return {number|null} Processing days, or null if dates are missing - */ -/** - * @param caseObj * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function getProcessingDays(caseObj) { @@ -63,10 +57,6 @@ export function getProcessingDays(caseObj) { * @param {object} caseObj Case object with caseType field * @param {Map} caseTypeMap Map of caseType id to caseType object * @return {number|null} Target days from processingDeadline, or null - */ -/** - * @param caseObj - * @param caseTypeMap * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function getSlaTargetDays(caseObj, caseTypeMap) { @@ -80,9 +70,6 @@ export function getSlaTargetDays(caseObj, caseTypeMap) { * * @param {object[]} caseTypes Array of case type objects * @return {Map} - */ -/** - * @param caseTypes * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function buildCaseTypeMap(caseTypes) { @@ -99,10 +86,6 @@ export function buildCaseTypeMap(caseTypes) { * @param {object[]} completedCases Cases with final status and endDate * @param {object[]} caseTypes All case types * @return {{ overallRate: number|null, withinSla: number, total: number, excluded: number, byType: Array<{ id, name, total, withinSla, rate, avgActual, targetDays }> }} - */ -/** - * @param completedCases - * @param caseTypes * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function computeSlaCompliance(completedCases, caseTypes) { @@ -246,11 +229,6 @@ export function computeProcessingTimeDistribution(completedCases, caseTypes, bin * @param {object[]} caseTypes All case types * @param {number} [months] Number of months to look back (defaults to 12) * @return {Array<{ month: string, rate: number|null, withinSla: number, total: number }>} - */ -/** - * @param completedCases - * @param caseTypes - * @param months * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function computeMonthlyTrend(completedCases, caseTypes, months) { @@ -300,11 +278,6 @@ export function computeMonthlyTrend(completedCases, caseTypes, months) { * @param {object[]} caseTypes All case types * @param {number} [thresholdPct] Threshold as fraction (defaults to 0.25 = 25%) * @return {Array<{ id, title, identifier, caseTypeName, targetDays, elapsedDays, remainingDays, percentUsed, isOverdue }>} - */ -/** - * @param openCases - * @param caseTypes - * @param thresholdPct * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function getAtRiskCases(openCases, caseTypes, thresholdPct) { @@ -359,10 +332,6 @@ export function getAtRiskCases(openCases, caseTypes, thresholdPct) { * @param {object[]} completedCases Completed cases * @param {object[]} caseTypes All case types * @return {Array<{ id, name, targetDays, avgActualDays, complianceRate, total, withinSla, status: 'good'|'warning'|'critical'|'no-target' }>} - */ -/** - * @param completedCases - * @param caseTypes * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function computePerformanceTable(completedCases, caseTypes) { diff --git a/src/utils/durationHelpers.js b/src/utils/durationHelpers.js index 3b10f677a..c27fd6f74 100644 --- a/src/utils/durationHelpers.js +++ b/src/utils/durationHelpers.js @@ -12,9 +12,6 @@ const DURATION_REGEX = /^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?$/ * * @param {string} value The string to validate * @return {boolean} - */ -/** - * @param value * @spec openspec/specs/milestone-tracking/spec.md */ export function isValidDuration(value) { @@ -27,9 +24,6 @@ export function isValidDuration(value) { * * @param {string} iso ISO 8601 duration string (e.g., "P56D", "P2M", "P1Y6M") * @return {{ years: number, months: number, weeks: number, days: number } | null} - */ -/** - * @param iso * @spec openspec/specs/milestone-tracking/spec.md */ export function parseDuration(iso) { @@ -48,9 +42,6 @@ export function parseDuration(iso) { * * @param {string} iso ISO 8601 duration string * @return {string} Human-readable text (e.g., "56 days", "2 months", "1 year, 6 months") - */ -/** - * @param iso * @spec openspec/specs/milestone-tracking/spec.md */ export function formatDuration(iso) { @@ -91,9 +82,6 @@ export function formatDuration(iso) { * * @param {string} value The value to validate * @return {string} Error message or empty string - */ -/** - * @param value * @spec openspec/specs/milestone-tracking/spec.md */ export function getDurationError(value) { diff --git a/src/utils/i18nResolver.js b/src/utils/i18nResolver.js index d5ca9e19f..11cf97214 100644 --- a/src/utils/i18nResolver.js +++ b/src/utils/i18nResolver.js @@ -46,11 +46,6 @@ export function getUserLocale() { * @param {string} [locale] The preferred locale (defaults to user's locale) * @param {string} [fallbackLocale] The fallback locale (defaults to app default 'nl') * @return {{ text: string, lang: string|null, isFallback: boolean }} - */ -/** - * @param value - * @param locale - * @param fallbackLocale * @spec openspec/changes/retrofit-2026-05-25-procest-app-scaffold/tasks.md */ export function resolveTranslatable(value, locale, fallbackLocale) { @@ -115,11 +110,6 @@ export function resolveTranslatable(value, locale, fallbackLocale) { * @param {string} field The field name to resolve * @param {string} [locale] The preferred locale * @return {{ text: string, lang: string|null, isFallback: boolean }} - */ -/** - * @param obj - * @param field - * @param locale * @spec openspec/changes/retrofit-2026-05-25-procest-app-scaffold/tasks.md */ export function resolveField(obj, field, locale) { @@ -136,11 +126,6 @@ export function resolveField(obj, field, locale) { * @param {string} field The field name to resolve * @param {string} [locale] The preferred locale * @return {string} The resolved text - */ -/** - * @param obj - * @param field - * @param locale * @spec openspec/changes/retrofit-2026-05-25-procest-app-scaffold/tasks.md */ export function resolveText(obj, field, locale) { diff --git a/src/utils/taskHelpers.js b/src/utils/taskHelpers.js index 37a6a5012..fd524de00 100644 --- a/src/utils/taskHelpers.js +++ b/src/utils/taskHelpers.js @@ -42,9 +42,6 @@ export function getPriorityLevels() { * * @param {object} task Task object with dueDate and status * @return {boolean} - */ -/** - * @param task * @spec openspec/specs/task-management/spec.md */ export function isOverdue(task) { @@ -62,9 +59,6 @@ export function isOverdue(task) { * * @param {object} task Task object with dueDate and status * @return {boolean} - */ -/** - * @param task * @spec openspec/specs/task-management/spec.md */ export function isDueToday(task) { @@ -84,9 +78,6 @@ export function isDueToday(task) { * * @param {object} task Task object with dueDate * @return {string|null} Overdue text or null if not overdue - */ -/** - * @param task * @spec openspec/specs/task-management/spec.md */ export function getOverdueText(task) { @@ -108,9 +99,6 @@ export function getOverdueText(task) { * * @param {string} dateString ISO 8601 date string * @return {string} Formatted date - */ -/** - * @param dateString * @spec openspec/specs/task-management/spec.md */ export function formatDueDate(dateString) { @@ -124,9 +112,6 @@ export function formatDueDate(dateString) { * * @param {string} priority One of urgent, high, normal, low * @return {number} - */ -/** - * @param priority * @spec openspec/specs/task-management/spec.md */ export function prioritySortWeight(priority) { @@ -162,9 +147,6 @@ function statusGroupWeight(status) { * * @param {object[]} tasks Array of task objects * @return {object[]} Sorted copy of the array - */ -/** - * @param tasks * @spec openspec/specs/task-management/spec.md */ export function sortTasks(tasks) { diff --git a/src/utils/taskLifecycle.js b/src/utils/taskLifecycle.js index 6466d30c2..8958928fd 100644 --- a/src/utils/taskLifecycle.js +++ b/src/utils/taskLifecycle.js @@ -55,9 +55,6 @@ const TERMINAL_STATUSES = new Set(['completed', 'terminated', 'disabled']) * * @param {string} currentStatus One of the TASK_STATUSES values * @return {string[]} Array of valid target statuses - */ -/** - * @param currentStatus * @spec openspec/specs/task-management/spec.md */ export function getAllowedTransitions(currentStatus) { @@ -70,10 +67,6 @@ export function getAllowedTransitions(currentStatus) { * @param {string} from Current status * @param {string} to Target status * @return {boolean} - */ -/** - * @param from - * @param to * @spec openspec/specs/task-management/spec.md */ export function validateTransition(from, to) { @@ -86,9 +79,6 @@ export function validateTransition(from, to) { * * @param {string} status One of the TASK_STATUSES values * @return {string} - */ -/** - * @param status * @spec openspec/specs/task-management/spec.md */ export function getStatusLabel(status) { @@ -100,9 +90,6 @@ export function getStatusLabel(status) { * * @param {string} targetStatus The status being transitioned to * @return {string} - */ -/** - * @param targetStatus * @spec openspec/specs/task-management/spec.md */ export function getTransitionLabel(targetStatus) { @@ -114,9 +101,6 @@ export function getTransitionLabel(targetStatus) { * * @param {string} status One of the TASK_STATUSES values * @return {boolean} - */ -/** - * @param status * @spec openspec/specs/task-management/spec.md */ export function isTerminalStatus(status) { diff --git a/src/utils/taskValidation.js b/src/utils/taskValidation.js index 3bd1f98e3..b0f2e3d03 100644 --- a/src/utils/taskValidation.js +++ b/src/utils/taskValidation.js @@ -9,9 +9,6 @@ import { validateTransition } from './taskLifecycle.js' * * @param {object} form The form data * @return {{ valid: boolean, errors: object }} Validation result - */ -/** - * @param form * @spec openspec/specs/task-management/spec.md */ export function validateTaskCreate(form) { @@ -36,9 +33,6 @@ export function validateTaskCreate(form) { * * @param {object} form The form data * @return {{ valid: boolean, errors: object }} Validation result - */ -/** - * @param form * @spec openspec/specs/task-management/spec.md */ export function validateTaskUpdate(form) { @@ -60,10 +54,6 @@ export function validateTaskUpdate(form) { * @param {string} from Current status * @param {string} to Target status * @return {{ valid: boolean, error: string|null }} Validation result - */ -/** - * @param from - * @param to * @spec openspec/specs/task-management/spec.md */ export function validateTaskTransition(from, to) { diff --git a/src/views/settings/WorkflowEditor.vue b/src/views/settings/WorkflowEditor.vue index 55c565dae..79e9d28b0 100644 --- a/src/views/settings/WorkflowEditor.vue +++ b/src/views/settings/WorkflowEditor.vue @@ -539,10 +539,6 @@ export default { * * @param {string} fromStatusId Source status UUID * @param {string} toStatusId Target status UUID - */ - /** - * @param fromStatusId - * @param toStatusId * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-keyboard-operable-canvas */ onConnectionKeyboard(fromStatusId, toStatusId) { @@ -558,9 +554,6 @@ export default { * selected. * * @param {string} transitionId UUID of the transition to remove - */ - /** - * @param transitionId * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-keyboard-operable-canvas */ onDisconnectionKeyboard(transitionId) { @@ -579,9 +572,6 @@ export default { * the working copy via `workflowStore.removeStatusNode()`. * * @param {string} statusId UUID of the status to delete - */ - /** - * @param statusId * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-drag-and-drop-workflow-canvas */ async onDeleteStatusNode(statusId) { @@ -643,9 +633,6 @@ export default { * never called from any component. * * @param {string} stepId UUID of the step to delete - */ - /** - * @param stepId * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-step-configuration-panel */ onStepDelete(stepId) { diff --git a/src/views/settings/components/WorkflowNode.vue b/src/views/settings/components/WorkflowNode.vue index 10048eebc..ed48a6311 100644 --- a/src/views/settings/components/WorkflowNode.vue +++ b/src/views/settings/components/WorkflowNode.vue @@ -195,9 +195,6 @@ export default { * * @param {string} statusId UUID of the status * @return {string} The status name, or the id if not found - */ - /** - * @param statusId * @spec openspec/specs/visual-workflow-editor/spec.md#requirement-keyboard-operable-canvas */ targetName(statusId) { From ff0ab18253880f5a8ffe261983a2556cec52dc8d Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Fri, 4 Sep 2026 07:50:02 +0200 Subject: [PATCH 2/7] fix(vue): declare the events these components already emit vue/require-explicit-emits fires when $emit('x') has no matching entry in the component's emits option. Nothing here is guessed: eslint names each event because the component is already emitting it, and an undeclared emit falls through to the native listener path in Vue 3 rather than being bound as a component event. 13 components, 22 events, placed in style-guide position (after props, before data/computed/methods). eslint warnings 296 -> 244, lint and vitest exit 0. --- .../besluitvorming/BesluitPublicatiePanel.vue | 2 ++ src/components/initiator/InitiatorPicker.vue | 2 ++ src/modals/InitiatorPickerModal.vue | 2 ++ src/views/MyWorkCaseCard.vue | 2 ++ src/views/cases/components/AdviceRequestPanel.vue | 2 ++ src/views/cases/components/CaseEmailTab.vue | 2 ++ src/views/cases/components/EmailThread.vue | 2 ++ src/views/settings/CaseTypeDetail.vue | 2 ++ src/views/settings/CaseTypeList.vue | 2 ++ src/views/settings/WorkflowEditor.vue | 2 ++ src/views/settings/components/DurationPicker.vue | 2 ++ src/views/settings/components/WorkflowNode.vue | 13 +++++++------ src/views/settings/tabs/GeneralTab.vue | 2 ++ 13 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/components/besluitvorming/BesluitPublicatiePanel.vue b/src/components/besluitvorming/BesluitPublicatiePanel.vue index 831ad976d..063f498c9 100644 --- a/src/components/besluitvorming/BesluitPublicatiePanel.vue +++ b/src/components/besluitvorming/BesluitPublicatiePanel.vue @@ -68,6 +68,8 @@ export default { }, }, + emits: ['published'], + data() { return { state: this.initialState, diff --git a/src/components/initiator/InitiatorPicker.vue b/src/components/initiator/InitiatorPicker.vue index 494751152..9ac3697ed 100644 --- a/src/components/initiator/InitiatorPicker.vue +++ b/src/components/initiator/InitiatorPicker.vue @@ -107,6 +107,8 @@ export default { }, }, + emits: ['select'], + data() { return { activeTab: 'person', diff --git a/src/modals/InitiatorPickerModal.vue b/src/modals/InitiatorPickerModal.vue index b2ddc24a6..b72a5f587 100644 --- a/src/modals/InitiatorPickerModal.vue +++ b/src/modals/InitiatorPickerModal.vue @@ -66,6 +66,8 @@ export default { InitiatorPicker, }, + emits: ['close', 'confirm', 'skip'], + data() { return { selection: null, diff --git a/src/views/MyWorkCaseCard.vue b/src/views/MyWorkCaseCard.vue index 594c6d06d..582a988f6 100644 --- a/src/views/MyWorkCaseCard.vue +++ b/src/views/MyWorkCaseCard.vue @@ -88,6 +88,8 @@ export default { }, }, + emits: ['open'], + computed: { /** * Card heading for one case on the personal work index. diff --git a/src/views/cases/components/AdviceRequestPanel.vue b/src/views/cases/components/AdviceRequestPanel.vue index 4cb196a4b..6e2e6dbec 100644 --- a/src/views/cases/components/AdviceRequestPanel.vue +++ b/src/views/cases/components/AdviceRequestPanel.vue @@ -131,6 +131,8 @@ export default { }, }, + emits: ['create'], + data() { return { showForm: false, diff --git a/src/views/cases/components/CaseEmailTab.vue b/src/views/cases/components/CaseEmailTab.vue index 3bcb71acd..0959f7eeb 100644 --- a/src/views/cases/components/CaseEmailTab.vue +++ b/src/views/cases/components/CaseEmailTab.vue @@ -146,6 +146,8 @@ export default { }, }, + emits: ['drafted'], + data() { return { loading: true, diff --git a/src/views/cases/components/EmailThread.vue b/src/views/cases/components/EmailThread.vue index f025009d6..f30d89b46 100644 --- a/src/views/cases/components/EmailThread.vue +++ b/src/views/cases/components/EmailThread.vue @@ -88,6 +88,8 @@ export default { }, }, + emits: ['compose'], + data() { return { expandedMessages: {}, diff --git a/src/views/settings/CaseTypeDetail.vue b/src/views/settings/CaseTypeDetail.vue index f8fb13521..403458043 100644 --- a/src/views/settings/CaseTypeDetail.vue +++ b/src/views/settings/CaseTypeDetail.vue @@ -220,6 +220,8 @@ export default { }, }, + emits: ['back', 'duplicated', 'saved'], + data() { return { form: { ...EMPTY_FORM }, diff --git a/src/views/settings/CaseTypeList.vue b/src/views/settings/CaseTypeList.vue index 01d8c3252..67199fea5 100644 --- a/src/views/settings/CaseTypeList.vue +++ b/src/views/settings/CaseTypeList.vue @@ -103,6 +103,8 @@ export default { CnIndexPage, }, + emits: ['create', 'select'], + data() { return { statusTypeCounts: {}, diff --git a/src/views/settings/WorkflowEditor.vue b/src/views/settings/WorkflowEditor.vue index 79e9d28b0..2474abff1 100644 --- a/src/views/settings/WorkflowEditor.vue +++ b/src/views/settings/WorkflowEditor.vue @@ -124,6 +124,8 @@ export default { }, }, + emits: ['dirty'], + data() { return { /** @type {Array} Status type objects for the case type */ diff --git a/src/views/settings/components/DurationPicker.vue b/src/views/settings/components/DurationPicker.vue index a6653478f..3973d6116 100644 --- a/src/views/settings/components/DurationPicker.vue +++ b/src/views/settings/components/DurationPicker.vue @@ -51,6 +51,8 @@ export default { }, }, + emits: ['input'], + computed: { /** @spec openspec/changes/retrofit-2026-05-24-milestone-tracking/tasks.md */ daysInput() { diff --git a/src/views/settings/components/WorkflowNode.vue b/src/views/settings/components/WorkflowNode.vue index ed48a6311..7cb07073b 100644 --- a/src/views/settings/components/WorkflowNode.vue +++ b/src/views/settings/components/WorkflowNode.vue @@ -147,15 +147,16 @@ export default { }, emits: [ - 'select', - 'drag-start', - 'connection-start', - 'connection-end', - 'step-click', 'add-step', + 'connection-end', + 'connection-start', + 'delete-status', + 'drag-start', 'keyboard-connect', 'keyboard-disconnect', - 'delete-status', + 'select', + 'step-click', + 'step-reorder', ], data() { diff --git a/src/views/settings/tabs/GeneralTab.vue b/src/views/settings/tabs/GeneralTab.vue index 9a0d69e87..20fc08cec 100644 --- a/src/views/settings/tabs/GeneralTab.vue +++ b/src/views/settings/tabs/GeneralTab.vue @@ -301,6 +301,8 @@ export default { }, }, + emits: ['update'], + data() { return { iv3Taakvelden: [], From e5481284374495993dd170222160f47691c898a3 Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Fri, 4 Sep 2026 09:02:09 +0200 Subject: [PATCH 3/7] docs(jsdoc): give the bare @param tags a type and a description An earlier automated pass bolted `@spec` onto these functions and dragged bare `@param name` lines along with it: no type, no description, no information. Deleting them is not a fix either, because jsdoc/require-param is enabled and simply reports the parameter as undeclared instead. 115 filled across 47 files. The type comes from the parameter's DEFAULT VALUE where the signature has one, otherwise from a closed table of name patterns (`*Uuid` string, `is*`/`has*` boolean, `*Count` number, plurals Array, and so on). 67 are deliberately left: `value`, `val`, `mode`, `tpl` and friends, whose type is whatever the call site passes. A guessed @param type is a claim the next reader trusts, so those are worth reading one at a time rather than filling in bulk. Warnings 244 -> 109. lint, format and vitest all exit 0. --- eslint-suppressions.json | 90 +++++-------------- src/components/map/AddressSearch.vue | 4 +- src/components/map/LocationPicker.vue | 4 +- src/dialogs/AiExtractDialog.vue | 4 +- src/dialogs/ConsultationResponseForm.vue | 2 +- src/modals/BulkReassignModal.vue | 2 +- src/modals/DeelzaakDeleteWarningModal.vue | 2 +- src/modals/SubstitutionFormModal.vue | 2 +- src/services/berichtenboxApi.js | 6 +- src/services/caseRelationApi.js | 2 +- src/services/wooPublicationApi.js | 4 +- src/store/modules/deelzaak.js | 8 +- src/store/modules/processMining.js | 4 +- src/store/modules/settings.js | 2 +- src/store/modules/zgwMapping.js | 6 +- src/utils/caseTypeValidation.js | 2 +- src/utils/doorlooptijdHelpers.js | 6 +- src/utils/openregisterCheck.js | 2 +- src/views/admin/SubstitutionAdmin.vue | 4 +- src/views/cases/DeelzaakList.vue | 2 +- .../cases/components/AdviceRequestPanel.vue | 8 +- src/views/cases/components/AdviesPanel.vue | 18 ++-- src/views/cases/components/EmailThread.vue | 6 +- .../cases/components/InspectionPanel.vue | 10 +-- .../components/EmailTemplateAdmin.vue | 4 +- .../ExternalConsultationResponsePage.vue | 4 +- src/views/public/PublicAppointmentPage.vue | 2 +- src/views/settings/CaseTypeAdmin.vue | 4 +- src/views/settings/CaseTypeDetail.vue | 2 +- src/views/settings/CaseTypeList.vue | 4 +- src/views/settings/SubstitutionSettings.vue | 2 +- src/views/settings/WorkflowEditor.vue | 36 ++++---- src/views/settings/ZgwMappingSettings.vue | 6 +- .../components/MandaatImportPanel.vue | 2 +- .../components/MandaatMatrixTable.vue | 2 +- .../components/MandaatToewijzingenTable.vue | 2 +- .../components/OrganisatieRolManager.vue | 2 +- .../settings/components/StepConfigPanel.vue | 10 +-- .../components/TransitionConfigPanel.vue | 6 +- .../settings/components/WorkflowNode.vue | 10 +-- .../settings/components/WorkflowPalette.vue | 4 +- src/views/settings/tabs/AiSettingsTab.vue | 2 +- src/views/settings/tabs/DocumentTypesTab.vue | 4 +- src/views/settings/tabs/MandaatMatrixTab.vue | 2 +- src/views/settings/tabs/StatusesTab.vue | 4 +- .../settings/tabs/TermijnDefinitiesTab.vue | 2 +- src/views/settings/tabs/WorkflowTab.vue | 2 +- .../e2e/workflows/deelzaak-case-email.spec.ts | 2 +- 48 files changed, 135 insertions(+), 185 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 06270f2a0..69e189401 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -33,7 +33,7 @@ "count": 2 }, "jsdoc/require-param-type": { - "count": 3 + "count": 1 } }, "src/components/map/LocationPicker.vue": { @@ -41,7 +41,7 @@ "count": 3 }, "jsdoc/require-param-type": { - "count": 5 + "count": 3 } }, "src/components/tabs/CaseDocumentsTab.vue": { @@ -86,7 +86,7 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 3 + "count": 1 } }, "src/dialogs/BerichtenboxComposeDialog.vue": { @@ -145,7 +145,7 @@ "count": 3 }, "jsdoc/require-param-type": { - "count": 2 + "count": 1 } }, "src/dialogs/CreateFederatedShareDialog.vue": { @@ -250,9 +250,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/modals/DeelzaakCreateModal.vue": { @@ -267,9 +264,6 @@ "@nextcloud/no-deprecated-library-props": { "count": 1 }, - "jsdoc/require-param-type": { - "count": 1 - }, "no-console": { "count": 1 } @@ -298,9 +292,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/modals/TermijnDefinitieEditor.vue": { @@ -399,9 +390,6 @@ "@nextcloud/no-deprecated-library-props": { "count": 4 }, - "jsdoc/require-param-type": { - "count": 2 - }, "no-console": { "count": 3 } @@ -421,9 +409,6 @@ "@typescript-eslint/no-unused-vars": { "count": 1 }, - "jsdoc/require-param-type": { - "count": 1 - }, "no-console": { "count": 2 } @@ -431,9 +416,6 @@ "src/views/cases/components/AdviceRequestPanel.vue": { "@nextcloud/no-deprecated-library-props": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 4 } }, "src/views/cases/components/AdviesPanel.vue": { @@ -444,7 +426,7 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 11 + "count": 2 }, "no-console": { "count": 3 @@ -495,9 +477,6 @@ "src/views/cases/components/EmailThread.vue": { "@nextcloud/no-deprecated-library-props": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 3 } }, "src/views/cases/components/InspectionPanel.vue": { @@ -508,7 +487,7 @@ "count": 2 }, "jsdoc/require-param-type": { - "count": 6 + "count": 1 } }, "src/views/cases/components/ShareTab.vue": { @@ -544,7 +523,7 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 4 + "count": 2 } }, "src/views/dashboard/WooDeadlinePanel.vue": { @@ -569,9 +548,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 2 } }, "src/views/public/PublicAppointmentPage.vue": { @@ -582,7 +558,7 @@ "count": 2 }, "jsdoc/require-param-type": { - "count": 2 + "count": 1 } }, "src/views/public/PublicFederatedTransferPage.vue": { @@ -604,11 +580,6 @@ "count": 1 } }, - "src/views/settings/CaseTypeAdmin.vue": { - "jsdoc/require-param-type": { - "count": 2 - } - }, "src/views/settings/CaseTypeDetail.vue": { "@nextcloud/no-deprecated-library-props": { "count": 5 @@ -617,7 +588,7 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 2 + "count": 1 } }, "src/views/settings/CaseTypeList.vue": { @@ -625,7 +596,7 @@ "count": 3 }, "jsdoc/require-param-type": { - "count": 8 + "count": 6 } }, "src/views/settings/EmailSettings.vue": { @@ -681,9 +652,6 @@ "@nextcloud/no-deprecated-library-props": { "count": 2 }, - "jsdoc/require-param-type": { - "count": 1 - }, "no-console": { "count": 2 } @@ -693,15 +661,12 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 20 + "count": 2 } }, "src/views/settings/ZgwMappingSettings.vue": { "@nextcloud/no-deprecated-library-props": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 3 } }, "src/views/settings/components/DurationPicker.vue": { @@ -712,17 +677,11 @@ "src/views/settings/components/MandaatImportPanel.vue": { "@nextcloud/no-deprecated-library-props": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/views/settings/components/MandaatMatrixTable.vue": { "@nextcloud/no-deprecated-library-props": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/views/settings/components/MandaatToewijzingenTable.vue": { @@ -733,7 +692,7 @@ "count": 2 }, "jsdoc/require-param-type": { - "count": 5 + "count": 4 } }, "src/views/settings/components/OrganisatieRolManager.vue": { @@ -744,7 +703,7 @@ "count": 2 }, "jsdoc/require-param-type": { - "count": 3 + "count": 2 } }, "src/views/settings/components/RolNode.vue": { @@ -763,7 +722,7 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 11 + "count": 6 } }, "src/views/settings/components/TransitionConfigPanel.vue": { @@ -771,12 +730,12 @@ "count": 6 }, "jsdoc/require-param-type": { - "count": 6 + "count": 3 } }, "src/views/settings/components/WorkflowNode.vue": { "jsdoc/require-param-type": { - "count": 6 + "count": 1 }, "vue/custom-event-name-casing": { "count": 12 @@ -786,9 +745,6 @@ "@nextcloud/no-deprecated-library-props": { "count": 1 }, - "jsdoc/require-param-type": { - "count": 2 - }, "vue/custom-event-name-casing": { "count": 2 } @@ -798,7 +754,7 @@ "count": 2 }, "jsdoc/require-param-type": { - "count": 2 + "count": 1 } }, "src/views/settings/tabs/ChecklistsTab.vue": { @@ -836,9 +792,6 @@ "src/views/settings/tabs/DocumentTypesTab.vue": { "@nextcloud/no-deprecated-library-props": { "count": 3 - }, - "jsdoc/require-param-type": { - "count": 2 } }, "src/views/settings/tabs/FinancialIntegrationTab.vue": { @@ -867,7 +820,7 @@ "count": 4 }, "jsdoc/require-param-type": { - "count": 3 + "count": 2 } }, "src/views/settings/tabs/PropertiesTab.vue": { @@ -896,7 +849,7 @@ "count": 5 }, "jsdoc/require-param-type": { - "count": 6 + "count": 4 } }, "src/views/settings/tabs/SubCaseTypesTab.vue": { @@ -915,16 +868,13 @@ "count": 1 }, "jsdoc/require-param-type": { - "count": 4 + "count": 3 } }, "src/views/settings/tabs/WorkflowTab.vue": { "@nextcloud/no-deprecated-library-props": { "count": 7 }, - "jsdoc/require-param-type": { - "count": 1 - }, "no-console": { "count": 1 } diff --git a/src/components/map/AddressSearch.vue b/src/components/map/AddressSearch.vue index 12f40ca66..0fb8b2729 100644 --- a/src/components/map/AddressSearch.vue +++ b/src/components/map/AddressSearch.vue @@ -99,7 +99,7 @@ export default { }, /** - * @param result + * @param {object} result The result. * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ async selectResult(result) { @@ -136,7 +136,7 @@ export default { }, /** - * @param type + * @param {string} type The type. * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ getTypeIcon(type) { diff --git a/src/components/map/LocationPicker.vue b/src/components/map/LocationPicker.vue index 257c18197..b9d81ab6d 100644 --- a/src/components/map/LocationPicker.vue +++ b/src/components/map/LocationPicker.vue @@ -220,7 +220,7 @@ export default { }, /** - * @param latlng + * @param {object} latlng The latlng. * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ placeMarker(latlng) { @@ -277,7 +277,7 @@ export default { }, /** - * @param sqm + * @param {number} sqm The sqm. * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ formatArea(sqm) { diff --git a/src/dialogs/AiExtractDialog.vue b/src/dialogs/AiExtractDialog.vue index 641051f58..790ac87eb 100644 --- a/src/dialogs/AiExtractDialog.vue +++ b/src/dialogs/AiExtractDialog.vue @@ -179,7 +179,7 @@ export default { }, /** - * @param checked + * @param {boolean} checked Whether the checked is set. * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ toggleAll(checked) { @@ -187,7 +187,7 @@ export default { }, /** - * @param name + * @param {string} name The name. * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ toggleField(name) { diff --git a/src/dialogs/ConsultationResponseForm.vue b/src/dialogs/ConsultationResponseForm.vue index 37387f0b3..db2c6969e 100644 --- a/src/dialogs/ConsultationResponseForm.vue +++ b/src/dialogs/ConsultationResponseForm.vue @@ -240,7 +240,7 @@ export default { }, /** - * @param idx + * @param {number} idx The index. * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-05 */ removeVoorwaarde(idx) { diff --git a/src/modals/BulkReassignModal.vue b/src/modals/BulkReassignModal.vue index 82cc23545..5b6209288 100644 --- a/src/modals/BulkReassignModal.vue +++ b/src/modals/BulkReassignModal.vue @@ -302,7 +302,7 @@ export default { }, /** - * @param open + * @param {boolean} open Whether the open is set. * @spec openspec/specs/handler-vervanging-waarneming/spec.md */ onDialogClose(open) { diff --git a/src/modals/DeelzaakDeleteWarningModal.vue b/src/modals/DeelzaakDeleteWarningModal.vue index a6abff566..c4da55f0b 100644 --- a/src/modals/DeelzaakDeleteWarningModal.vue +++ b/src/modals/DeelzaakDeleteWarningModal.vue @@ -114,7 +114,7 @@ export default { methods: { /** - * @param open + * @param {boolean} open Whether the open is set. * @spec openspec/changes/deelzaak-support/tasks.md#T11 */ onDialogClose(open) { diff --git a/src/modals/SubstitutionFormModal.vue b/src/modals/SubstitutionFormModal.vue index a9ec52349..3d27166b6 100644 --- a/src/modals/SubstitutionFormModal.vue +++ b/src/modals/SubstitutionFormModal.vue @@ -258,7 +258,7 @@ export default { }, /** - * @param open + * @param {boolean} open Whether the open is set. * @spec openspec/specs/handler-vervanging-waarneming/spec.md */ onDialogClose(open) { diff --git a/src/services/berichtenboxApi.js b/src/services/berichtenboxApi.js index 01dfe4104..80f110011 100644 --- a/src/services/berichtenboxApi.js +++ b/src/services/berichtenboxApi.js @@ -4,7 +4,7 @@ import { generateUrl } from '@nextcloud/router' const baseUrl = generateUrl('/apps/dossiq/api/berichtenbox') /** - * @param data + * @param {object} data The data. * @spec openspec/changes/retrofit-2026-05-24-berichtenbox-integration/tasks.md */ export async function sendMessage(data) { @@ -13,7 +13,7 @@ export async function sendMessage(data) { } /** - * @param caseId + * @param {string} caseId Identifier of the case id. * @spec openspec/changes/retrofit-2026-05-24-berichtenbox-integration/tasks.md */ export async function listMessages(caseId) { @@ -28,7 +28,7 @@ export async function getTypeCodes() { } /** - * @param messageId + * @param {string} messageId Identifier of the message id. * @spec openspec/changes/retrofit-2026-05-24-berichtenbox-integration/tasks.md */ export async function pollReadStatus(messageId) { diff --git a/src/services/caseRelationApi.js b/src/services/caseRelationApi.js index 2f6cb0506..8a0db3c57 100644 --- a/src/services/caseRelationApi.js +++ b/src/services/caseRelationApi.js @@ -27,7 +27,7 @@ export { /** * - * @param caseId + * @param {string} caseId Identifier of the case id. */ function base(caseId) { return generateUrl( diff --git a/src/services/wooPublicationApi.js b/src/services/wooPublicationApi.js index 88b418e79..e17cc4304 100644 --- a/src/services/wooPublicationApi.js +++ b/src/services/wooPublicationApi.js @@ -13,8 +13,8 @@ import { generateUrl } from '@nextcloud/router' /** * - * @param caseId - * @param path + * @param {string} caseId Identifier of the case id. + * @param {string} path The path. */ function base(caseId, path) { return generateUrl('/apps/dossiq/api/cases/' + caseId + '/woo' + path) diff --git a/src/store/modules/deelzaak.js b/src/store/modules/deelzaak.js index 9451d2c8e..4cd749fc0 100644 --- a/src/store/modules/deelzaak.js +++ b/src/store/modules/deelzaak.js @@ -35,7 +35,7 @@ export const useDeelzaakStore = defineStore('deelzaak', { }, actions: { /** - * @param parentCaseUuid + * @param {string} parentCaseUuid UUID of the parent case. * @spec openspec/changes/deelzaak-support/tasks.md#T01 */ async fetchSubCases(parentCaseUuid) { @@ -54,7 +54,7 @@ export const useDeelzaakStore = defineStore('deelzaak', { }, /** - * @param parentCaseUuid + * @param {string} parentCaseUuid UUID of the parent case. * @spec openspec/changes/deelzaak-support/tasks.md#T02 */ async fetchParentCase(parentCaseUuid) { @@ -68,7 +68,7 @@ export const useDeelzaakStore = defineStore('deelzaak', { }, /** - * @param caseUuidArray + * @param {Array} caseUuidArray The case array. * @spec openspec/changes/deelzaak-support/tasks.md#T03 */ async fetchSubCaseCounts(caseUuidArray) { @@ -81,7 +81,7 @@ export const useDeelzaakStore = defineStore('deelzaak', { }, /** - * @param params + * @param {object} params The params. * @spec openspec/changes/deelzaak-support/tasks.md#T08 */ async validateSubCase(params) { diff --git a/src/store/modules/processMining.js b/src/store/modules/processMining.js index c175874fb..9bb6b66bf 100644 --- a/src/store/modules/processMining.js +++ b/src/store/modules/processMining.js @@ -62,13 +62,13 @@ export const useProcessMiningStore = defineStore('processMining', { getters: { /** - * @param state + * @param {object} state The Pinia store state. * @return {Array} Per-case-type report blocks, never null. * @spec openspec/changes/page-topology-cleanup/specs/analytics-dashboard-surface/spec.md */ caseTypesList: (state) => state.report?.caseTypes || [], /** - * @param state + * @param {object} state The Pinia store state. * @return {Array} Weekly throughput points, never null. * @spec openspec/changes/page-topology-cleanup/specs/analytics-dashboard-surface/spec.md */ diff --git a/src/store/modules/settings.js b/src/store/modules/settings.js index 0db4674ab..8c2fc4096 100644 --- a/src/store/modules/settings.js +++ b/src/store/modules/settings.js @@ -60,7 +60,7 @@ export const useSettingsStore = defineStore('settings', { }, /** - * @param settingsData + * @param {object} settingsData The settings data. * @spec openspec/changes/retrofit-2026-05-25-admin-settings/tasks.md */ async saveSettings(settingsData) { diff --git a/src/store/modules/zgwMapping.js b/src/store/modules/zgwMapping.js index 638dd7203..aa0002a46 100644 --- a/src/store/modules/zgwMapping.js +++ b/src/store/modules/zgwMapping.js @@ -50,8 +50,8 @@ export const useZgwMappingStore = defineStore('zgwMapping', { }, /** - * @param resourceKey - * @param config + * @param {string} resourceKey The resource key. + * @param {object} config The config. * @spec openspec/changes/retrofit-2026-05-24-zgw-api-mapping/tasks.md */ async saveMapping(resourceKey, config) { @@ -91,7 +91,7 @@ export const useZgwMappingStore = defineStore('zgwMapping', { }, /** - * @param resourceKey + * @param {string} resourceKey The resource key. * @spec openspec/changes/retrofit-2026-05-24-zgw-api-mapping/tasks.md */ async resetMapping(resourceKey) { diff --git a/src/utils/caseTypeValidation.js b/src/utils/caseTypeValidation.js index c83bc5d29..2f0123745 100644 --- a/src/utils/caseTypeValidation.js +++ b/src/utils/caseTypeValidation.js @@ -140,7 +140,7 @@ export function validateForPublish(caseType, statusTypes) { /** * - * @param field + * @param {object} field The field. */ function getFieldLabel(field) { const labels = { diff --git a/src/utils/doorlooptijdHelpers.js b/src/utils/doorlooptijdHelpers.js index 99fb4aaee..9181afc42 100644 --- a/src/utils/doorlooptijdHelpers.js +++ b/src/utils/doorlooptijdHelpers.js @@ -177,9 +177,9 @@ const DEFAULT_BINS = [ * @return {{ bins: Array<{ label, count }>, slaTargetDays: number|null }} */ /** - * @param completedCases - * @param caseTypes - * @param bins + * @param {Array} completedCases The completed cases. + * @param {Array} caseTypes The case types. + * @param {Array} bins The bins. * @spec openspec/specs/doorlooptijd-dashboard/spec.md */ export function computeProcessingTimeDistribution(completedCases, caseTypes, bins) { diff --git a/src/utils/openregisterCheck.js b/src/utils/openregisterCheck.js index fa408cbc5..7c388a75e 100644 --- a/src/utils/openregisterCheck.js +++ b/src/utils/openregisterCheck.js @@ -48,7 +48,7 @@ export async function checkOpenRegisterStatus() { * @return {string} */ /** - * @param status + * @param {string} status The status. * @spec openspec/specs/openregister-integration/spec.md */ export function getStatusMessage(status) { diff --git a/src/views/admin/SubstitutionAdmin.vue b/src/views/admin/SubstitutionAdmin.vue index 5c1579472..d30825362 100644 --- a/src/views/admin/SubstitutionAdmin.vue +++ b/src/views/admin/SubstitutionAdmin.vue @@ -198,7 +198,7 @@ export default { }, /** - * @param id + * @param {string} id Identifier of the id. * @spec openspec/specs/handler-vervanging-waarneming/spec.md */ async revoke(id) { @@ -211,7 +211,7 @@ export default { }, /** - * @param sub + * @param {object} sub The sub. * @spec openspec/specs/handler-vervanging-waarneming/spec.md */ async openActions(sub) { diff --git a/src/views/cases/DeelzaakList.vue b/src/views/cases/DeelzaakList.vue index d6c85eff5..b2f87a19f 100644 --- a/src/views/cases/DeelzaakList.vue +++ b/src/views/cases/DeelzaakList.vue @@ -431,7 +431,7 @@ export default { }, /** - * @param deletedId + * @param {string} deletedId Identifier of the deleted id. * @spec openspec/changes/deelzaak-support/tasks.md#T11 */ onParentDeleted(deletedId) { diff --git a/src/views/cases/components/AdviceRequestPanel.vue b/src/views/cases/components/AdviceRequestPanel.vue index 6e2e6dbec..7d0a5fed6 100644 --- a/src/views/cases/components/AdviceRequestPanel.vue +++ b/src/views/cases/components/AdviceRequestPanel.vue @@ -158,7 +158,7 @@ export default { methods: { /** - * @param status + * @param {string} status The status. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ getStatusLabel(status) { @@ -172,7 +172,7 @@ export default { }, /** - * @param response + * @param {object} response The response. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ getResponseLabel(response) { @@ -187,7 +187,7 @@ export default { }, /** - * @param dateStr + * @param {string} dateStr The date str, as a string. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ formatDate(dateStr) { @@ -198,7 +198,7 @@ export default { }, /** - * @param req + * @param {object} req The req. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ isOverdue(req) { diff --git a/src/views/cases/components/AdviesPanel.vue b/src/views/cases/components/AdviesPanel.vue index b37fdd4fd..eb3851265 100644 --- a/src/views/cases/components/AdviesPanel.vue +++ b/src/views/cases/components/AdviesPanel.vue @@ -169,7 +169,7 @@ export default { }, /** - * @param item + * @param {object} item The item. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ async onRemind(item) { @@ -181,7 +181,7 @@ export default { }, /** - * @param item + * @param {object} item The item. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ async onMarkReceived(item) { @@ -197,7 +197,7 @@ export default { }, /** - * @param item + * @param {object} item The item. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ onViewDocument(item) { @@ -207,7 +207,7 @@ export default { }, /** - * @param type + * @param {string} type The type. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ typeLabel(type) { @@ -217,7 +217,7 @@ export default { }, /** - * @param type + * @param {string} type The type. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ typeBadgeType(type) { @@ -225,7 +225,7 @@ export default { }, /** - * @param status + * @param {string} status The status. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ statusLabel(status) { @@ -238,7 +238,7 @@ export default { }, /** - * @param status + * @param {string} status The status. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ statusBadgeType(status) { @@ -251,7 +251,7 @@ export default { }, /** - * @param item + * @param {object} item The item. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ isOverdue(item) { @@ -262,7 +262,7 @@ export default { }, /** - * @param item + * @param {object} item The item. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ daysOverdue(item) { diff --git a/src/views/cases/components/EmailThread.vue b/src/views/cases/components/EmailThread.vue index f30d89b46..b37537feb 100644 --- a/src/views/cases/components/EmailThread.vue +++ b/src/views/cases/components/EmailThread.vue @@ -109,7 +109,7 @@ export default { methods: { /** - * @param dateStr + * @param {string} dateStr The date str, as a string. * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ formatDateTime(dateStr) { @@ -126,7 +126,7 @@ export default { }, /** - * @param body + * @param {object} body The body. * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ truncateBody(body) { @@ -143,7 +143,7 @@ export default { }, /** - * @param id + * @param {string} id Identifier of the id. * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ toggleExpand(id) { diff --git a/src/views/cases/components/InspectionPanel.vue b/src/views/cases/components/InspectionPanel.vue index db02fe734..45d40792d 100644 --- a/src/views/cases/components/InspectionPanel.vue +++ b/src/views/cases/components/InspectionPanel.vue @@ -347,7 +347,7 @@ export default { caseId: { immediate: true, /** - * @param newId + * @param {string} newId Identifier of the new id. * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ handler(newId) { @@ -360,7 +360,7 @@ export default { caseTypeId: { immediate: true, /** - * @param newId + * @param {string} newId Identifier of the new id. * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ handler(newId) { @@ -391,7 +391,7 @@ export default { t, /** - * @param result + * @param {object} result The result. * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ resultLabel(result) { @@ -404,7 +404,7 @@ export default { }, /** - * @param dateStr + * @param {string} dateStr The date str, as a string. * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ formatDate(dateStr) { @@ -415,7 +415,7 @@ export default { }, /** - * @param reportId + * @param {string} reportId Identifier of the report id. * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ toggleReport(reportId) { diff --git a/src/views/casetypes/components/EmailTemplateAdmin.vue b/src/views/casetypes/components/EmailTemplateAdmin.vue index df5152eb4..89200f623 100644 --- a/src/views/casetypes/components/EmailTemplateAdmin.vue +++ b/src/views/casetypes/components/EmailTemplateAdmin.vue @@ -231,7 +231,7 @@ export default { methods: { /** - * @param name + * @param {string} name The name. * @spec openspec/specs/case-email-integration/spec.md */ varToken(name) { @@ -320,7 +320,7 @@ export default { }, /** - * @param name + * @param {string} name The name. * @spec openspec/specs/case-email-integration/spec.md */ insertVariable(name) { diff --git a/src/views/public/ExternalConsultationResponsePage.vue b/src/views/public/ExternalConsultationResponsePage.vue index fd34d02c5..3d87c048d 100644 --- a/src/views/public/ExternalConsultationResponsePage.vue +++ b/src/views/public/ExternalConsultationResponsePage.vue @@ -310,7 +310,7 @@ export default { }, /** - * @param idx + * @param {number} idx The index. * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-06 */ removeVoorwaarde(idx) { @@ -347,7 +347,7 @@ export default { }, /** - * @param dateStr + * @param {string} dateStr The date str, as a string. * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-06 */ formatDate(dateStr) { diff --git a/src/views/public/PublicAppointmentPage.vue b/src/views/public/PublicAppointmentPage.vue index 043831ebf..5b1987701 100644 --- a/src/views/public/PublicAppointmentPage.vue +++ b/src/views/public/PublicAppointmentPage.vue @@ -90,7 +90,7 @@ export default { }, /** - * @param status + * @param {string} status The status. * @spec openspec/changes/retrofit-2026-05-25-appointment-booking/tasks.md */ statusLabel(status) { diff --git a/src/views/settings/CaseTypeAdmin.vue b/src/views/settings/CaseTypeAdmin.vue index dfb209be6..eadb55c12 100644 --- a/src/views/settings/CaseTypeAdmin.vue +++ b/src/views/settings/CaseTypeAdmin.vue @@ -30,7 +30,7 @@ export default { methods: { /** - * @param id + * @param {string} id Identifier of the id. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ openDetail(id) { @@ -51,7 +51,7 @@ export default { }, /** - * @param id + * @param {string} id Identifier of the id. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ onSaved(id) { diff --git a/src/views/settings/CaseTypeDetail.vue b/src/views/settings/CaseTypeDetail.vue index 403458043..f16595ab1 100644 --- a/src/views/settings/CaseTypeDetail.vue +++ b/src/views/settings/CaseTypeDetail.vue @@ -299,7 +299,7 @@ export default { }, /** - * @param field + * @param {object} field The field. * @param value * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ diff --git a/src/views/settings/CaseTypeList.vue b/src/views/settings/CaseTypeList.vue index 67199fea5..0abc8e041 100644 --- a/src/views/settings/CaseTypeList.vue +++ b/src/views/settings/CaseTypeList.vue @@ -157,7 +157,7 @@ export default { }, /** - * @param caseTypeId + * @param {string} caseTypeId Identifier of the case type id. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ async loadStatusTypeCount(caseTypeId) { @@ -217,7 +217,7 @@ export default { }, /** - * @param row + * @param {object} row The row. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ selectCaseType(row) { diff --git a/src/views/settings/SubstitutionSettings.vue b/src/views/settings/SubstitutionSettings.vue index f4720b8f6..4b1b59112 100644 --- a/src/views/settings/SubstitutionSettings.vue +++ b/src/views/settings/SubstitutionSettings.vue @@ -146,7 +146,7 @@ export default { }, /** - * @param id + * @param {string} id Identifier of the id. * @spec openspec/specs/handler-vervanging-waarneming/spec.md */ async revoke(id) { diff --git a/src/views/settings/WorkflowEditor.vue b/src/views/settings/WorkflowEditor.vue index 2474abff1..88824791b 100644 --- a/src/views/settings/WorkflowEditor.vue +++ b/src/views/settings/WorkflowEditor.vue @@ -284,7 +284,7 @@ export default { }, /** - * @param statusId + * @param {string} statusId Identifier of the status id. * @spec openspec/specs/workflow-definition-model/spec.md */ getStepsForStatus(statusId) { @@ -294,7 +294,7 @@ export default { }, /** - * @param statusId + * @param {string} statusId Identifier of the status id. * @spec openspec/specs/workflow-definition-model/spec.md */ getNodeCenter(statusId) { @@ -308,7 +308,7 @@ export default { // --- Selection --- /** - * @param statusId + * @param {string} statusId Identifier of the status id. * @spec openspec/specs/workflow-definition-model/spec.md */ selectNode(statusId) { @@ -318,7 +318,7 @@ export default { }, /** - * @param transitionId + * @param {string} transitionId Identifier of the transition id. * @spec openspec/specs/workflow-definition-model/spec.md */ selectTransition(transitionId) { @@ -328,7 +328,7 @@ export default { }, /** - * @param transitionId + * @param {string} transitionId Identifier of the transition id. * @spec openspec/specs/workflow-definition-model/spec.md */ editTransition(transitionId) { @@ -336,7 +336,7 @@ export default { }, /** - * @param step + * @param {object} step The step. * @spec openspec/specs/workflow-definition-model/spec.md */ onStepClick(step) { @@ -347,8 +347,8 @@ export default { // --- Node drag --- /** - * @param statusId - * @param event + * @param {string} statusId Identifier of the status id. + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onNodeDragStart(statusId, event) { @@ -360,7 +360,7 @@ export default { }, /** - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onCanvasMouseMove(event) { @@ -402,7 +402,7 @@ export default { }, /** - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onCanvasMouseDown(event) { @@ -423,7 +423,7 @@ export default { }, /** - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onCanvasWheel(event) { @@ -434,8 +434,8 @@ export default { // --- Connection drawing --- /** - * @param statusId - * @param event + * @param {string} statusId Identifier of the status id. + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onConnectionStart(statusId, event) { @@ -450,7 +450,7 @@ export default { }, /** - * @param statusId + * @param {string} statusId Identifier of the status id. * @spec openspec/specs/workflow-definition-model/spec.md */ onConnectionEnd(statusId) { @@ -469,7 +469,7 @@ export default { // --- Palette drag & drop --- /** - * @param type + * @param {string} type The type. * @spec openspec/specs/workflow-definition-model/spec.md */ onPaletteDragStart(type) { @@ -477,7 +477,7 @@ export default { }, /** - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ async onCanvasDrop(event) { @@ -645,7 +645,7 @@ export default { // --- Step management --- /** - * @param statusId + * @param {string} statusId Identifier of the status id. * @spec openspec/specs/workflow-definition-model/spec.md */ onAddStep(statusId) { @@ -678,7 +678,7 @@ export default { }, /** - * @param transitionId + * @param {string} transitionId Identifier of the transition id. * @spec openspec/specs/workflow-definition-model/spec.md */ onTransitionDelete(transitionId) { diff --git a/src/views/settings/ZgwMappingSettings.vue b/src/views/settings/ZgwMappingSettings.vue index e7c346f0e..0e33b7f14 100644 --- a/src/views/settings/ZgwMappingSettings.vue +++ b/src/views/settings/ZgwMappingSettings.vue @@ -106,7 +106,7 @@ export default { methods: { /** - * @param key + * @param {string} key The key. * @spec openspec/changes/retrofit-2026-05-24-zgw-api-mapping/tasks.md */ editMapping(key) { @@ -114,7 +114,7 @@ export default { }, /** - * @param config + * @param {object} config The config. * @spec openspec/changes/retrofit-2026-05-24-zgw-api-mapping/tasks.md */ async saveMapping(config) { @@ -129,7 +129,7 @@ export default { }, /** - * @param key + * @param {string} key The key. * @spec openspec/changes/retrofit-2026-05-24-zgw-api-mapping/tasks.md */ async resetMapping(key) { diff --git a/src/views/settings/components/MandaatImportPanel.vue b/src/views/settings/components/MandaatImportPanel.vue index a780335a9..99d0c9f86 100644 --- a/src/views/settings/components/MandaatImportPanel.vue +++ b/src/views/settings/components/MandaatImportPanel.vue @@ -125,7 +125,7 @@ export default { methods: { t, /** - * @param e + * @param {Event} e The originating DOM event. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ onFileChange(e) { diff --git a/src/views/settings/components/MandaatMatrixTable.vue b/src/views/settings/components/MandaatMatrixTable.vue index 0f1ac5c9c..8f38af149 100644 --- a/src/views/settings/components/MandaatMatrixTable.vue +++ b/src/views/settings/components/MandaatMatrixTable.vue @@ -99,7 +99,7 @@ export default { methods: { t, /** - * @param status + * @param {string} status The status. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ badgeClass(status) { diff --git a/src/views/settings/components/MandaatToewijzingenTable.vue b/src/views/settings/components/MandaatToewijzingenTable.vue index d9f176352..84796aa43 100644 --- a/src/views/settings/components/MandaatToewijzingenTable.vue +++ b/src/views/settings/components/MandaatToewijzingenTable.vue @@ -169,7 +169,7 @@ export default { }, /** - * @param payload + * @param {object} payload The payload. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ async onAdd(payload) { diff --git a/src/views/settings/components/OrganisatieRolManager.vue b/src/views/settings/components/OrganisatieRolManager.vue index 382f3cd7b..2882324ba 100644 --- a/src/views/settings/components/OrganisatieRolManager.vue +++ b/src/views/settings/components/OrganisatieRolManager.vue @@ -160,7 +160,7 @@ export default { }, /** - * @param payload + * @param {object} payload The payload. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ async onSave(payload) { diff --git a/src/views/settings/components/StepConfigPanel.vue b/src/views/settings/components/StepConfigPanel.vue index 38031bad8..3c054a7b1 100644 --- a/src/views/settings/components/StepConfigPanel.vue +++ b/src/views/settings/components/StepConfigPanel.vue @@ -420,7 +420,7 @@ export default { methods: { /** - * @param config + * @param {object} config The config. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ parseConfig(config) { @@ -564,7 +564,7 @@ export default { }, /** - * @param actions + * @param {Array} actions The actions. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ parseActions(actions) { @@ -616,7 +616,7 @@ export default { /** * @param index - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ onCheckDragStart(index, event) { @@ -625,8 +625,8 @@ export default { }, /** - * @param targetIndex - * @param event + * @param {number} targetIndex The target index. + * @param {Event} event The originating DOM event. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ onCheckDrop(targetIndex, event) { diff --git a/src/views/settings/components/TransitionConfigPanel.vue b/src/views/settings/components/TransitionConfigPanel.vue index b35228801..cc50f6c75 100644 --- a/src/views/settings/components/TransitionConfigPanel.vue +++ b/src/views/settings/components/TransitionConfigPanel.vue @@ -335,7 +335,7 @@ export default { methods: { /** - * @param guards + * @param {Array} guards The guards. * @spec openspec/specs/status-transition-engine/spec.md */ parseGuards(guards) { @@ -351,7 +351,7 @@ export default { }, /** - * @param actions + * @param {Array} actions The actions. * @spec openspec/specs/status-transition-engine/spec.md */ parseActions(actions) { @@ -377,7 +377,7 @@ export default { }, /** - * @param roleId + * @param {string} roleId Identifier of the role id. * @spec openspec/specs/status-transition-engine/spec.md */ toggleRole(roleId) { diff --git a/src/views/settings/components/WorkflowNode.vue b/src/views/settings/components/WorkflowNode.vue index 7cb07073b..040ce0474 100644 --- a/src/views/settings/components/WorkflowNode.vue +++ b/src/views/settings/components/WorkflowNode.vue @@ -205,7 +205,7 @@ export default { }, /** - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onMouseDown(event) { @@ -216,7 +216,7 @@ export default { }, /** - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onConnectionStartFromPort(event) { @@ -224,8 +224,8 @@ export default { }, /** - * @param step - * @param event + * @param {object} step The step. + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onStepDragStart(step, event) { @@ -236,7 +236,7 @@ export default { /** * @param targetStep - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onStepDrop(targetStep, event) { diff --git a/src/views/settings/components/WorkflowPalette.vue b/src/views/settings/components/WorkflowPalette.vue index 39f0cf4ec..677608892 100644 --- a/src/views/settings/components/WorkflowPalette.vue +++ b/src/views/settings/components/WorkflowPalette.vue @@ -76,8 +76,8 @@ export default { emits: ['drag-start', 'add-status'], methods: { /** - * @param type - * @param event + * @param {string} type The type. + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ onDragStart(type, event) { diff --git a/src/views/settings/tabs/AiSettingsTab.vue b/src/views/settings/tabs/AiSettingsTab.vue index 3bb9ddde7..4f9fb28e9 100644 --- a/src/views/settings/tabs/AiSettingsTab.vue +++ b/src/views/settings/tabs/AiSettingsTab.vue @@ -233,7 +233,7 @@ export default { methods: { t, /** - * @param key + * @param {string} key The key. * @param value * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ diff --git a/src/views/settings/tabs/DocumentTypesTab.vue b/src/views/settings/tabs/DocumentTypesTab.vue index b39fcee01..bf2edb6e5 100644 --- a/src/views/settings/tabs/DocumentTypesTab.vue +++ b/src/views/settings/tabs/DocumentTypesTab.vue @@ -209,7 +209,7 @@ export default { }, /** - * @param item + * @param {object} item The item. * @spec openspec/changes/retrofit-2026-05-25-admin-settings/tasks.md */ startEdit(item) { @@ -254,7 +254,7 @@ export default { }, /** - * @param item + * @param {object} item The item. * @spec openspec/changes/retrofit-2026-05-25-admin-settings/tasks.md */ async deleteItem(item) { diff --git a/src/views/settings/tabs/MandaatMatrixTab.vue b/src/views/settings/tabs/MandaatMatrixTab.vue index 3c54e61f6..ce9c8f1ad 100644 --- a/src/views/settings/tabs/MandaatMatrixTab.vue +++ b/src/views/settings/tabs/MandaatMatrixTab.vue @@ -213,7 +213,7 @@ export default { }, /** - * @param payload + * @param {object} payload The payload. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ async onMandaatSave(payload) { diff --git a/src/views/settings/tabs/StatusesTab.vue b/src/views/settings/tabs/StatusesTab.vue index 21da886ef..794f30b10 100644 --- a/src/views/settings/tabs/StatusesTab.vue +++ b/src/views/settings/tabs/StatusesTab.vue @@ -496,7 +496,7 @@ export default { // Drag and drop /** * @param index - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/status-transition-engine/spec.md */ onDragStart(index, event) { @@ -519,7 +519,7 @@ export default { }, /** - * @param targetIndex + * @param {number} targetIndex The target index. * @spec openspec/specs/status-transition-engine/spec.md */ async onDrop(targetIndex) { diff --git a/src/views/settings/tabs/TermijnDefinitiesTab.vue b/src/views/settings/tabs/TermijnDefinitiesTab.vue index ba0139adc..afbcd3f3d 100644 --- a/src/views/settings/tabs/TermijnDefinitiesTab.vue +++ b/src/views/settings/tabs/TermijnDefinitiesTab.vue @@ -219,7 +219,7 @@ export default { }, /** - * @param payload + * @param {object} payload The payload. * @spec openspec/changes/termijnbewaking-dwangsom-engine-11-tests-admin-docs/tasks.md */ async onSave(payload) { diff --git a/src/views/settings/tabs/WorkflowTab.vue b/src/views/settings/tabs/WorkflowTab.vue index cd76fa2f5..1a763a461 100644 --- a/src/views/settings/tabs/WorkflowTab.vue +++ b/src/views/settings/tabs/WorkflowTab.vue @@ -362,7 +362,7 @@ export default { }, /** - * @param event + * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ async handleImport(event) { diff --git a/tests/e2e/workflows/deelzaak-case-email.spec.ts b/tests/e2e/workflows/deelzaak-case-email.spec.ts index 4f23f3a9e..03e89e942 100644 --- a/tests/e2e/workflows/deelzaak-case-email.spec.ts +++ b/tests/e2e/workflows/deelzaak-case-email.spec.ts @@ -57,7 +57,7 @@ let caseTypeSeeded = false /** * Call a dossiq deelzaken endpoint with the run's CSRF token. - * @param path + * @param {string} path The path. */ async function deelzaken(path: string): Promise<{ status: number; body: any }> { const res = await api.get(`/index.php/apps/dossiq/api/deelzaken${path}`, { From 4c19bd1668f7f036ed9d4047d57e8a1337dace02 Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Fri, 4 Sep 2026 09:21:05 +0200 Subject: [PATCH 4/7] docs(spec): give every class and public method its @spec tag 435 warnings from CustomSniffs.Commenting.SpecTag, on 172 classes and 263 public methods. PHPCS is now at zero. The target is DERIVED, never invented, and that distinction is the whole of the work. The sniff only checks that an @spec tag EXISTS: it never resolves the path. So the cheap way to clear 435 warnings is to paste any spec path onto every method, which satisfies the gate and leaves 435 claims nobody verified. A wrong @spec is worse than a missing one, because a missing one reads as "unlinked" and a wrong one reads as "linked and checked". So the tag comes from evidence in the file itself: - for a METHOD, the @spec of the nearest sibling method above it, since the methods of one class serve one capability; - for a CLASS, the most common @spec among its own methods; - 198 of the 206 files already carried at least one @spec, which is what made 411 of the 435 derivable this way. The remaining 8 files carried none, so there was nothing to derive from. Those 24 tags were resolved by reading each file's subject matter and matching it to a spec that exists: ZgwController -> zgw-api-mapping ZgwAuthException -> zgw-autorisaties-api ZgwAuthValidationException -> zgw-autorisaties-api TenantMiddleware -> tenant-isolation Iv3TaakveldController -> iv3-taakveld-2023-refinement BrokerAssertionResult -> zaakportaal-mijngemeente (the DigiD / eHerkenning SAML broker is specified there) SettingsSection -> admin-settings AdminSettings -> admin-settings PHPUnit, PHPStan, Psalm and PHPMD all exit 0, and php -l passes on every changed file. --- lib/BackgroundJob/AdviceDeadlineJob.php | 2 ++ lib/BackgroundJob/AppointmentReminderJob.php | 2 ++ .../BerichtenboxReadStatusJob.php | 2 ++ lib/BackgroundJob/BottleneckDetectionJob.php | 2 ++ .../DeadlineNotificationDispatchJob.php | 2 ++ lib/BackgroundJob/EmailPdfRetryJob.php | 2 ++ lib/BackgroundJob/InboundEmailJob.php | 2 ++ lib/BackgroundJob/ResetMonthlyQuotasJob.php | 2 ++ lib/BackgroundJob/ShareMaintenanceJob.php | 2 ++ lib/BackgroundJob/StufRetryJob.php | 2 ++ lib/Command/BackfillLegalHoldsCommand.php | 2 ++ lib/Command/SeedBezwaarBeroepCommand.php | 2 ++ lib/Controller/AdviceController.php | 2 ++ lib/Controller/AiAuditExportController.php | 2 ++ lib/Controller/AiController.php | 2 ++ lib/Controller/AppointmentController.php | 2 ++ lib/Controller/BerichtenboxController.php | 2 ++ lib/Controller/BesluitvormingController.php | 2 ++ lib/Controller/BrcController.php | 2 ++ lib/Controller/ConsultationController.php | 2 ++ lib/Controller/DashboardController.php | 2 ++ lib/Controller/DeelzaakController.php | 2 ++ lib/Controller/DoorlooptijdController.php | 2 ++ lib/Controller/DrcController.php | 2 ++ lib/Controller/EmailController.php | 2 ++ lib/Controller/EmailTemplateController.php | 2 ++ lib/Controller/Iv3TaakveldController.php | 4 ++++ lib/Controller/KccContactController.php | 18 ++++++++++++++++++ lib/Controller/KccRoutingController.php | 6 ++++++ lib/Controller/MilestoneController.php | 2 ++ lib/Controller/NotesController.php | 2 ++ lib/Controller/NoticeOfDefaultController.php | 2 ++ lib/Controller/NrcController.php | 2 ++ lib/Controller/PublicAppointmentController.php | 2 ++ lib/Controller/PublicationController.php | 2 ++ lib/Controller/StufController.php | 2 ++ lib/Controller/TemplateController.php | 2 ++ lib/Controller/TenantController.php | 2 ++ lib/Controller/TenantOnboardingController.php | 10 ++++++++++ lib/Controller/TenantSaasController.php | 2 ++ lib/Controller/ZaakdossierController.php | 2 ++ lib/Controller/ZgwController.php | 2 ++ lib/Controller/ZgwMappingController.php | 2 ++ lib/Controller/ZrcController.php | 2 ++ lib/Controller/ZtcController.php | 2 ++ lib/Dashboard/CasesOverviewWidget.php | 14 ++++++++++++++ lib/Dashboard/DeadlineAlertsWidget.php | 14 ++++++++++++++ lib/Dashboard/MyTasksWidget.php | 14 ++++++++++++++ lib/Dashboard/OverdueCasesWidget.php | 14 ++++++++++++++ lib/Dashboard/StalledCasesWidget.php | 14 ++++++++++++++ lib/Dashboard/StartCaseWidget.php | 14 ++++++++++++++ lib/Dashboard/TaskRemindersWidget.php | 14 ++++++++++++++ lib/Flow/DossiqFlowNodeBase.php | 4 ++++ lib/Http/RangeStreamResponse.php | 4 ++++ lib/Listener/BezwaarLifecycleListener.php | 2 ++ lib/Listener/TermijnTimerFiredListener.php | 2 ++ lib/Mcp/DossiqToolProvider.php | 8 ++++++++ lib/Middleware/MandateDeniedException.php | 2 ++ lib/Middleware/MandateValidationMiddleware.php | 8 ++++++++ lib/Middleware/QuotaEnforcementMiddleware.php | 8 ++++++++ lib/Middleware/QuotaExceededException.php | 2 ++ .../TenantClaimMismatchException.php | 2 ++ .../TenantClaimValidationMiddleware.php | 6 ++++++ lib/Middleware/TenantContextMiddleware.php | 6 ++++++ lib/Middleware/TenantIsolationMiddleware.php | 12 ++++++++++++ lib/Middleware/TenantMiddleware.php | 6 ++++++ lib/Middleware/ZgwAuthException.php | 4 ++++ lib/Middleware/ZgwAuthMiddleware.php | 8 ++++++++ lib/Notification/Notifier.php | 8 ++++++++ .../BackfillInformatieobjectMetadata.php | 4 ++++ lib/Repair/DbValueMigrationPort.php | 2 ++ .../LinkInFlightContractDecisionsRepair.php | 2 ++ .../LinkInFlightRemainingDecisionsRepair.php | 2 ++ lib/Repair/MigrateWorkflowDefinitions.php | 4 ++++ lib/Repair/RenameDutchDirectionValues.php | 2 ++ lib/Repair/RenameDutchValueDecisions.php | 2 ++ lib/Repair/RenameDutchValues.php | 2 ++ lib/Repair/SeedBezwaarBeroepData.php | 4 ++++ lib/Repair/SeedBezwaarWorkflowDefinition.php | 4 ++++ lib/Repair/SeedLhsMatrix.php | 2 ++ lib/Sections/PersonalSection.php | 8 ++++++++ lib/Sections/SettingsSection.php | 10 ++++++++++ lib/Service/Actions/ActionResult.php | 2 ++ lib/Service/Actions/CallWebhookHandler.php | 2 ++ lib/Service/Actions/CreateDocumentHandler.php | 2 ++ lib/Service/Actions/MergeTemplateHandler.php | 2 ++ lib/Service/Actions/NotifyRoleHandler.php | 2 ++ .../Actions/ScheduleReminderHandler.php | 2 ++ lib/Service/Actions/SendEmailHandler.php | 2 ++ lib/Service/AdvisoryBodyService.php | 2 ++ .../AppointmentBackendInterface.php | 2 ++ lib/Service/AppointmentBackend/JccBackend.php | 2 ++ .../AppointmentBackend/QmaticBackend.php | 2 ++ lib/Service/AppointmentService.php | 4 ++++ lib/Service/Auth/BrokerAssertionResult.php | 8 ++++++++ lib/Service/Auth/DigidSamlAdapterInterface.php | 4 ++++ .../Auth/EHerkenningSamlAdapterInterface.php | 4 ++++ lib/Service/Auth/LogDigidSamlAdapter.php | 4 ++++ lib/Service/Auth/LogEHerkenningSamlAdapter.php | 4 ++++ lib/Service/Auth/SimulatorDigidSamlAdapter.php | 2 ++ .../Auth/SimulatorEHerkenningSamlAdapter.php | 2 ++ .../BerichtenboxAdapterInterface.php | 2 ++ .../BerichtenboxAdapter/MockAdapter.php | 2 ++ lib/Service/CaseDefinitionExportService.php | 2 ++ lib/Service/CaseEmailService.php | 2 ++ lib/Service/ConsultationService.php | 2 ++ lib/Service/DeadlineEscalationService.php | 2 ++ lib/Service/DeadlineExtensionService.php | 2 ++ lib/Service/DeadlinePauseService.php | 2 ++ lib/Service/DoorlooptijdService.php | 2 ++ lib/Service/DsoIntakeService.php | 4 ++++ lib/Service/DwangsomBezwaarService.php | 2 ++ lib/Service/DwangsomCalculationService.php | 2 ++ lib/Service/DwangsomUitbetalingService.php | 2 ++ lib/Service/EmailArchivalService.php | 2 ++ lib/Service/EmailTemplateService.php | 2 ++ .../Brp/BrpHaalCentraalAdapterInterface.php | 4 ++++ .../External/Brp/HaalCentraalBrpAdapter.php | 2 ++ .../External/Brp/LogBrpHaalCentraalAdapter.php | 2 ++ lib/Service/External/Kvk/KvkApiAdapter.php | 2 ++ .../Kvk/KvkHandelsregisterAdapterInterface.php | 4 ++++ .../Kvk/LogKvkHandelsregisterAdapter.php | 2 ++ .../External/Zgw/LogZgwExternalAdapter.php | 2 ++ .../Zgw/ZgwExternalAdapterInterface.php | 6 ++++++ .../External/Ztc/LogZtcCatalogiAdapter.php | 2 ++ .../Ztc/ZtcCatalogiAdapterInterface.php | 6 ++++++ lib/Service/InformatieobjectAccessGuard.php | 2 ++ lib/Service/Kcc/BelplanRoutingService.php | 2 ++ lib/Service/Kcc/CallbackService.php | 12 ++++++++++++ lib/Service/Kcc/ContactMomentService.php | 12 ++++++++++++ lib/Service/Kcc/RoutingEngine.php | 8 ++++++++ lib/Service/Kcc/RoutingRuleService.php | 10 ++++++++++ lib/Service/Kcc/SentimentService.php | 2 ++ lib/Service/Kcc/SlaCalculator.php | 18 ++++++++++++++++++ lib/Service/MandaatEscalatieService.php | 2 ++ lib/Service/MandaatGebruikService.php | 2 ++ lib/Service/MandaatImportService.php | 2 ++ lib/Service/MapTileService.php | 2 ++ lib/Service/MentionNotificationService.php | 2 ++ lib/Service/MilestoneService.php | 2 ++ lib/Service/NoticeOfDefaultService.php | 2 ++ lib/Service/NotificatieService.php | 2 ++ lib/Service/ObjectSchemaSlugResolver.php | 2 ++ lib/Service/Pdok/PdokBagService.php | 2 ++ lib/Service/PdokService.php | 10 ++++++++++ lib/Service/ProcessMiningService.php | 2 ++ lib/Service/SelectionReassignmentService.php | 2 ++ lib/Service/ShillinqIntegrationService.php | 6 ++++++ lib/Service/Stuf/CircuitBreakerService.php | 2 ++ lib/Service/Stuf/CircuitOpenException.php | 2 ++ lib/Service/Stuf/ContactBetrokkeneMapper.php | 2 ++ lib/Service/Stuf/NeedsInputDispatcher.php | 2 ++ lib/Service/Stuf/PayloadTooLargeException.php | 2 ++ lib/Service/Stuf/StufException.php | 2 ++ lib/Service/Stuf/StufHttpClient.php | 2 ++ lib/Service/Stuf/StufMessageHandler.php | 2 ++ lib/Service/Stuf/StufMessageParser.php | 2 ++ lib/Service/Stuf/StufVaultService.php | 2 ++ lib/Service/Stuf/TimeoutException.php | 2 ++ .../Stuf/VrijBerichtNotRegisteredException.php | 2 ++ .../Stuf/ZaaktypeNotMappedException.php | 2 ++ lib/Service/StufFieldMappingService.php | 2 ++ lib/Service/StufMessageBuilder.php | 2 ++ lib/Service/Subsidie/BeschikkingService.php | 4 ++++ lib/Service/Subsidie/BewijsstukService.php | 12 ++++++++++++ .../Subsidie/CofinancieringValidator.php | 8 ++++++++ lib/Service/Subsidie/StaatssteunClassifier.php | 12 ++++++++++++ .../Subsidie/SubsidieRegisterExporter.php | 6 ++++++ lib/Service/Subsidie/SubsidieService.php | 16 ++++++++++++++++ lib/Service/Subsidie/TerugvorderingService.php | 8 ++++++++ .../Subsidie/TussenrapportageService.php | 4 ++++ lib/Service/Support/SeedSummary.php | 8 ++++++++ lib/Service/TemplateLibraryService.php | 2 ++ lib/Service/TenantAuditTrailService.php | 4 ++++ lib/Service/TenantAuthenticationService.php | 6 ++++++ lib/Service/TenantBillingService.php | 8 ++++++++ lib/Service/TenantConfigurationService.php | 12 ++++++++++++ lib/Service/TenantContext.php | 16 ++++++++++++++++ lib/Service/TenantJwtService.php | 6 ++++++ lib/Service/TenantLifecycleControlService.php | 4 ++++ lib/Service/TenantOnboardingService.php | 4 ++++ lib/Service/TenantProvisioningService.php | 6 ++++++ lib/Service/TenantQuotaService.php | 14 ++++++++++++++ lib/Service/TenantSaasService.php | 8 ++++++++ lib/Service/TenantSchemaProvisioner.php | 8 ++++++++ lib/Service/TenantSeedService.php | 2 ++ lib/Service/TenantService.php | 4 ++++ lib/Service/TenantSessionService.php | 2 ++ lib/Service/TenantWelcomeMailer.php | 4 ++++ lib/Service/TermijnNotificationService.php | 2 ++ lib/Service/TermijnTimerService.php | 2 ++ lib/Service/TranscriptionService.php | 2 ++ .../Transitions/ActionHandlerRegistry.php | 4 ++++ .../Transitions/GuardFailedException.php | 2 ++ lib/Service/ZaakdossierService.php | 2 ++ lib/Service/ZgwAuthValidationException.php | 2 ++ lib/Service/ZgwBrcRulesService.php | 2 ++ lib/Service/ZgwDrcRulesService.php | 2 ++ lib/Service/ZgwMappingService.php | 6 ++++++ lib/Service/ZgwPaginationHelper.php | 2 ++ lib/Service/ZgwService.php | 16 ++++++++++++++++ lib/Service/ZgwZrcRulesService.php | 2 ++ lib/Service/ZgwZtcRulesService.php | 2 ++ lib/Service/ZipManifestBuilder.php | 2 ++ lib/Settings/AdminSettings.php | 12 ++++++++++++ lib/Settings/EmailSettings.php | 8 ++++++++ 206 files changed, 870 insertions(+) diff --git a/lib/BackgroundJob/AdviceDeadlineJob.php b/lib/BackgroundJob/AdviceDeadlineJob.php index 9359cdcd6..bfbd44d28 100644 --- a/lib/BackgroundJob/AdviceDeadlineJob.php +++ b/lib/BackgroundJob/AdviceDeadlineJob.php @@ -39,6 +39,8 @@ /** * Daily timed job that processes advice request deadlines and reminders. + * + * @spec openspec/specs/advice-management/spec.md */ class AdviceDeadlineJob extends TimedJob { /** diff --git a/lib/BackgroundJob/AppointmentReminderJob.php b/lib/BackgroundJob/AppointmentReminderJob.php index 18af45eae..fd1602b90 100644 --- a/lib/BackgroundJob/AppointmentReminderJob.php +++ b/lib/BackgroundJob/AppointmentReminderJob.php @@ -34,6 +34,8 @@ /** * Daily timed job that sends appointment reminders for next-day appointments. + * + * @spec openspec/specs/appointment-booking/spec.md */ class AppointmentReminderJob extends TimedJob { /** diff --git a/lib/BackgroundJob/BerichtenboxReadStatusJob.php b/lib/BackgroundJob/BerichtenboxReadStatusJob.php index c7c939ed1..9f18d4ec4 100644 --- a/lib/BackgroundJob/BerichtenboxReadStatusJob.php +++ b/lib/BackgroundJob/BerichtenboxReadStatusJob.php @@ -33,6 +33,8 @@ /** * Daily timed job that polls Berichtenbox read status for sent messages. + * + * @spec openspec/specs/berichtenbox-integration/spec.md */ class BerichtenboxReadStatusJob extends TimedJob { /** diff --git a/lib/BackgroundJob/BottleneckDetectionJob.php b/lib/BackgroundJob/BottleneckDetectionJob.php index 84deff014..22a5b71ed 100644 --- a/lib/BackgroundJob/BottleneckDetectionJob.php +++ b/lib/BackgroundJob/BottleneckDetectionJob.php @@ -41,6 +41,8 @@ /** * Daily timed job that detects milestone bottlenecks and notifies case workers. + * + * @spec openspec/specs/milestone-tracking/spec.md */ class BottleneckDetectionJob extends TimedJob { /** diff --git a/lib/BackgroundJob/DeadlineNotificationDispatchJob.php b/lib/BackgroundJob/DeadlineNotificationDispatchJob.php index d958dcd92..41baa66d9 100644 --- a/lib/BackgroundJob/DeadlineNotificationDispatchJob.php +++ b/lib/BackgroundJob/DeadlineNotificationDispatchJob.php @@ -41,6 +41,8 @@ * Asynchronous queued notification dispatcher. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-08-burger-notifications/tasks.md */ class DeadlineNotificationDispatchJob extends QueuedJob { /** diff --git a/lib/BackgroundJob/EmailPdfRetryJob.php b/lib/BackgroundJob/EmailPdfRetryJob.php index 51b1a7553..1a2370462 100644 --- a/lib/BackgroundJob/EmailPdfRetryJob.php +++ b/lib/BackgroundJob/EmailPdfRetryJob.php @@ -37,6 +37,8 @@ /** * Retries failed PDF archival attempts on a 15-minute cadence. + * + * @spec openspec/changes/case-email-integration/tasks.md#T09 */ class EmailPdfRetryJob extends TimedJob { /** diff --git a/lib/BackgroundJob/InboundEmailJob.php b/lib/BackgroundJob/InboundEmailJob.php index bdc15b4aa..d191d043d 100644 --- a/lib/BackgroundJob/InboundEmailJob.php +++ b/lib/BackgroundJob/InboundEmailJob.php @@ -42,6 +42,8 @@ /** * Pulls inbound email from the shared mailbox and auto-links to cases. + * + * @spec openspec/changes/case-email-integration/tasks.md#T08 */ class InboundEmailJob extends TimedJob { diff --git a/lib/BackgroundJob/ResetMonthlyQuotasJob.php b/lib/BackgroundJob/ResetMonthlyQuotasJob.php index 8a6150c3f..24f72fd29 100644 --- a/lib/BackgroundJob/ResetMonthlyQuotasJob.php +++ b/lib/BackgroundJob/ResetMonthlyQuotasJob.php @@ -36,6 +36,8 @@ /** * Resets monthly + hourly quotas after their window elapses. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-09-quotas-enforcement/tasks.md */ class ResetMonthlyQuotasJob extends TimedJob { /** diff --git a/lib/BackgroundJob/ShareMaintenanceJob.php b/lib/BackgroundJob/ShareMaintenanceJob.php index 93c5bff0c..c3d917f49 100644 --- a/lib/BackgroundJob/ShareMaintenanceJob.php +++ b/lib/BackgroundJob/ShareMaintenanceJob.php @@ -39,6 +39,8 @@ * * Checks for shares expiring within 3 days and sends reminder * notifications to case workers. + * + * @spec openspec/specs/case-management/spec.md */ class ShareMaintenanceJob extends TimedJob { /** diff --git a/lib/BackgroundJob/StufRetryJob.php b/lib/BackgroundJob/StufRetryJob.php index 1e944a7f2..c36301964 100644 --- a/lib/BackgroundJob/StufRetryJob.php +++ b/lib/BackgroundJob/StufRetryJob.php @@ -36,6 +36,8 @@ /** * On-demand background job that retries a single StufMessage. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-circuit-breaker-and-retry */ class StufRetryJob extends Job { /** diff --git a/lib/Command/BackfillLegalHoldsCommand.php b/lib/Command/BackfillLegalHoldsCommand.php index 667e60b4a..d3ef422a4 100644 --- a/lib/Command/BackfillLegalHoldsCommand.php +++ b/lib/Command/BackfillLegalHoldsCommand.php @@ -59,6 +59,8 @@ * Backfill the Awb legal holds the dead bezwaar listener never placed. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) Remediation spans several OpenRegister collaborators. + * + * @spec openspec/specs/archief-edepot-handover/spec.md#requirement-legal-proceedings-must-suspend-archival-via-or-legal-holds */ class BackfillLegalHoldsCommand extends Command { diff --git a/lib/Command/SeedBezwaarBeroepCommand.php b/lib/Command/SeedBezwaarBeroepCommand.php index 953ebe88a..01885a972 100644 --- a/lib/Command/SeedBezwaarBeroepCommand.php +++ b/lib/Command/SeedBezwaarBeroepCommand.php @@ -40,6 +40,8 @@ /** * Seed the Bezwaar & Beroep case types, status types and role types. + * + * @spec openspec/specs/bezwaar-beroep-workflow/spec.md#requirement-req-bbw-001-bezwaar-casetype-seed-shall-be-installed-with-awb-compliant-process-configuration */ class SeedBezwaarBeroepCommand extends Command { /** diff --git a/lib/Controller/AdviceController.php b/lib/Controller/AdviceController.php index 2222ab304..aa7deefdd 100644 --- a/lib/Controller/AdviceController.php +++ b/lib/Controller/AdviceController.php @@ -43,6 +43,8 @@ /** * Controller for advice request workflow operations. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class AdviceController extends Controller { /** diff --git a/lib/Controller/AiAuditExportController.php b/lib/Controller/AiAuditExportController.php index 035ea693d..bf2abee4b 100644 --- a/lib/Controller/AiAuditExportController.php +++ b/lib/Controller/AiAuditExportController.php @@ -44,6 +44,8 @@ * Read-only action controller for the AI audit trail export. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/ai-oversight-log/tasks.md#2.1 */ class AiAuditExportController extends Controller { /** diff --git a/lib/Controller/AiController.php b/lib/Controller/AiController.php index bd27df387..7cfd9dbc1 100644 --- a/lib/Controller/AiController.php +++ b/lib/Controller/AiController.php @@ -48,6 +48,8 @@ * health endpoints live on {@see AiSettingsController}. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class AiController extends Controller { /** diff --git a/lib/Controller/AppointmentController.php b/lib/Controller/AppointmentController.php index 598011ff9..7624bf63b 100644 --- a/lib/Controller/AppointmentController.php +++ b/lib/Controller/AppointmentController.php @@ -36,6 +36,8 @@ /** * Controller exposing citizen appointment endpoints. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class AppointmentController extends Controller { /** diff --git a/lib/Controller/BerichtenboxController.php b/lib/Controller/BerichtenboxController.php index 3ff7c50a4..d967a4fe5 100644 --- a/lib/Controller/BerichtenboxController.php +++ b/lib/Controller/BerichtenboxController.php @@ -35,6 +35,8 @@ /** * Controller exposing Berichtenbox send/list/poll endpoints. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class BerichtenboxController extends Controller { /** diff --git a/lib/Controller/BesluitvormingController.php b/lib/Controller/BesluitvormingController.php index d3f0280ca..5e8c10866 100644 --- a/lib/Controller/BesluitvormingController.php +++ b/lib/Controller/BesluitvormingController.php @@ -42,6 +42,8 @@ * Controller exposing besluitvorming template-activation endpoints. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/besluitvorming-workflow/tasks.md#task-2 */ class BesluitvormingController extends Controller { /** diff --git a/lib/Controller/BrcController.php b/lib/Controller/BrcController.php index 79ef46691..915f16cd8 100644 --- a/lib/Controller/BrcController.php +++ b/lib/Controller/BrcController.php @@ -55,6 +55,8 @@ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class BrcController extends ZgwController { /** diff --git a/lib/Controller/ConsultationController.php b/lib/Controller/ConsultationController.php index c35cc361b..7a755264c 100644 --- a/lib/Controller/ConsultationController.php +++ b/lib/Controller/ConsultationController.php @@ -43,6 +43,8 @@ * * Every endpoint carries the NoAdminRequired annotation and applies the * ConsultationAccessGuard (OWASP A01:2021, ADR-005 Rule 3). + * + * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-04 */ class ConsultationController extends Controller { /** diff --git a/lib/Controller/DashboardController.php b/lib/Controller/DashboardController.php index 9d78f0d45..4b0803b13 100644 --- a/lib/Controller/DashboardController.php +++ b/lib/Controller/DashboardController.php @@ -56,6 +56,8 @@ * Controller for the main Dossiq dashboard page plus the PWA assets. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/adopt-apphost/tasks.md#task-2.1 */ class DashboardController extends Controller { /** diff --git a/lib/Controller/DeelzaakController.php b/lib/Controller/DeelzaakController.php index 28832ccc2..a2c502532 100644 --- a/lib/Controller/DeelzaakController.php +++ b/lib/Controller/DeelzaakController.php @@ -38,6 +38,8 @@ /** * REST controller for sub-case operations. + * + * @spec openspec/specs/authz-bypass-fixes/spec.md */ class DeelzaakController extends Controller { /** diff --git a/lib/Controller/DoorlooptijdController.php b/lib/Controller/DoorlooptijdController.php index 85b8eff70..5e24a474b 100644 --- a/lib/Controller/DoorlooptijdController.php +++ b/lib/Controller/DoorlooptijdController.php @@ -37,6 +37,8 @@ /** * REST controller for the throughput-time dashboard. + * + * @spec openspec/changes/doorlooptijd-dashboard/tasks.md#T02 */ class DoorlooptijdController extends Controller { /** diff --git a/lib/Controller/DrcController.php b/lib/Controller/DrcController.php index 7735231e5..adc98c83a 100644 --- a/lib/Controller/DrcController.php +++ b/lib/Controller/DrcController.php @@ -53,6 +53,8 @@ * @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class DrcController extends ZgwController { /** diff --git a/lib/Controller/EmailController.php b/lib/Controller/EmailController.php index 802519ef9..6f59005c0 100644 --- a/lib/Controller/EmailController.php +++ b/lib/Controller/EmailController.php @@ -35,6 +35,8 @@ /** * Controller for case email operations. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class EmailController extends Controller { /** diff --git a/lib/Controller/EmailTemplateController.php b/lib/Controller/EmailTemplateController.php index 58472869b..0900b4a8a 100644 --- a/lib/Controller/EmailTemplateController.php +++ b/lib/Controller/EmailTemplateController.php @@ -46,6 +46,8 @@ /** * REST controller for email-template templating + IMAP settings. + * + * @spec openspec/changes/case-email-integration/tasks.md#T06 */ class EmailTemplateController extends Controller { diff --git a/lib/Controller/Iv3TaakveldController.php b/lib/Controller/Iv3TaakveldController.php index c5d65dfe9..eca6eaca9 100644 --- a/lib/Controller/Iv3TaakveldController.php +++ b/lib/Controller/Iv3TaakveldController.php @@ -46,6 +46,8 @@ /** * Read-only access to the IV3/BBV taakveld reference list. + * + * @spec openspec/specs/iv3-taakveld-2023-refinement/spec.md */ class Iv3TaakveldController extends Controller { /** @@ -70,6 +72,8 @@ public function __construct( * is a public CBS classification, not report data). * * @return JSONResponse + * + * @spec openspec/specs/iv3-taakveld-2023-refinement/spec.md */ #[NoAdminRequired] public function taakvelden(): JSONResponse { diff --git a/lib/Controller/KccContactController.php b/lib/Controller/KccContactController.php index 0d88266cd..f5bd8de33 100644 --- a/lib/Controller/KccContactController.php +++ b/lib/Controller/KccContactController.php @@ -44,6 +44,8 @@ * Controller exposing KCC contact-moment and callback endpoints. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ class KccContactController extends Controller { /** @@ -73,6 +75,8 @@ public function __construct( * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function index(): JSONResponse { $agentId = $this->requireAgentId(); @@ -107,6 +111,8 @@ public function index(): JSONResponse { * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function create(): JSONResponse { $agentId = $this->requireAgentId(); @@ -133,6 +139,8 @@ public function create(): JSONResponse { * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function show(string $id): JSONResponse { $agentId = $this->requireAgentId(); @@ -163,6 +171,8 @@ public function show(string $id): JSONResponse { * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function update(string $id): JSONResponse { $agentId = $this->requireAgentId(); @@ -194,6 +204,8 @@ public function update(string $id): JSONResponse { * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function related(string $id): JSONResponse { $agentId = $this->requireAgentId(); @@ -222,6 +234,8 @@ public function related(string $id): JSONResponse { * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function scheduleCallback(): JSONResponse { $agentId = $this->requireAgentId(); @@ -246,6 +260,8 @@ public function scheduleCallback(): JSONResponse { * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function indexCallbacks(): JSONResponse { $agentId = $this->requireAgentId(); @@ -278,6 +294,8 @@ public function indexCallbacks(): JSONResponse { * @NoAdminRequired * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-16 */ public function cancelCallback(string $id): JSONResponse { $agentId = $this->requireAgentId(); diff --git a/lib/Controller/KccRoutingController.php b/lib/Controller/KccRoutingController.php index 1b5e3de64..faa4bf535 100644 --- a/lib/Controller/KccRoutingController.php +++ b/lib/Controller/KccRoutingController.php @@ -44,6 +44,8 @@ * Controller exposing KCC routing-rule and routing-evaluation endpoints. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-17 */ class KccRoutingController extends Controller { /** @@ -102,6 +104,8 @@ public function index(): JSONResponse { * @return JSONResponse * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-17 */ #[AuthorizedAdminSetting(settings: AdminSettings::class)] public function create(): JSONResponse { @@ -130,6 +134,8 @@ public function create(): JSONResponse { * @return JSONResponse * * @psalm-suppress PossiblyUnusedMethod + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-17 */ #[AuthorizedAdminSetting(settings: AdminSettings::class)] public function update(string $id): JSONResponse { diff --git a/lib/Controller/MilestoneController.php b/lib/Controller/MilestoneController.php index 746c213ae..aff2546b6 100644 --- a/lib/Controller/MilestoneController.php +++ b/lib/Controller/MilestoneController.php @@ -36,6 +36,8 @@ /** * Controller for milestone progress tracking. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class MilestoneController extends Controller { /** diff --git a/lib/Controller/NotesController.php b/lib/Controller/NotesController.php index 310bf9929..a8e784235 100644 --- a/lib/Controller/NotesController.php +++ b/lib/Controller/NotesController.php @@ -44,6 +44,8 @@ /** * Controller for note-mention notification side-effects. + * + * @spec openspec/specs/ncvue-w2-leaves-adoption/spec.md */ class NotesController extends Controller { /** diff --git a/lib/Controller/NoticeOfDefaultController.php b/lib/Controller/NoticeOfDefaultController.php index d3634ca03..b3d12cc53 100644 --- a/lib/Controller/NoticeOfDefaultController.php +++ b/lib/Controller/NoticeOfDefaultController.php @@ -40,6 +40,8 @@ * REST surface for ingebrekestelling registration. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-10-bezwaar-rest-api/tasks.md */ class NoticeOfDefaultController extends Controller { diff --git a/lib/Controller/NrcController.php b/lib/Controller/NrcController.php index 26be9187f..eb11ab330 100644 --- a/lib/Controller/NrcController.php +++ b/lib/Controller/NrcController.php @@ -44,6 +44,8 @@ * @psalm-suppress UnusedClass * * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class NrcController extends ZgwController { /** diff --git a/lib/Controller/PublicAppointmentController.php b/lib/Controller/PublicAppointmentController.php index 79a67d5db..3846af0fd 100644 --- a/lib/Controller/PublicAppointmentController.php +++ b/lib/Controller/PublicAppointmentController.php @@ -33,6 +33,8 @@ /** * Public (citizen-facing) endpoints for appointment view/cancel by token. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class PublicAppointmentController extends Controller { /** diff --git a/lib/Controller/PublicationController.php b/lib/Controller/PublicationController.php index ff873ba17..9762f0958 100644 --- a/lib/Controller/PublicationController.php +++ b/lib/Controller/PublicationController.php @@ -41,6 +41,8 @@ * Controller exposing besluitvorming publication endpoints. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/besluitvorming-workflow/tasks.md#task-7 */ class PublicationController extends Controller { /** diff --git a/lib/Controller/StufController.php b/lib/Controller/StufController.php index 7e9bec5e1..5059b05de 100644 --- a/lib/Controller/StufController.php +++ b/lib/Controller/StufController.php @@ -65,6 +65,8 @@ * @psalm-suppress UnusedClass * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class StufController extends Controller { /** diff --git a/lib/Controller/TemplateController.php b/lib/Controller/TemplateController.php index 8618932f6..b6ad9aed0 100644 --- a/lib/Controller/TemplateController.php +++ b/lib/Controller/TemplateController.php @@ -35,6 +35,8 @@ /** * Controller for zaaktype template management. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class TemplateController extends Controller { /** diff --git a/lib/Controller/TenantController.php b/lib/Controller/TenantController.php index 503703f64..d06cbef2b 100644 --- a/lib/Controller/TenantController.php +++ b/lib/Controller/TenantController.php @@ -49,6 +49,8 @@ * pages call the OpenRegister object endpoints directly. Only the three domain * methods below remain: they wrap provisioning workflow, resource-usage * aggregation, and current-tenant resolution. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class TenantController extends Controller { /** diff --git a/lib/Controller/TenantOnboardingController.php b/lib/Controller/TenantOnboardingController.php index 904cf69ca..0bf4b4923 100644 --- a/lib/Controller/TenantOnboardingController.php +++ b/lib/Controller/TenantOnboardingController.php @@ -35,6 +35,8 @@ /** * Onboarding REST controller. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-07-onboarding-workflow/tasks.md */ class TenantOnboardingController extends Controller { /** @@ -58,6 +60,8 @@ public function __construct( * @param string $tenantId Tenant UUID. * * @return JSONResponse + * + * @spec openspec/changes/tenant-zaaksysteem-saas-07-onboarding-workflow/tasks.md */ #[AuthorizedAdminSetting(AdminSettings::class)] public function progress(string $tenantId): JSONResponse { @@ -76,6 +80,8 @@ public function progress(string $tenantId): JSONResponse { * @param string $step Step name. * * @return JSONResponse + * + * @spec openspec/changes/tenant-zaaksysteem-saas-07-onboarding-workflow/tasks.md */ #[AuthorizedAdminSetting(AdminSettings::class)] public function complete(string $tenantId, string $step): JSONResponse { @@ -107,6 +113,8 @@ public function complete(string $tenantId, string $step): JSONResponse { * @param string $tenantId Tenant UUID. * * @return JSONResponse + * + * @spec openspec/changes/tenant-zaaksysteem-saas-07-onboarding-workflow/tasks.md */ #[AuthorizedAdminSetting(AdminSettings::class)] public function activate(string $tenantId): JSONResponse { @@ -125,6 +133,8 @@ public function activate(string $tenantId): JSONResponse { * @param string $tenantId Tenant UUID. * * @return JSONResponse + * + * @spec openspec/changes/tenant-zaaksysteem-saas-07-onboarding-workflow/tasks.md */ #[AuthorizedAdminSetting(AdminSettings::class)] public function initialise(string $tenantId): JSONResponse { diff --git a/lib/Controller/TenantSaasController.php b/lib/Controller/TenantSaasController.php index f410e1845..0f926d570 100644 --- a/lib/Controller/TenantSaasController.php +++ b/lib/Controller/TenantSaasController.php @@ -51,6 +51,8 @@ * PATCH /api/saas/tenants/{tenantId} → update (display + optional status) * DELETE /api/saas/tenants/{tenantId} → destroy * POST /api/saas/tenants/{tenantId}/status → transition + * + * @spec openspec/changes/tenant-zaaksysteem-saas-02-tenant-crud-lifecycle/tasks.md */ class TenantSaasController extends Controller { /** diff --git a/lib/Controller/ZaakdossierController.php b/lib/Controller/ZaakdossierController.php index 5ed9a5622..46a5217a0 100644 --- a/lib/Controller/ZaakdossierController.php +++ b/lib/Controller/ZaakdossierController.php @@ -47,6 +47,8 @@ /** * Controller for the ZGW DRC zaakdossier. + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T05 */ class ZaakdossierController extends Controller { /** diff --git a/lib/Controller/ZgwController.php b/lib/Controller/ZgwController.php index 47e66c318..e54357252 100644 --- a/lib/Controller/ZgwController.php +++ b/lib/Controller/ZgwController.php @@ -38,6 +38,8 @@ * controllers fall under ZGW JWT authentication and scope enforcement. * Any controller that handles a ZGW API endpoint must extend this class * so the middleware's guard is actually exercised. + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ abstract class ZgwController extends Controller { use NormalisesObjectRows; diff --git a/lib/Controller/ZgwMappingController.php b/lib/Controller/ZgwMappingController.php index d53b4180e..c7c49f658 100644 --- a/lib/Controller/ZgwMappingController.php +++ b/lib/Controller/ZgwMappingController.php @@ -41,6 +41,8 @@ /** * Controller for managing ZGW API mapping configurations. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZgwMappingController extends Controller { /** diff --git a/lib/Controller/ZrcController.php b/lib/Controller/ZrcController.php index ad1e79ff1..2a55bbbf6 100644 --- a/lib/Controller/ZrcController.php +++ b/lib/Controller/ZrcController.php @@ -58,6 +58,8 @@ * @SuppressWarnings(PHPMD.NPathComplexity) * @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZrcController extends ZgwController { /** diff --git a/lib/Controller/ZtcController.php b/lib/Controller/ZtcController.php index 6b49bab78..21c11557c 100644 --- a/lib/Controller/ZtcController.php +++ b/lib/Controller/ZtcController.php @@ -50,6 +50,8 @@ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.NPathComplexity) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZtcController extends ZgwController { /** diff --git a/lib/Dashboard/CasesOverviewWidget.php b/lib/Dashboard/CasesOverviewWidget.php index 3edb51aea..ccda3f3a7 100644 --- a/lib/Dashboard/CasesOverviewWidget.php +++ b/lib/Dashboard/CasesOverviewWidget.php @@ -36,6 +36,8 @@ /** * Dashboard widget showing an overview of recent cases. + * + * @spec openspec/specs/dashboard/spec.md */ class CasesOverviewWidget implements IWidget { /** @@ -55,6 +57,8 @@ public function __construct( * * @inheritDoc * @return string The widget identifier + * + * @spec openspec/specs/dashboard/spec.md */ public function getId(): string { // FROZEN at `procest_*` — deliberately NOT renamed with the app id. @@ -73,6 +77,8 @@ public function getId(): string { * * @inheritDoc * @return string The widget title + * + * @spec openspec/specs/dashboard/spec.md */ public function getTitle(): string { return $this->l10n->t('Cases overview'); @@ -83,6 +89,8 @@ public function getTitle(): string { * * @inheritDoc * @return int The widget order + * + * @spec openspec/specs/dashboard/spec.md */ public function getOrder(): int { return 10; @@ -93,6 +101,8 @@ public function getOrder(): int { * * @inheritDoc * @return string The icon CSS class + * + * @spec openspec/specs/dashboard/spec.md */ public function getIconClass(): string { return 'icon-dossiq-widget'; @@ -103,6 +113,8 @@ public function getIconClass(): string { * * @inheritDoc * @return string|null The widget URL or null + * + * @spec openspec/specs/dashboard/spec.md */ public function getUrl(): ?string { return $this->url->linkToRouteAbsolute(Application::APP_ID . '.dashboard.page'); @@ -115,6 +127,8 @@ public function getUrl(): ?string { * @return void * * @SuppressWarnings(PHPMD.StaticAccess) — Nextcloud Util API is static by design + * + * @spec openspec/specs/dashboard/spec.md */ public function load(): void { // Shared vendor chunks emitted by webpack splitChunks (see webpack.config.js). diff --git a/lib/Dashboard/DeadlineAlertsWidget.php b/lib/Dashboard/DeadlineAlertsWidget.php index 12caf930a..bb8d19d8e 100644 --- a/lib/Dashboard/DeadlineAlertsWidget.php +++ b/lib/Dashboard/DeadlineAlertsWidget.php @@ -38,6 +38,8 @@ /** * Dashboard widget showing deadline alerts for cases. + * + * @spec openspec/specs/signalering-widgets/spec.md */ class DeadlineAlertsWidget implements IWidget { /** @@ -57,6 +59,8 @@ public function __construct( * * @inheritDoc * @return string The widget identifier + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getId(): string { // FROZEN at the old app-id prefix — see CasesOverviewWidget::getId(). @@ -68,6 +72,8 @@ public function getId(): string { * * @inheritDoc * @return string The widget title + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getTitle(): string { return $this->l10n->t('Deadline Alerts'); @@ -78,6 +84,8 @@ public function getTitle(): string { * * @inheritDoc * @return int The widget order + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getOrder(): int { return 11; @@ -88,6 +96,8 @@ public function getOrder(): int { * * @inheritDoc * @return string The icon CSS class + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getIconClass(): string { return 'icon-dossiq-widget'; @@ -98,6 +108,8 @@ public function getIconClass(): string { * * @inheritDoc * @return string|null The widget URL or null + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getUrl(): ?string { return $this->url->linkToRouteAbsolute(Application::APP_ID . '.dashboard.page'); @@ -110,6 +122,8 @@ public function getUrl(): ?string { * @return void * * @SuppressWarnings(PHPMD.StaticAccess) — Nextcloud Util API is static by design + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function load(): void { // Shared vendor chunks emitted by webpack splitChunks (see webpack.config.js). diff --git a/lib/Dashboard/MyTasksWidget.php b/lib/Dashboard/MyTasksWidget.php index a986c6198..b99470e9b 100644 --- a/lib/Dashboard/MyTasksWidget.php +++ b/lib/Dashboard/MyTasksWidget.php @@ -36,6 +36,8 @@ /** * Dashboard widget showing tasks assigned to the current user. + * + * @spec openspec/specs/dashboard/spec.md */ class MyTasksWidget implements IWidget { /** @@ -55,6 +57,8 @@ public function __construct( * * @inheritDoc * @return string The widget identifier + * + * @spec openspec/specs/dashboard/spec.md */ public function getId(): string { // FROZEN at the old app-id prefix — see CasesOverviewWidget::getId() @@ -70,6 +74,8 @@ public function getId(): string { * * @inheritDoc * @return string The widget title + * + * @spec openspec/specs/dashboard/spec.md */ public function getTitle(): string { return $this->l10n->t('My Tasks'); @@ -80,6 +86,8 @@ public function getTitle(): string { * * @inheritDoc * @return int The widget order + * + * @spec openspec/specs/dashboard/spec.md */ public function getOrder(): int { return 12; @@ -90,6 +98,8 @@ public function getOrder(): int { * * @inheritDoc * @return string The icon CSS class + * + * @spec openspec/specs/dashboard/spec.md */ public function getIconClass(): string { return 'icon-dossiq-widget'; @@ -100,6 +110,8 @@ public function getIconClass(): string { * * @inheritDoc * @return string|null The widget URL or null + * + * @spec openspec/specs/dashboard/spec.md */ public function getUrl(): ?string { return $this->url->linkToRouteAbsolute(Application::APP_ID . '.dashboard.page'); @@ -112,6 +124,8 @@ public function getUrl(): ?string { * @return void * * @SuppressWarnings(PHPMD.StaticAccess) — Nextcloud Util API is static by design + * + * @spec openspec/specs/dashboard/spec.md */ public function load(): void { // Shared vendor chunks emitted by webpack splitChunks (see webpack.config.js). diff --git a/lib/Dashboard/OverdueCasesWidget.php b/lib/Dashboard/OverdueCasesWidget.php index 825913df4..c0d167574 100644 --- a/lib/Dashboard/OverdueCasesWidget.php +++ b/lib/Dashboard/OverdueCasesWidget.php @@ -37,6 +37,8 @@ /** * Dashboard widget showing overdue cases with deadline info. + * + * @spec openspec/specs/signalering-widgets/spec.md */ class OverdueCasesWidget implements IWidget { /** @@ -56,6 +58,8 @@ public function __construct( * * @inheritDoc * @return string The widget identifier + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getId(): string { // FROZEN at the old app-id prefix — see CasesOverviewWidget::getId(). @@ -67,6 +71,8 @@ public function getId(): string { * * @inheritDoc * @return string The widget title + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getTitle(): string { return $this->l10n->t('Overdue Cases'); @@ -77,6 +83,8 @@ public function getTitle(): string { * * @inheritDoc * @return int The widget order + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getOrder(): int { return 11; @@ -87,6 +95,8 @@ public function getOrder(): int { * * @inheritDoc * @return string The icon CSS class + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getIconClass(): string { return 'icon-dossiq-widget'; @@ -97,6 +107,8 @@ public function getIconClass(): string { * * @inheritDoc * @return string|null The widget URL or null + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getUrl(): ?string { return $this->url->linkToRouteAbsolute(Application::APP_ID . '.dashboard.page'); @@ -109,6 +121,8 @@ public function getUrl(): ?string { * @return void * * @SuppressWarnings(PHPMD.StaticAccess) — Nextcloud Util API is static by design + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function load(): void { // Shared vendor chunks emitted by webpack splitChunks (see webpack.config.js). diff --git a/lib/Dashboard/StalledCasesWidget.php b/lib/Dashboard/StalledCasesWidget.php index 411bbaaaf..0161b449c 100644 --- a/lib/Dashboard/StalledCasesWidget.php +++ b/lib/Dashboard/StalledCasesWidget.php @@ -38,6 +38,8 @@ /** * Dashboard widget showing stalled (inactive) cases. + * + * @spec openspec/specs/signalering-widgets/spec.md */ class StalledCasesWidget implements IWidget { /** @@ -57,6 +59,8 @@ public function __construct( * * @inheritDoc * @return string The widget identifier + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getId(): string { // FROZEN at the old app-id prefix — see CasesOverviewWidget::getId(). @@ -68,6 +72,8 @@ public function getId(): string { * * @inheritDoc * @return string The widget title + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getTitle(): string { return $this->l10n->t('Stalled Cases'); @@ -78,6 +84,8 @@ public function getTitle(): string { * * @inheritDoc * @return int The widget order + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getOrder(): int { return 13; @@ -88,6 +96,8 @@ public function getOrder(): int { * * @inheritDoc * @return string The icon CSS class + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getIconClass(): string { return 'icon-dossiq-widget'; @@ -98,6 +108,8 @@ public function getIconClass(): string { * * @inheritDoc * @return string|null The widget URL or null + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getUrl(): ?string { return $this->url->linkToRouteAbsolute(Application::APP_ID . '.dashboard.page'); @@ -110,6 +122,8 @@ public function getUrl(): ?string { * @return void * * @SuppressWarnings(PHPMD.StaticAccess) — Nextcloud Util API is static by design + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function load(): void { // Shared vendor chunks emitted by webpack splitChunks (see webpack.config.js). diff --git a/lib/Dashboard/StartCaseWidget.php b/lib/Dashboard/StartCaseWidget.php index 0045f44fe..547c15882 100644 --- a/lib/Dashboard/StartCaseWidget.php +++ b/lib/Dashboard/StartCaseWidget.php @@ -36,6 +36,8 @@ /** * Dashboard widget showing available case types for quick case creation. + * + * @spec openspec/specs/dashboard/spec.md */ class StartCaseWidget implements IWidget { /** @@ -55,6 +57,8 @@ public function __construct( * * @inheritDoc * @return string The widget identifier + * + * @spec openspec/specs/dashboard/spec.md */ public function getId(): string { // FROZEN at the old app-id prefix — see CasesOverviewWidget::getId(). @@ -66,6 +70,8 @@ public function getId(): string { * * @inheritDoc * @return string The widget title + * + * @spec openspec/specs/dashboard/spec.md */ public function getTitle(): string { return $this->l10n->t('Start case'); @@ -76,6 +82,8 @@ public function getTitle(): string { * * @inheritDoc * @return int The widget order + * + * @spec openspec/specs/dashboard/spec.md */ public function getOrder(): int { return 15; @@ -86,6 +94,8 @@ public function getOrder(): int { * * @inheritDoc * @return string The icon CSS class + * + * @spec openspec/specs/dashboard/spec.md */ public function getIconClass(): string { return 'icon-dossiq-widget'; @@ -96,6 +106,8 @@ public function getIconClass(): string { * * @inheritDoc * @return string|null The widget URL or null + * + * @spec openspec/specs/dashboard/spec.md */ public function getUrl(): ?string { return $this->url->linkToRouteAbsolute(Application::APP_ID . '.dashboard.page'); @@ -108,6 +120,8 @@ public function getUrl(): ?string { * @return void * * @SuppressWarnings(PHPMD.StaticAccess) — Nextcloud Util API is static by design + * + * @spec openspec/specs/dashboard/spec.md */ public function load(): void { // Shared vendor chunks emitted by webpack splitChunks (see webpack.config.js). diff --git a/lib/Dashboard/TaskRemindersWidget.php b/lib/Dashboard/TaskRemindersWidget.php index 219d93a81..3989ec0af 100644 --- a/lib/Dashboard/TaskRemindersWidget.php +++ b/lib/Dashboard/TaskRemindersWidget.php @@ -38,6 +38,8 @@ /** * Dashboard widget showing task due reminders. + * + * @spec openspec/specs/signalering-widgets/spec.md */ class TaskRemindersWidget implements IWidget { /** @@ -57,6 +59,8 @@ public function __construct( * * @inheritDoc * @return string The widget identifier + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getId(): string { // FROZEN at the old app-id prefix — see CasesOverviewWidget::getId(). @@ -68,6 +72,8 @@ public function getId(): string { * * @inheritDoc * @return string The widget title + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getTitle(): string { return $this->l10n->t('Task Reminders'); @@ -78,6 +84,8 @@ public function getTitle(): string { * * @inheritDoc * @return int The widget order + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getOrder(): int { return 12; @@ -88,6 +96,8 @@ public function getOrder(): int { * * @inheritDoc * @return string The icon CSS class + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getIconClass(): string { return 'icon-dossiq-widget'; @@ -98,6 +108,8 @@ public function getIconClass(): string { * * @inheritDoc * @return string|null The widget URL or null + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function getUrl(): ?string { return $this->url->linkToRouteAbsolute(Application::APP_ID . '.dashboard.page'); @@ -110,6 +122,8 @@ public function getUrl(): ?string { * @return void * * @SuppressWarnings(PHPMD.StaticAccess) — Nextcloud Util API is static by design + * + * @spec openspec/specs/signalering-widgets/spec.md */ public function load(): void { // Shared vendor chunks emitted by webpack splitChunks (see webpack.config.js). diff --git a/lib/Flow/DossiqFlowNodeBase.php b/lib/Flow/DossiqFlowNodeBase.php index e61a5440f..c6f7e6836 100644 --- a/lib/Flow/DossiqFlowNodeBase.php +++ b/lib/Flow/DossiqFlowNodeBase.php @@ -121,6 +121,8 @@ public function getId(): string { * The node icon. * * @return string The icon path. + * + * @spec openspec/changes/page-topology-cleanup/specs/automatic-actions-surface/spec.md */ public function getIcon(): string { return $this->urls->imagePath('dossiq', 'app-dark.svg'); @@ -217,6 +219,8 @@ public function execute(array $items, array $config, array $context): array { * @param integer $scope The Nextcloud workflow scope. * * @return boolean True when available in this scope. + * + * @spec openspec/changes/page-topology-cleanup/specs/automatic-actions-surface/spec.md */ public function isAvailableForScope(int $scope): bool { return in_array($scope, [IManager::SCOPE_ADMIN, IManager::SCOPE_USER], true); diff --git a/lib/Http/RangeStreamResponse.php b/lib/Http/RangeStreamResponse.php index 199ee2baa..b2f32b408 100644 --- a/lib/Http/RangeStreamResponse.php +++ b/lib/Http/RangeStreamResponse.php @@ -38,6 +38,8 @@ * @template-extends Response<200|206|404|416, array> * * @psalm-suppress InvalidTemplateParam + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T05 */ class RangeStreamResponse extends Response { @@ -85,6 +87,8 @@ public function __construct(string $content, string $fileName, string $contentTy * Render the response body. * * @return string The (possibly sliced) content. + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T05 */ public function render(): string { return $this->body; diff --git a/lib/Listener/BezwaarLifecycleListener.php b/lib/Listener/BezwaarLifecycleListener.php index 59330bc88..f793b5c66 100644 --- a/lib/Listener/BezwaarLifecycleListener.php +++ b/lib/Listener/BezwaarLifecycleListener.php @@ -49,6 +49,8 @@ * status-transition-engine without owning any transition logic itself. * * @template-implements IEventListener + * + * @spec openspec/specs/bezwaar-lifecycle/spec.md */ class BezwaarLifecycleListener implements IEventListener { diff --git a/lib/Listener/TermijnTimerFiredListener.php b/lib/Listener/TermijnTimerFiredListener.php index d5da79c27..f2eb69656 100644 --- a/lib/Listener/TermijnTimerFiredListener.php +++ b/lib/Listener/TermijnTimerFiredListener.php @@ -52,6 +52,8 @@ * Maps engine rung fires onto the AWB termijn domain actions. * * @template-implements IEventListener + * + * @spec openspec/changes/termijnbewaking-op-engine-timers/tasks.md */ class TermijnTimerFiredListener implements IEventListener { use SearchesObjects; diff --git a/lib/Mcp/DossiqToolProvider.php b/lib/Mcp/DossiqToolProvider.php index d75ce6afd..094e8c6ac 100644 --- a/lib/Mcp/DossiqToolProvider.php +++ b/lib/Mcp/DossiqToolProvider.php @@ -55,6 +55,8 @@ * the Nextcloud system admin group), mirroring StatusTransitionService. * - A non-admin caller may read a case only when they are its assignee * (primary handler) or hold a role record linking them to the case. + * + * @spec openspec/specs/mcp-integration/spec.md */ class DossiqToolProvider implements IMcpToolProvider { @@ -139,6 +141,8 @@ public function __construct( * Returns the app ID that namespaces every tool id. * * @return string "dossiq" + * + * @spec openspec/specs/mcp-integration/spec.md */ public function getAppId(): string { return 'dossiq'; @@ -151,6 +155,8 @@ public function getAppId(): string { * Per-object authorisation runs in invokeTool(). * * @return array> + * + * @spec openspec/specs/mcp-integration/spec.md */ public function getTools(): array { return self::TOOL_DESCRIPTORS; @@ -167,6 +173,8 @@ public function getTools(): array { * @param array $arguments Tool arguments from the LLM call * * @return array + * + * @spec openspec/specs/mcp-integration/spec.md */ public function invokeTool(string $toolId, array $arguments): array { switch ($toolId) { diff --git a/lib/Middleware/MandateDeniedException.php b/lib/Middleware/MandateDeniedException.php index 8e86e4370..90e04499f 100644 --- a/lib/Middleware/MandateDeniedException.php +++ b/lib/Middleware/MandateDeniedException.php @@ -26,6 +26,8 @@ /** * Mandate matrix denied this request. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-06-mandate-validation/tasks.md */ class MandateDeniedException extends Exception { }//end class diff --git a/lib/Middleware/MandateValidationMiddleware.php b/lib/Middleware/MandateValidationMiddleware.php index 7faa055e1..a55227d26 100644 --- a/lib/Middleware/MandateValidationMiddleware.php +++ b/lib/Middleware/MandateValidationMiddleware.php @@ -35,6 +35,8 @@ /** * Mandate-matrix middleware. Audit-logs every decision (allow + deny). + * + * @spec openspec/changes/tenant-zaaksysteem-saas-06-mandate-validation/tasks.md */ class MandateValidationMiddleware extends Middleware { /** @@ -87,6 +89,8 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::beforeController(); this middleware * dispatches on the request URI instead. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-06-mandate-validation/tasks.md */ public function beforeController($controller, $methodName): void { if ($this->context->isBound() === false) { @@ -137,6 +141,8 @@ public function beforeController($controller, $methodName): void { * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::afterException(); only $exception is * inspected. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-06-mandate-validation/tasks.md */ public function afterException($controller, $methodName, \Exception $exception): \OCP\AppFramework\Http\Response { if ($exception instanceof MandateDeniedException) { @@ -156,6 +162,8 @@ public function afterException($controller, $methodName, \Exception $exception): * @param string $path Request URI. * * @return string|null Action or null when no mandate gate applies. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-06-mandate-validation/tasks.md */ public function resolveAction(string $verb, string $path): ?string { foreach (self::STATUS_PATH_HINTS as $hint) { diff --git a/lib/Middleware/QuotaEnforcementMiddleware.php b/lib/Middleware/QuotaEnforcementMiddleware.php index 4760a9e92..87c446af7 100644 --- a/lib/Middleware/QuotaEnforcementMiddleware.php +++ b/lib/Middleware/QuotaEnforcementMiddleware.php @@ -33,6 +33,8 @@ /** * Pre-controller quota enforcement. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-09-quotas-enforcement/tasks.md */ class QuotaEnforcementMiddleware extends Middleware { /** @@ -62,6 +64,8 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::beforeController(); this middleware * dispatches on the request URI instead. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-09-quotas-enforcement/tasks.md */ public function beforeController($controller, $methodName): void { if ($this->context->isBound() === false) { @@ -115,6 +119,8 @@ public function beforeController($controller, $methodName): void { * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::afterException(); only $exception is * inspected. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-09-quotas-enforcement/tasks.md */ public function afterException($controller, $methodName, \Exception $exception): \OCP\AppFramework\Http\Response { if ($exception instanceof QuotaExceededException) { @@ -134,6 +140,8 @@ public function afterException($controller, $methodName, \Exception $exception): * @param string $path URI. * * @return string|null + * + * @spec openspec/changes/tenant-zaaksysteem-saas-09-quotas-enforcement/tasks.md */ public function resolveQuotaType(string $verb, string $path): ?string { if ($verb === 'POST' && (str_contains($path, '/api/case') === true || str_contains($path, '/api/cases') === true)) { diff --git a/lib/Middleware/QuotaExceededException.php b/lib/Middleware/QuotaExceededException.php index 7da70cbd9..c1b78b6ac 100644 --- a/lib/Middleware/QuotaExceededException.php +++ b/lib/Middleware/QuotaExceededException.php @@ -26,6 +26,8 @@ /** * Tenant quota exceeded (429). + * + * @spec openspec/changes/tenant-zaaksysteem-saas-09-quotas-enforcement/tasks.md */ class QuotaExceededException extends Exception { }//end class diff --git a/lib/Middleware/TenantClaimMismatchException.php b/lib/Middleware/TenantClaimMismatchException.php index bd933c22b..b4e71f96e 100644 --- a/lib/Middleware/TenantClaimMismatchException.php +++ b/lib/Middleware/TenantClaimMismatchException.php @@ -29,6 +29,8 @@ /** * Tenant-claim mismatch exception (always 403). + * + * @spec openspec/changes/tenant-zaaksysteem-saas-05-auth-jwt-tenant-claim/tasks.md */ class TenantClaimMismatchException extends Exception { }//end class diff --git a/lib/Middleware/TenantClaimValidationMiddleware.php b/lib/Middleware/TenantClaimValidationMiddleware.php index eb0ecc015..9f9ea2f44 100644 --- a/lib/Middleware/TenantClaimValidationMiddleware.php +++ b/lib/Middleware/TenantClaimValidationMiddleware.php @@ -42,6 +42,8 @@ /** * Validate JWT tenant_id ↔ request-tenant match. Fail-closed. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-05-auth-jwt-tenant-claim/tasks.md */ class TenantClaimValidationMiddleware extends Middleware { /** @@ -98,6 +100,8 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::beforeController(); this middleware * validates the bound tenant claim instead. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-05-auth-jwt-tenant-claim/tasks.md */ public function beforeController($controller, $methodName): void { // No bearer header → not a JWT-authenticated request; let other auth layers handle. @@ -145,6 +149,8 @@ public function beforeController($controller, $methodName): void { * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::afterException(); only $exception is * inspected. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-05-auth-jwt-tenant-claim/tasks.md */ public function afterException($controller, $methodName, \Exception $exception): \OCP\AppFramework\Http\Response { if ($exception instanceof TenantClaimMismatchException) { diff --git a/lib/Middleware/TenantContextMiddleware.php b/lib/Middleware/TenantContextMiddleware.php index f84b88a6e..15d415be2 100644 --- a/lib/Middleware/TenantContextMiddleware.php +++ b/lib/Middleware/TenantContextMiddleware.php @@ -51,6 +51,8 @@ /** * Middleware that resolves the tenant and binds it to the TenantContext. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ class TenantContextMiddleware extends Middleware { /** @@ -100,6 +102,8 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) $methodName is fixed by * OCP\AppFramework\Middleware::beforeController(); tenant resolution keys off * the controller class and the request, not the action name. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function beforeController($controller, $methodName): void { if (in_array(get_class($controller), self::EXEMPT_CONTROLLERS, true) === true) { @@ -150,6 +154,8 @@ public function beforeController($controller, $methodName): void { * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::afterException(); this hook only * re-throws. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function afterException($controller, $methodName, \Exception $exception): \OCP\AppFramework\Http\Response { throw $exception; diff --git a/lib/Middleware/TenantIsolationMiddleware.php b/lib/Middleware/TenantIsolationMiddleware.php index 1c032a4a6..270c85e08 100644 --- a/lib/Middleware/TenantIsolationMiddleware.php +++ b/lib/Middleware/TenantIsolationMiddleware.php @@ -41,6 +41,8 @@ /** * Set the per-request Postgres search_path from the bound tenant schema. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ class TenantIsolationMiddleware extends Middleware { /** @@ -70,6 +72,8 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::beforeController(); the search_path is * derived from the bound tenant context. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function beforeController($controller, $methodName): void { if ($this->context->isBound() === false) { @@ -98,6 +102,8 @@ public function beforeController($controller, $methodName): void { * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::afterController(); the reset is * unconditional. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function afterController($controller, $methodName, \OCP\AppFramework\Http\Response $response): \OCP\AppFramework\Http\Response { $this->resetSearchPath(); @@ -118,6 +124,8 @@ public function afterController($controller, $methodName, \OCP\AppFramework\Http * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::afterException(); the reset is * unconditional. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function afterException($controller, $methodName, \Exception $exception): \OCP\AppFramework\Http\Response { $this->resetSearchPath(); @@ -130,6 +138,8 @@ public function afterException($controller, $methodName, \Exception $exception): * @param string $schemaName Schema name (validated). * * @return void + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function applySearchPath(string $schemaName): void { try { @@ -158,6 +168,8 @@ public function applySearchPath(string $schemaName): void { * Reset the search_path to `public`. * * @return void + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function resetSearchPath(): void { try { diff --git a/lib/Middleware/TenantMiddleware.php b/lib/Middleware/TenantMiddleware.php index d61e259d4..dbda172f8 100644 --- a/lib/Middleware/TenantMiddleware.php +++ b/lib/Middleware/TenantMiddleware.php @@ -37,6 +37,8 @@ * Ensures that users can only access data belonging to their tenant. * Platform admins can access any tenant via context switching. * Returns 404 (not 403) for cross-tenant access to prevent information leakage. + * + * @spec openspec/specs/tenant-isolation/spec.md */ class TenantMiddleware extends Middleware { /** @@ -79,6 +81,8 @@ public function __construct( * @SuppressWarnings(PHPMD.UnusedFormalParameter) $methodName is fixed by * OCP\AppFramework\Middleware::beforeController(); the tenant check keys off * the controller class and the request, not the action name. + * + * @spec openspec/specs/tenant-isolation/spec.md */ public function beforeController($controller, $methodName): void { // Skip for exempt controllers. @@ -157,6 +161,8 @@ public function beforeController($controller, $methodName): void { * @SuppressWarnings(PHPMD.UnusedFormalParameter) $controller and $methodName are * fixed by OCP\AppFramework\Middleware::afterException(); only $exception is * inspected. + * + * @spec openspec/specs/tenant-isolation/spec.md */ public function afterException($controller, $methodName, \Exception $exception): JSONResponse { if ($exception->getCode() === 404) { diff --git a/lib/Middleware/ZgwAuthException.php b/lib/Middleware/ZgwAuthException.php index 38eb09746..d5987ea5b 100644 --- a/lib/Middleware/ZgwAuthException.php +++ b/lib/Middleware/ZgwAuthException.php @@ -26,6 +26,8 @@ /** * Exception for ZGW authentication and authorization failures. + * + * @spec openspec/specs/zgw-autorisaties-api/spec.md */ class ZgwAuthException extends \Exception { @@ -51,6 +53,8 @@ public function __construct(string $message, int $statusCode = 403) { * Get the HTTP status code. * * @return int + * + * @spec openspec/specs/zgw-autorisaties-api/spec.md */ public function getStatusCode(): int { return $this->statusCode; diff --git a/lib/Middleware/ZgwAuthMiddleware.php b/lib/Middleware/ZgwAuthMiddleware.php index cdd8b23c3..1f4bf3203 100644 --- a/lib/Middleware/ZgwAuthMiddleware.php +++ b/lib/Middleware/ZgwAuthMiddleware.php @@ -42,6 +42,8 @@ * the authenticated applicatie has the required scope for the request. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ class ZgwAuthMiddleware extends Middleware { /** @@ -167,6 +169,8 @@ private function loadOpenRegisterServices(): void { * @throws \OCA\Dossiq\Middleware\ZgwAuthException If authorization fails. * * @SuppressWarnings(PHPMD.UnusedFormalParameter) — $methodName required by Middleware interface + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function beforeController($controller, $methodName): void { if (($controller instanceof ZgwController) === false) { @@ -240,6 +244,8 @@ public function beforeController($controller, $methodName): void { * @throws \Exception Re-throws any non-ZGW-auth exception for the next middleware. * * @SuppressWarnings(PHPMD.UnusedFormalParameter) — $controller/$methodName required by Middleware interface + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function afterException($controller, $methodName, \Exception $exception): JSONResponse { if ($exception instanceof ZgwAuthException) { @@ -450,6 +456,8 @@ private function findConsumerByIssuer(string $issuer): ?object { * @param string $max The maximum allowed level * * @return bool True if actual is at or below max + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function isConfidentialityAllowed(string $actual, string $max): bool { $actualIndex = array_search(needle: $actual, haystack: self::CONFIDENTIALITY_ORDER); diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php index e385fa785..8e920540e 100644 --- a/lib/Notification/Notifier.php +++ b/lib/Notification/Notifier.php @@ -39,6 +39,8 @@ /** * Parses Dossiq notifications into localised, rendered form. + * + * @spec openspec/specs/ncvue-w2-leaves-adoption/spec.md */ class Notifier implements INotifier { @@ -67,6 +69,8 @@ public function __construct( * Identifier of the notifier, only use [a-z0-9_]. * * @return string + * + * @spec openspec/specs/ncvue-w2-leaves-adoption/spec.md */ public function getID(): string { return Application::APP_ID; @@ -76,6 +80,8 @@ public function getID(): string { * Human-readable name describing the notifier. * * @return string + * + * @spec openspec/specs/ncvue-w2-leaves-adoption/spec.md */ public function getName(): string { return 'Dossiq'; @@ -90,6 +96,8 @@ public function getName(): string { * @return INotification The prepared notification. * * @throws UnknownNotificationException When the notification is not a Dossiq one. + * + * @spec openspec/specs/ncvue-w2-leaves-adoption/spec.md */ public function prepare(INotification $notification, string $languageCode): INotification { if ($notification->getApp() !== Application::APP_ID) { diff --git a/lib/Repair/BackfillInformatieobjectMetadata.php b/lib/Repair/BackfillInformatieobjectMetadata.php index 0b01fce27..f2dd0a3f0 100644 --- a/lib/Repair/BackfillInformatieobjectMetadata.php +++ b/lib/Repair/BackfillInformatieobjectMetadata.php @@ -46,6 +46,8 @@ /** * Repair step that back-fills informatieobject metadata for existing files. + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T09 */ class BackfillInformatieobjectMetadata implements IRepairStep { use RunsUnderSystemIdentity; @@ -74,6 +76,8 @@ public function __construct( * Get the repair-step display name. * * @return string + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T09 */ public function getName(): string { return 'Back-fill ZGW informatieobject metadata for existing Dossiq dossier files'; diff --git a/lib/Repair/DbValueMigrationPort.php b/lib/Repair/DbValueMigrationPort.php index 9af6f17ba..70d32ca2c 100644 --- a/lib/Repair/DbValueMigrationPort.php +++ b/lib/Repair/DbValueMigrationPort.php @@ -35,6 +35,8 @@ /** * The real storage implementation behind ValueMigrationPort. + * + * @spec exclude Database adapter for the Dutch-to-English vocabulary migration. */ class DbValueMigrationPort implements ValueMigrationPort { /** diff --git a/lib/Repair/LinkInFlightContractDecisionsRepair.php b/lib/Repair/LinkInFlightContractDecisionsRepair.php index da3841acd..211fb7ff1 100644 --- a/lib/Repair/LinkInFlightContractDecisionsRepair.php +++ b/lib/Repair/LinkInFlightContractDecisionsRepair.php @@ -92,6 +92,8 @@ public function __construct( * Get the name of this repair step. * * @return string + * + * @spec openspec/specs/contract-decision-delegation/spec.md */ public function getName(): string { return 'Link in-flight Dossiq contract/besluitvorming cases to decidesk Decisions'; diff --git a/lib/Repair/LinkInFlightRemainingDecisionsRepair.php b/lib/Repair/LinkInFlightRemainingDecisionsRepair.php index 88b6e4efc..c3e4dfa62 100644 --- a/lib/Repair/LinkInFlightRemainingDecisionsRepair.php +++ b/lib/Repair/LinkInFlightRemainingDecisionsRepair.php @@ -116,6 +116,8 @@ public function __construct( * Get the name of this repair step. * * @return string + * + * @spec openspec/specs/remaining-decision-delegation/spec.md#requirement-req-pdrd-006-in-flight-remaining-decision-cases-are-migrated-without-data-loss */ public function getName(): string { return 'Link in-flight Dossiq bezwaar/advies/consultatie objects to decidesk Decisions'; diff --git a/lib/Repair/MigrateWorkflowDefinitions.php b/lib/Repair/MigrateWorkflowDefinitions.php index e8387e7f3..944a44f15 100644 --- a/lib/Repair/MigrateWorkflowDefinitions.php +++ b/lib/Repair/MigrateWorkflowDefinitions.php @@ -39,6 +39,8 @@ /** * Backfill workflowTemplate objects from implicit statusType ordering. + * + * @spec openspec/specs/workflow-definition-model/spec.md */ class MigrateWorkflowDefinitions implements IRepairStep { @@ -69,6 +71,8 @@ public function __construct( * Get the name of this repair step. * * @return string + * + * @spec openspec/specs/workflow-definition-model/spec.md */ public function getName(): string { return 'Backfill workflowTemplate definitions for existing caseTypes'; diff --git a/lib/Repair/RenameDutchDirectionValues.php b/lib/Repair/RenameDutchDirectionValues.php index 7e84d0926..f346c8883 100644 --- a/lib/Repair/RenameDutchDirectionValues.php +++ b/lib/Repair/RenameDutchDirectionValues.php @@ -135,6 +135,8 @@ public function __construct( * Step name shown by `occ maintenance:repair`. * * @return string + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md */ public function getName(): string { return 'Dossiq: rewrite Dutch direction values (inkomend/uitgaand/intern) to English'; diff --git a/lib/Repair/RenameDutchValueDecisions.php b/lib/Repair/RenameDutchValueDecisions.php index f57561e22..cc5aa9f1c 100644 --- a/lib/Repair/RenameDutchValueDecisions.php +++ b/lib/Repair/RenameDutchValueDecisions.php @@ -32,6 +32,8 @@ /** * Pure predicates for the Dutch-to-English value migration. + * + * @spec exclude Predicate of the Dutch-to-English vocabulary migration. */ class RenameDutchValueDecisions { diff --git a/lib/Repair/RenameDutchValues.php b/lib/Repair/RenameDutchValues.php index a73a11f76..c659148b8 100644 --- a/lib/Repair/RenameDutchValues.php +++ b/lib/Repair/RenameDutchValues.php @@ -35,6 +35,8 @@ /** * Rewrites stored Dutch enum values to their English replacements. + * + * @spec exclude Data migration for the Dutch-to-English vocabulary change. */ class RenameDutchValues implements IRepairStep { /** diff --git a/lib/Repair/SeedBezwaarBeroepData.php b/lib/Repair/SeedBezwaarBeroepData.php index cf9821e6b..acc590af9 100644 --- a/lib/Repair/SeedBezwaarBeroepData.php +++ b/lib/Repair/SeedBezwaarBeroepData.php @@ -35,6 +35,8 @@ /** * Repair step that seeds bezwaar and beroep case types into OpenRegister. + * + * @spec openspec/specs/bezwaar-lifecycle/spec.md */ class SeedBezwaarBeroepData implements IRepairStep { /** @@ -57,6 +59,8 @@ public function __construct( * Get the name of this repair step. * * @return string + * + * @spec openspec/specs/bezwaar-lifecycle/spec.md */ public function getName(): string { return 'Seed Bezwaar, Beroep and Subsidie case types for Dossiq'; diff --git a/lib/Repair/SeedBezwaarWorkflowDefinition.php b/lib/Repair/SeedBezwaarWorkflowDefinition.php index 439ba1be1..ee047a93d 100644 --- a/lib/Repair/SeedBezwaarWorkflowDefinition.php +++ b/lib/Repair/SeedBezwaarWorkflowDefinition.php @@ -43,6 +43,8 @@ /** * Seed the canonical bezwaar workflow definition (published, version 1). + * + * @spec openspec/specs/bezwaar-lifecycle/spec.md */ class SeedBezwaarWorkflowDefinition implements IRepairStep { @@ -78,6 +80,8 @@ public function __construct( * Get the name of this repair step. * * @return string + * + * @spec openspec/specs/bezwaar-lifecycle/spec.md */ public function getName(): string { return 'Seed canonical bezwaar workflow definition (AWB-compliant state machine)'; diff --git a/lib/Repair/SeedLhsMatrix.php b/lib/Repair/SeedLhsMatrix.php index e140ee9b6..5b6a84581 100644 --- a/lib/Repair/SeedLhsMatrix.php +++ b/lib/Repair/SeedLhsMatrix.php @@ -62,6 +62,8 @@ public function __construct( * Get the name of this repair step. * * @return string + * + * @spec openspec/changes/enforcement-lhs/tasks.md#T02 */ public function getName(): string { return 'Seed default LHS matrix (Landelijke Handhavingsstrategie 2024) for Dossiq'; diff --git a/lib/Sections/PersonalSection.php b/lib/Sections/PersonalSection.php index 74da183e5..195d94140 100644 --- a/lib/Sections/PersonalSection.php +++ b/lib/Sections/PersonalSection.php @@ -51,6 +51,8 @@ public function __construct( * Get the section id. * * @return string The section id. + * + * @spec openspec/changes/page-topology-cleanup/specs/personal-settings-surface/spec.md */ public function getID(): string { return 'dossiq'; @@ -60,6 +62,8 @@ public function getID(): string { * Get the section display name. * * @return string The translated section name. + * + * @spec openspec/changes/page-topology-cleanup/specs/personal-settings-surface/spec.md */ public function getName(): string { return $this->l->t('Dossiq'); @@ -69,6 +73,8 @@ public function getName(): string { * Get the ordering priority. * * @return int The priority. + * + * @spec openspec/changes/page-topology-cleanup/specs/personal-settings-surface/spec.md */ public function getPriority(): int { return 75; @@ -78,6 +84,8 @@ public function getPriority(): int { * Get the icon path for this section. * * @return string The icon path. + * + * @spec openspec/changes/page-topology-cleanup/specs/personal-settings-surface/spec.md */ public function getIcon(): string { // MUST be the live app id. imagePath() throws when the app does not diff --git a/lib/Sections/SettingsSection.php b/lib/Sections/SettingsSection.php index 528c5897a..0dd510b1f 100644 --- a/lib/Sections/SettingsSection.php +++ b/lib/Sections/SettingsSection.php @@ -30,6 +30,8 @@ /** * Defines the Dossiq section in the Nextcloud admin settings. + * + * @spec openspec/specs/admin-settings/spec.md */ class SettingsSection implements IIconSection { /** @@ -50,6 +52,8 @@ public function __construct( * Get the section identifier. * * @return string + * + * @spec openspec/specs/admin-settings/spec.md */ public function getID(): string { return 'dossiq'; @@ -59,6 +63,8 @@ public function getID(): string { * Get the display name of this section. * * @return string + * + * @spec openspec/specs/admin-settings/spec.md */ public function getName(): string { return $this->l->t('Dossiq'); @@ -68,6 +74,8 @@ public function getName(): string { * Get the priority for ordering this section. * * @return int + * + * @spec openspec/specs/admin-settings/spec.md */ public function getPriority(): int { return 75; @@ -77,6 +85,8 @@ public function getPriority(): int { * Get the icon path for this section. * * @return string + * + * @spec openspec/specs/admin-settings/spec.md */ public function getIcon(): string { return $this->urlGenerator->imagePath(appName: 'dossiq', file: 'app-dark.svg'); diff --git a/lib/Service/Actions/ActionResult.php b/lib/Service/Actions/ActionResult.php index f1734ae59..d73f1717f 100644 --- a/lib/Service/Actions/ActionResult.php +++ b/lib/Service/Actions/ActionResult.php @@ -36,6 +36,8 @@ * `webhook_timeout`, `unknown_action_ref`). Handlers MUST NEVER include * `$e->getMessage()` or raw exception text here — log the exception via * `LoggerInterface::error()` instead. + * + * @spec openspec/specs/automatic-actions/spec.md */ final class ActionResult { /** diff --git a/lib/Service/Actions/CallWebhookHandler.php b/lib/Service/Actions/CallWebhookHandler.php index 8242fa8b5..adf41df1f 100644 --- a/lib/Service/Actions/CallWebhookHandler.php +++ b/lib/Service/Actions/CallWebhookHandler.php @@ -35,6 +35,8 @@ /** * Handler for `callWebhook` automatic actions. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class CallWebhookHandler implements ActionHandlerInterface { use HandlesTemplates; diff --git a/lib/Service/Actions/CreateDocumentHandler.php b/lib/Service/Actions/CreateDocumentHandler.php index a7561e347..816c5f4ee 100644 --- a/lib/Service/Actions/CreateDocumentHandler.php +++ b/lib/Service/Actions/CreateDocumentHandler.php @@ -34,6 +34,8 @@ /** * Handler for `createDocument` automatic actions. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class CreateDocumentHandler implements ActionHandlerInterface { use HandlesTemplates; diff --git a/lib/Service/Actions/MergeTemplateHandler.php b/lib/Service/Actions/MergeTemplateHandler.php index 74ee812fa..4dca72333 100644 --- a/lib/Service/Actions/MergeTemplateHandler.php +++ b/lib/Service/Actions/MergeTemplateHandler.php @@ -36,6 +36,8 @@ /** * Handler for `mergeTemplate` automatic actions. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class MergeTemplateHandler implements ActionHandlerInterface { use HandlesTemplates; diff --git a/lib/Service/Actions/NotifyRoleHandler.php b/lib/Service/Actions/NotifyRoleHandler.php index c51a90b61..ea10291b9 100644 --- a/lib/Service/Actions/NotifyRoleHandler.php +++ b/lib/Service/Actions/NotifyRoleHandler.php @@ -34,6 +34,8 @@ /** * Handler for `notifyRole` automatic actions. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class NotifyRoleHandler implements ActionHandlerInterface { use HandlesTemplates; diff --git a/lib/Service/Actions/ScheduleReminderHandler.php b/lib/Service/Actions/ScheduleReminderHandler.php index 9b9d77d26..856df2ec8 100644 --- a/lib/Service/Actions/ScheduleReminderHandler.php +++ b/lib/Service/Actions/ScheduleReminderHandler.php @@ -38,6 +38,8 @@ /** * Handler for `scheduleReminder` automatic actions. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ScheduleReminderHandler implements ActionHandlerInterface { use HandlesTemplates; diff --git a/lib/Service/Actions/SendEmailHandler.php b/lib/Service/Actions/SendEmailHandler.php index 1bfe9136e..0731f1265 100644 --- a/lib/Service/Actions/SendEmailHandler.php +++ b/lib/Service/Actions/SendEmailHandler.php @@ -34,6 +34,8 @@ /** * Handler for `sendEmail` automatic actions. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class SendEmailHandler implements ActionHandlerInterface { use HandlesTemplates; diff --git a/lib/Service/AdvisoryBodyService.php b/lib/Service/AdvisoryBodyService.php index e79fd6d4c..f33e41f74 100644 --- a/lib/Service/AdvisoryBodyService.php +++ b/lib/Service/AdvisoryBodyService.php @@ -38,6 +38,8 @@ * Advisory bodies are departments (internal) or organizations (external) that * can be consulted during case processing. This service exposes CRUD, weighted * specialization search, and secure-token issuance for external notification. + * + * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-03 */ class AdvisoryBodyService { use SearchesObjects; diff --git a/lib/Service/AppointmentBackend/AppointmentBackendInterface.php b/lib/Service/AppointmentBackend/AppointmentBackendInterface.php index d91934a15..3a09a1dd0 100644 --- a/lib/Service/AppointmentBackend/AppointmentBackendInterface.php +++ b/lib/Service/AppointmentBackend/AppointmentBackendInterface.php @@ -38,6 +38,8 @@ interface AppointmentBackendInterface { * @param string $date The date (YYYY-MM-DD) * * @return array List of available timeslots [{time, duration, available}] + * + * @spec openspec/specs/appointment-booking/spec.md */ public function getTimeslots(string $productId, string $locationId, string $date): array; diff --git a/lib/Service/AppointmentBackend/JccBackend.php b/lib/Service/AppointmentBackend/JccBackend.php index f39a25a10..7e4f66cd7 100644 --- a/lib/Service/AppointmentBackend/JccBackend.php +++ b/lib/Service/AppointmentBackend/JccBackend.php @@ -32,6 +32,8 @@ * * Integrates with the JCC Afspraken REST API used by many Dutch municipalities * for balie appointment management. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class JccBackend implements AppointmentBackendInterface { /** diff --git a/lib/Service/AppointmentBackend/QmaticBackend.php b/lib/Service/AppointmentBackend/QmaticBackend.php index 7e0400fcf..a3318cf7c 100644 --- a/lib/Service/AppointmentBackend/QmaticBackend.php +++ b/lib/Service/AppointmentBackend/QmaticBackend.php @@ -28,6 +28,8 @@ /** * Qmatic Orchestra REST API backend for appointment scheduling. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class QmaticBackend implements AppointmentBackendInterface { /** diff --git a/lib/Service/AppointmentService.php b/lib/Service/AppointmentService.php index 1ca6b6591..59220d1e3 100644 --- a/lib/Service/AppointmentService.php +++ b/lib/Service/AppointmentService.php @@ -47,6 +47,8 @@ * Dispatches to the configured EXTERNAL backend (JCC or Qmatic) and stores * appointment records in OpenRegister. There is no local fallback — internal * scheduling lives in the OR calendar leaf. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class AppointmentService { /** @@ -77,6 +79,8 @@ public function __construct( * @param string $date The date (YYYY-MM-DD). * * @return array> List of available timeslots. + * + * @spec openspec/specs/appointment-booking/spec.md */ public function getTimeslots(string $productId, string $locationId, string $date): array { return $this->getBackend()->getTimeslots($productId, $locationId, $date); diff --git a/lib/Service/Auth/BrokerAssertionResult.php b/lib/Service/Auth/BrokerAssertionResult.php index 5747e67bb..d3d249721 100644 --- a/lib/Service/Auth/BrokerAssertionResult.php +++ b/lib/Service/Auth/BrokerAssertionResult.php @@ -37,6 +37,8 @@ /** * Decoded SAML-broker assertion result for dossiq auth flows. + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md */ final class BrokerAssertionResult { /** @@ -81,6 +83,8 @@ private function __construct( * @param array $attributes Raw attributes. * * @return self + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md */ public static function forEHerkenning( string $kvkNumber, @@ -114,6 +118,8 @@ public static function forEHerkenning( * @param array $attributes Raw attributes. * * @return self + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md */ public static function forDigid( string $bsn, @@ -141,6 +147,8 @@ public static function forDigid( * Serialise to a JSON-safe array (audit logs, session bootstrap). * * @return array + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md */ public function toArray(): array { return [ diff --git a/lib/Service/Auth/DigidSamlAdapterInterface.php b/lib/Service/Auth/DigidSamlAdapterInterface.php index 5c7b04a3e..21f9793bb 100644 --- a/lib/Service/Auth/DigidSamlAdapterInterface.php +++ b/lib/Service/Auth/DigidSamlAdapterInterface.php @@ -64,6 +64,8 @@ interface DigidSamlAdapterInterface { * @return BrokerAssertionResult Decoded assertion containing the citizen BSN. * * @throws RuntimeException When the broker is not configured, the signature is invalid, or no BSN claim is present. + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md#requirement-digid-and-eherkenning-authentication-with-wdo-mandated-trust-levels */ public function decodeAssertion(string $samlResponse, string $relayState): BrokerAssertionResult; @@ -71,6 +73,8 @@ public function decodeAssertion(string $samlResponse, string $relayState): Broke * Whether the live DigiD broker is enabled by the operator. * * @return bool True when `digid.feature_flag` is `1`. + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md#requirement-digid-and-eherkenning-authentication-with-wdo-mandated-trust-levels */ public function isActive(): bool; }//end interface diff --git a/lib/Service/Auth/EHerkenningSamlAdapterInterface.php b/lib/Service/Auth/EHerkenningSamlAdapterInterface.php index 24ad3cb84..17044f261 100644 --- a/lib/Service/Auth/EHerkenningSamlAdapterInterface.php +++ b/lib/Service/Auth/EHerkenningSamlAdapterInterface.php @@ -65,6 +65,8 @@ interface EHerkenningSamlAdapterInterface { * @return BrokerAssertionResult Decoded assertion containing the supplier KvK number. * * @throws RuntimeException When the broker is not configured, the signature is invalid, or no KvK claim is present. + * + * @spec openspec/changes/leverancier-zaakportaal-02-eherkenning-auth/tasks.md */ public function decodeAssertion(string $samlResponse, string $relayState): BrokerAssertionResult; @@ -72,6 +74,8 @@ public function decodeAssertion(string $samlResponse, string $relayState): Broke * Whether the live eHerkenning broker is enabled by the operator. * * @return bool True when `eherkenning.feature_flag` is `1`. + * + * @spec openspec/changes/leverancier-zaakportaal-02-eherkenning-auth/tasks.md */ public function isActive(): bool; }//end interface diff --git a/lib/Service/Auth/LogDigidSamlAdapter.php b/lib/Service/Auth/LogDigidSamlAdapter.php index 8481479e4..f303b895e 100644 --- a/lib/Service/Auth/LogDigidSamlAdapter.php +++ b/lib/Service/Auth/LogDigidSamlAdapter.php @@ -40,6 +40,8 @@ /** * Default DigiD adapter — logs + refuses. + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md#requirement-digid-and-eherkenning-authentication-with-wdo-mandated-trust-levels */ final class LogDigidSamlAdapter implements DigidSamlAdapterInterface { /** @@ -100,6 +102,8 @@ public function decodeAssertion(string $samlResponse, string $relayState): Broke * Whether the live broker is enabled. * * @return bool + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md#requirement-digid-and-eherkenning-authentication-with-wdo-mandated-trust-levels */ public function isActive(): bool { $raw = $this->config->getValueString(self::APP_ID, self::FLAG_KEY, '0'); diff --git a/lib/Service/Auth/LogEHerkenningSamlAdapter.php b/lib/Service/Auth/LogEHerkenningSamlAdapter.php index 8aadbe4e7..0c8dbcdd8 100644 --- a/lib/Service/Auth/LogEHerkenningSamlAdapter.php +++ b/lib/Service/Auth/LogEHerkenningSamlAdapter.php @@ -41,6 +41,8 @@ /** * Default eHerkenning adapter — logs + refuses. + * + * @spec openspec/changes/leverancier-zaakportaal-02-eherkenning-auth/tasks.md */ final class LogEHerkenningSamlAdapter implements EHerkenningSamlAdapterInterface { /** @@ -101,6 +103,8 @@ public function decodeAssertion(string $samlResponse, string $relayState): Broke * Whether the live broker is enabled. * * @return bool + * + * @spec openspec/specs/zaakportaal-mijngemeente/spec.md#requirement-digid-and-eherkenning-authentication-with-wdo-mandated-trust-levels */ public function isActive(): bool { $raw = $this->config->getValueString(self::APP_ID, self::FLAG_KEY, '0'); diff --git a/lib/Service/Auth/SimulatorDigidSamlAdapter.php b/lib/Service/Auth/SimulatorDigidSamlAdapter.php index d7905ffaf..d3efafad5 100644 --- a/lib/Service/Auth/SimulatorDigidSamlAdapter.php +++ b/lib/Service/Auth/SimulatorDigidSamlAdapter.php @@ -89,6 +89,8 @@ public function decodeAssertion(string $samlResponse, string $relayState): Broke * broker — callers surface the simulation label. * * @return bool + * + * @spec openspec/specs/external-integration-test-wiring/spec.md */ public function isActive(): bool { return true; diff --git a/lib/Service/Auth/SimulatorEHerkenningSamlAdapter.php b/lib/Service/Auth/SimulatorEHerkenningSamlAdapter.php index b0b9f8b5c..a35ee4d31 100644 --- a/lib/Service/Auth/SimulatorEHerkenningSamlAdapter.php +++ b/lib/Service/Auth/SimulatorEHerkenningSamlAdapter.php @@ -85,6 +85,8 @@ public function decodeAssertion(string $samlResponse, string $relayState): Broke * The simulator is an active (non-dormant) tier, but not a live broker. * * @return bool + * + * @spec openspec/specs/external-integration-test-wiring/spec.md */ public function isActive(): bool { return true; diff --git a/lib/Service/BerichtenboxAdapter/BerichtenboxAdapterInterface.php b/lib/Service/BerichtenboxAdapter/BerichtenboxAdapterInterface.php index 9347ae9a2..5c7b1c696 100644 --- a/lib/Service/BerichtenboxAdapter/BerichtenboxAdapterInterface.php +++ b/lib/Service/BerichtenboxAdapter/BerichtenboxAdapterInterface.php @@ -54,6 +54,8 @@ public function sendMessage( * @param string $messageId The external message ID * * @return array Status with read (bool), readAt (datetime|null) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function getReadStatus(string $messageId): array; }//end interface diff --git a/lib/Service/BerichtenboxAdapter/MockAdapter.php b/lib/Service/BerichtenboxAdapter/MockAdapter.php index 85e0d80ce..bdcd502dd 100644 --- a/lib/Service/BerichtenboxAdapter/MockAdapter.php +++ b/lib/Service/BerichtenboxAdapter/MockAdapter.php @@ -31,6 +31,8 @@ * Mock Berichtenbox adapter for development and testing. * * Simulates message sending and read status without external API calls. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class MockAdapter implements BerichtenboxAdapterInterface { /** diff --git a/lib/Service/CaseDefinitionExportService.php b/lib/Service/CaseDefinitionExportService.php index 7338924ea..9302a94b3 100644 --- a/lib/Service/CaseDefinitionExportService.php +++ b/lib/Service/CaseDefinitionExportService.php @@ -44,6 +44,8 @@ * permission rules, document types, and workflow definitions for a case type. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/archive/retrofit-2026-05-24-annotate-procest/tasks.md#task-3 */ class CaseDefinitionExportService { /** diff --git a/lib/Service/CaseEmailService.php b/lib/Service/CaseEmailService.php index 497cf716e..6a0a59081 100644 --- a/lib/Service/CaseEmailService.php +++ b/lib/Service/CaseEmailService.php @@ -40,6 +40,8 @@ /** * Service for case-integrated email functionality. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class CaseEmailService { diff --git a/lib/Service/ConsultationService.php b/lib/Service/ConsultationService.php index 04a5fd3a2..142c28409 100644 --- a/lib/Service/ConsultationService.php +++ b/lib/Service/ConsultationService.php @@ -38,6 +38,8 @@ * Handles the full consultation lifecycle: creation with auto-generated numbers, * status transitions, advice responses, deadline extensions, and dependency * cycle detection per Awb 3:5-3:9. + * + * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-02 */ class ConsultationService { /** diff --git a/lib/Service/DeadlineEscalationService.php b/lib/Service/DeadlineEscalationService.php index 5a3771480..fc95f0258 100644 --- a/lib/Service/DeadlineEscalationService.php +++ b/lib/Service/DeadlineEscalationService.php @@ -34,6 +34,8 @@ /** * Threshold-aware escalation dispatcher for the daily termijn scan. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-04-daily-scan-escalation/tasks.md */ class DeadlineEscalationService { /** diff --git a/lib/Service/DeadlineExtensionService.php b/lib/Service/DeadlineExtensionService.php index a01becce1..07721ba79 100644 --- a/lib/Service/DeadlineExtensionService.php +++ b/lib/Service/DeadlineExtensionService.php @@ -36,6 +36,8 @@ /** * AWB 4:14 verlenging engine on a TermijnInstance. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-03-pause-extension/tasks.md */ class DeadlineExtensionService { /** diff --git a/lib/Service/DeadlinePauseService.php b/lib/Service/DeadlinePauseService.php index 9fccf49b2..3c1764192 100644 --- a/lib/Service/DeadlinePauseService.php +++ b/lib/Service/DeadlinePauseService.php @@ -35,6 +35,8 @@ /** * AWB 4:5 / 4:15 pause + resume on a TermijnInstance. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-03-pause-extension/tasks.md */ class DeadlinePauseService { /** diff --git a/lib/Service/DoorlooptijdService.php b/lib/Service/DoorlooptijdService.php index 7d0edbd94..07c1eb61b 100644 --- a/lib/Service/DoorlooptijdService.php +++ b/lib/Service/DoorlooptijdService.php @@ -42,6 +42,8 @@ /** * Computes throughput-time metrics for the case dashboard. + * + * @spec openspec/changes/doorlooptijd-dashboard/tasks.md#T01 */ class DoorlooptijdService { diff --git a/lib/Service/DsoIntakeService.php b/lib/Service/DsoIntakeService.php index cd08cb57a..44d4929b8 100644 --- a/lib/Service/DsoIntakeService.php +++ b/lib/Service/DsoIntakeService.php @@ -36,6 +36,8 @@ * Creates permit cases from DSO vergunningaanvraag messages. * Supports multiple activities per application and calculates * deadlines based on procedure type (regulier: 8 weeks, uitgebreid: 26 weeks). + * + * @spec openspec/specs/dso-omgevingsloket-client/spec.md */ class DsoIntakeService { @@ -139,6 +141,8 @@ private function storeCaseProperties( * @param string $procedureType The procedure type (regulier or uitgebreid) * * @return string ISO 8601 duration + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function getDeadlineDuration(string $procedureType): string { return self::DEADLINE_DURATIONS[$procedureType] ?? self::DEADLINE_DURATIONS['regulier']; diff --git a/lib/Service/DwangsomBezwaarService.php b/lib/Service/DwangsomBezwaarService.php index 91e063fd7..ab78f630b 100644 --- a/lib/Service/DwangsomBezwaarService.php +++ b/lib/Service/DwangsomBezwaarService.php @@ -38,6 +38,8 @@ /** * Bezwaar lifecycle for a DwangsomBerekening. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-10-bezwaar-rest-api/tasks.md */ class DwangsomBezwaarService { use SearchesObjects; diff --git a/lib/Service/DwangsomCalculationService.php b/lib/Service/DwangsomCalculationService.php index 80fe68205..f9f32c45e 100644 --- a/lib/Service/DwangsomCalculationService.php +++ b/lib/Service/DwangsomCalculationService.php @@ -42,6 +42,8 @@ /** * Daily-accruing dwangsom calculator. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-06-dwangsom-calculation/tasks.md */ class DwangsomCalculationService { use SearchesObjects; diff --git a/lib/Service/DwangsomUitbetalingService.php b/lib/Service/DwangsomUitbetalingService.php index bb64b5915..7b513d5fa 100644 --- a/lib/Service/DwangsomUitbetalingService.php +++ b/lib/Service/DwangsomUitbetalingService.php @@ -38,6 +38,8 @@ /** * Payment-signal preparation + callback processing for dwangsom payouts. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-07-financial-integration/tasks.md */ class DwangsomUitbetalingService { use SearchesObjects; diff --git a/lib/Service/EmailArchivalService.php b/lib/Service/EmailArchivalService.php index b50ac2743..8ddf15621 100644 --- a/lib/Service/EmailArchivalService.php +++ b/lib/Service/EmailArchivalService.php @@ -35,6 +35,8 @@ /** * Archival surface for emails linked to a case. + * + * @spec openspec/changes/case-email-integration/tasks.md#T05 */ class EmailArchivalService { diff --git a/lib/Service/EmailTemplateService.php b/lib/Service/EmailTemplateService.php index 49d411b95..86435f4d6 100644 --- a/lib/Service/EmailTemplateService.php +++ b/lib/Service/EmailTemplateService.php @@ -39,6 +39,8 @@ * OpenRegister access is delegated to EmailTemplateRepository; what stays here * is the template domain itself — versioning, seeding and placeholder * resolution. + * + * @spec openspec/changes/case-email-integration/tasks.md#T04 */ class EmailTemplateService { diff --git a/lib/Service/External/Brp/BrpHaalCentraalAdapterInterface.php b/lib/Service/External/Brp/BrpHaalCentraalAdapterInterface.php index 78a474454..3c2c946df 100644 --- a/lib/Service/External/Brp/BrpHaalCentraalAdapterInterface.php +++ b/lib/Service/External/Brp/BrpHaalCentraalAdapterInterface.php @@ -95,6 +95,8 @@ interface BrpHaalCentraalAdapterInterface { * * @return BrpLookupResult The lookup outcome (status + persoon * envelope minus BSN). + * + * @spec openspec/changes/brp-kvk-register-sets/proposal.md */ public function lookup(string $bsn, array $context = []): BrpLookupResult; @@ -103,6 +105,8 @@ public function lookup(string $bsn, array $context = []): BrpLookupResult; * Haal Centraal. * * @return bool TRUE when the adapter is a log-only stub. + * + * @spec openspec/changes/brp-kvk-register-sets/proposal.md */ public function isDormant(): bool; }//end interface diff --git a/lib/Service/External/Brp/HaalCentraalBrpAdapter.php b/lib/Service/External/Brp/HaalCentraalBrpAdapter.php index ec26bb63f..a6b305e56 100644 --- a/lib/Service/External/Brp/HaalCentraalBrpAdapter.php +++ b/lib/Service/External/Brp/HaalCentraalBrpAdapter.php @@ -151,6 +151,8 @@ public function lookup(string $bsn, array $context = []): BrpLookupResult { * A configured live adapter is not dormant. * * @return bool + * + * @spec openspec/specs/external-integration-test-wiring/spec.md */ public function isDormant(): bool { return false; diff --git a/lib/Service/External/Brp/LogBrpHaalCentraalAdapter.php b/lib/Service/External/Brp/LogBrpHaalCentraalAdapter.php index 1cf180f6a..a4d7297f8 100644 --- a/lib/Service/External/Brp/LogBrpHaalCentraalAdapter.php +++ b/lib/Service/External/Brp/LogBrpHaalCentraalAdapter.php @@ -96,6 +96,8 @@ public function lookup(string $bsn, array $context = []): BrpLookupResult { * @inheritDoc * * @return bool + * + * @spec openspec/specs/brp-register/spec.md#requirement-brp-person-register-schema-exists-in-openregister */ public function isDormant(): bool { return true; diff --git a/lib/Service/External/Kvk/KvkApiAdapter.php b/lib/Service/External/Kvk/KvkApiAdapter.php index 0466bc5d8..142fcc903 100644 --- a/lib/Service/External/Kvk/KvkApiAdapter.php +++ b/lib/Service/External/Kvk/KvkApiAdapter.php @@ -148,6 +148,8 @@ public function lookup(string $kvkNumber, array $context = []): KvkLookupResult * A configured live adapter is not dormant. * * @return bool + * + * @spec openspec/specs/external-integration-test-wiring/spec.md */ public function isDormant(): bool { return false; diff --git a/lib/Service/External/Kvk/KvkHandelsregisterAdapterInterface.php b/lib/Service/External/Kvk/KvkHandelsregisterAdapterInterface.php index c4135597f..b683838b4 100644 --- a/lib/Service/External/Kvk/KvkHandelsregisterAdapterInterface.php +++ b/lib/Service/External/Kvk/KvkHandelsregisterAdapterInterface.php @@ -84,6 +84,8 @@ interface KvkHandelsregisterAdapterInterface { * * @return KvkLookupResult The lookup outcome (status + entity * envelope + optional vestiging list). + * + * @spec openspec/changes/brp-kvk-register-sets/proposal.md */ public function lookup(string $kvkNumber, array $context = []): KvkLookupResult; @@ -92,6 +94,8 @@ public function lookup(string $kvkNumber, array $context = []): KvkLookupResult; * the KvK Handelsregister. * * @return bool TRUE when the adapter is a log-only stub. + * + * @spec openspec/changes/brp-kvk-register-sets/proposal.md */ public function isDormant(): bool; }//end interface diff --git a/lib/Service/External/Kvk/LogKvkHandelsregisterAdapter.php b/lib/Service/External/Kvk/LogKvkHandelsregisterAdapter.php index 5d624f01a..61509debb 100644 --- a/lib/Service/External/Kvk/LogKvkHandelsregisterAdapter.php +++ b/lib/Service/External/Kvk/LogKvkHandelsregisterAdapter.php @@ -94,6 +94,8 @@ public function lookup(string $kvkNumber, array $context = []): KvkLookupResult * @inheritDoc * * @return bool + * + * @spec openspec/specs/kvk-register/spec.md#requirement-kvk-company-register-schema-exists-in-openregister */ public function isDormant(): bool { return true; diff --git a/lib/Service/External/Zgw/LogZgwExternalAdapter.php b/lib/Service/External/Zgw/LogZgwExternalAdapter.php index b1f6277b1..eeffa311e 100644 --- a/lib/Service/External/Zgw/LogZgwExternalAdapter.php +++ b/lib/Service/External/Zgw/LogZgwExternalAdapter.php @@ -140,6 +140,8 @@ public function submitDocument(array $documentEnvelope, array $context = []): Zg * @inheritDoc * * @return bool + * + * @spec openspec/specs/zgw-api-mapping/spec.md#requirement-drc-documenten-api-resources-must-be-mappable */ public function isDormant(): bool { return true; diff --git a/lib/Service/External/Zgw/ZgwExternalAdapterInterface.php b/lib/Service/External/Zgw/ZgwExternalAdapterInterface.php index 50ff46ddb..f60adf1d4 100644 --- a/lib/Service/External/Zgw/ZgwExternalAdapterInterface.php +++ b/lib/Service/External/Zgw/ZgwExternalAdapterInterface.php @@ -93,6 +93,8 @@ interface ZgwExternalAdapterInterface { * * @return ZgwPushResult The dispatch outcome (status + * receiver-side zaak URL). + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function submitZaak(array $caseEnvelope, array $context = []): ZgwPushResult; @@ -110,6 +112,8 @@ public function submitZaak(array $caseEnvelope, array $context = []): ZgwPushRes * * @return ZgwPushResult The dispatch outcome (status + * receiver-side document URL). + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function submitDocument(array $documentEnvelope, array $context = []): ZgwPushResult; @@ -118,6 +122,8 @@ public function submitDocument(array $documentEnvelope, array $context = []): Zg * any external ZGW stack. * * @return bool TRUE when the adapter is a log-only stub. + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function isDormant(): bool; }//end interface diff --git a/lib/Service/External/Ztc/LogZtcCatalogiAdapter.php b/lib/Service/External/Ztc/LogZtcCatalogiAdapter.php index 58c10f8b2..0974cca15 100644 --- a/lib/Service/External/Ztc/LogZtcCatalogiAdapter.php +++ b/lib/Service/External/Ztc/LogZtcCatalogiAdapter.php @@ -120,6 +120,8 @@ public function importZaakType(string $caseTypeUrl, array $context = []): ZtcRes * @inheritDoc * * @return bool + * + * @spec openspec/specs/zgw-api-mapping/spec.md#requirement-ztc-catalogi-api-resources-must-be-fully-mappable */ public function isDormant(): bool { return true; diff --git a/lib/Service/External/Ztc/ZtcCatalogiAdapterInterface.php b/lib/Service/External/Ztc/ZtcCatalogiAdapterInterface.php index 65a43de66..f0548ac14 100644 --- a/lib/Service/External/Ztc/ZtcCatalogiAdapterInterface.php +++ b/lib/Service/External/Ztc/ZtcCatalogiAdapterInterface.php @@ -87,6 +87,8 @@ interface ZtcCatalogiAdapterInterface { * correlationId. * * @return ZtcResult The lookup outcome (status + canonical URL). + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function resolveZaakType(string $caseTypeId, string $receiverSourceSlug, array $context = []): ZtcResult; @@ -108,6 +110,8 @@ public function resolveZaakType(string $caseTypeId, string $receiverSourceSlug, * * @return ZtcResult The import outcome (status + * `localZaakTypeUrl`). + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function importZaakType(string $caseTypeUrl, array $context = []): ZtcResult; @@ -116,6 +120,8 @@ public function importZaakType(string $caseTypeUrl, array $context = []): ZtcRes * an external Catalogi-API. * * @return bool TRUE when the adapter is a log-only stub. + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function isDormant(): bool; }//end interface diff --git a/lib/Service/InformatieobjectAccessGuard.php b/lib/Service/InformatieobjectAccessGuard.php index 48872233f..73d1985f9 100644 --- a/lib/Service/InformatieobjectAccessGuard.php +++ b/lib/Service/InformatieobjectAccessGuard.php @@ -41,6 +41,8 @@ /** * Enforces vertrouwelijkheidaanduiding-based access control on informatieobjecten. + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T03 */ class InformatieobjectAccessGuard { /** diff --git a/lib/Service/Kcc/BelplanRoutingService.php b/lib/Service/Kcc/BelplanRoutingService.php index 1a664ca4e..0cf9b8c6f 100644 --- a/lib/Service/Kcc/BelplanRoutingService.php +++ b/lib/Service/Kcc/BelplanRoutingService.php @@ -34,6 +34,8 @@ /** * Belplan-driven KCC call routing. + * + * @spec openspec/changes/kcc-werkplek-zaaksysteem-bridge/tasks.md#T06 */ class BelplanRoutingService { /** diff --git a/lib/Service/Kcc/CallbackService.php b/lib/Service/Kcc/CallbackService.php index ffe257df8..76e414fa5 100644 --- a/lib/Service/Kcc/CallbackService.php +++ b/lib/Service/Kcc/CallbackService.php @@ -41,6 +41,8 @@ * * @SuppressWarnings(PHPMD.BooleanArgumentFlag) — $isPrivileged is the standard * cross-agent/own-record scoping flag used across the app's controllers. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-05 */ class CallbackService { /** @@ -71,6 +73,8 @@ public function __construct( * @return array The callback payload. * * @throws OCSBadRequestException When validation fails. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-05 */ public function buildPayload(array $data, string $agentId): array { $phone = trim((string)($data['customerPhone'] ?? '')); @@ -144,6 +148,8 @@ public function schedule(array $data, string $agentId): array { * @return array The updated callback record. * * @SuppressWarnings(PHPMD.BooleanArgumentFlag) — $succeeded is the attempt outcome. + * + * @spec openspec/specs/kcc-klantcontact-integratie/spec.md#requirement-callback-scheduling-and-sla-tracking */ public function applyAttempt(array $callback, bool $succeeded, ?DateTimeImmutable $now = null): array { $now = ($now ?? new DateTimeImmutable()); @@ -181,6 +187,8 @@ public function applyAttempt(array $callback, bool $succeeded, ?DateTimeImmutabl * @return array The cancelled callback record. * * @throws OCSBadRequestException When not found or not owned. + * + * @spec openspec/specs/kcc-klantcontact-integratie/spec.md#requirement-callback-scheduling-and-sla-tracking */ public function cancel(string $id, string $agentId, bool $isPrivileged = false): array { [$objectService, $register, $schema] = $this->resolve(); @@ -208,6 +216,8 @@ public function cancel(string $id, string $agentId, bool $isPrivileged = false): * @param bool $isPrivileged Whether the caller may see all callbacks. * * @return array> The callback requests. + * + * @spec openspec/specs/kcc-klantcontact-integratie/spec.md#requirement-callback-scheduling-and-sla-tracking */ public function list(array $filters, string $agentId, bool $isPrivileged = false): array { [$objectService, $register, $schema] = $this->resolve(); @@ -232,6 +242,8 @@ public function list(array $filters, string $agentId, bool $isPrivileged = false * @param array $callback The callback record. * * @return array The saved record. + * + * @spec openspec/specs/kcc-klantcontact-integratie/spec.md#requirement-callback-scheduling-and-sla-tracking */ public function persist(string $id, array $callback): array { [$objectService, $register, $schema] = $this->resolve(); diff --git a/lib/Service/Kcc/ContactMomentService.php b/lib/Service/Kcc/ContactMomentService.php index 823b14c1a..5083b8c94 100644 --- a/lib/Service/Kcc/ContactMomentService.php +++ b/lib/Service/Kcc/ContactMomentService.php @@ -44,6 +44,8 @@ * validation, persistence and IDOR-scoped queries for one entity. * @SuppressWarnings(PHPMD.BooleanArgumentFlag) — $isPrivileged is the standard * cross-agent/own-record scoping flag used across the app's controllers. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-02 */ class ContactMomentService { /** @@ -84,6 +86,8 @@ public function __construct( * @return array The sanitised contact-moment payload. * * @throws OCSBadRequestException When validation fails. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-02 */ public function buildPayload(array $data, string $agentId): array { $channel = $this->validateEnum(value: (string)($data['channel'] ?? ''), allowed: self::CHANNELS, label: 'channel'); @@ -226,6 +230,8 @@ public function create(array $data, string $agentId): array { * @return array The updated contact moment. * * @throws OCSBadRequestException When not found or not owned. + * + * @spec openspec/specs/kcc-klantcontact-integratie/spec.md#requirement-contactmoment-records-capture-full-interaction-context */ public function update(string $id, array $data, string $agentId, bool $isPrivileged = false): array { [$objectService, $register, $schema] = $this->resolve(); @@ -297,6 +303,8 @@ private function mergeUpdate(array $existing, array $data): array { * @param bool $isPrivileged Whether the caller may see all moments. * * @return array> The contact moments. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-02 */ public function list(array $filters, string $agentId, bool $isPrivileged = false): array { [$objectService, $register, $schema] = $this->resolve(); @@ -328,6 +336,8 @@ public function list(array $filters, string $agentId, bool $isPrivileged = false * @return array The contact moment. * * @throws OCSBadRequestException When not found or not owned. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-02 */ public function get(string $id, string $agentId, bool $isPrivileged = false): array { [$objectService, $register, $schema] = $this->resolve(); @@ -349,6 +359,8 @@ public function get(string $id, string $agentId, bool $isPrivileged = false): ar * @param bool $isPrivileged Whether the caller may see any moment. * * @return array> Related contact moments. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-02 */ public function related(string $id, string $agentId, bool $isPrivileged = false): array { [$objectService, $register, $schema] = $this->resolve(); diff --git a/lib/Service/Kcc/RoutingEngine.php b/lib/Service/Kcc/RoutingEngine.php index 8f568f59f..53716ea6a 100644 --- a/lib/Service/Kcc/RoutingEngine.php +++ b/lib/Service/Kcc/RoutingEngine.php @@ -35,6 +35,8 @@ * Deterministic routing-rule evaluation and agent ranking for the KCC. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-03 */ class RoutingEngine { /** @@ -56,6 +58,8 @@ class RoutingEngine { * @param \DateTimeImmutable|null $now Reference time (for time-of-day rules). * * @return array|null The routing result, or null when unmatched. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-03 */ public function evaluate(array $rules, array $contactMoment, ?\DateTimeImmutable $now = null): ?array { $now = ($now ?? new DateTimeImmutable()); @@ -98,6 +102,8 @@ static function (array $first, array $second): int { * @param \DateTimeImmutable $now Reference time. * * @return bool True when all conditions match. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-03 */ public function ruleMatches(array $rule, array $contactMoment, \DateTimeImmutable $now): bool { $conditions = ($rule['matchConditions'] ?? []); @@ -219,6 +225,8 @@ private function timeOfDayMatches(string $value, \DateTimeImmutable $now): bool * @param int $limit Maximum results. * * @return array> Ranked agents with motivation. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-03 */ public function rankAgents(array $agents, string $team, array $contactMoment, int $limit = 3): array { $domain = strtolower((string)($contactMoment['assignedDomain'] ?? '')); diff --git a/lib/Service/Kcc/RoutingRuleService.php b/lib/Service/Kcc/RoutingRuleService.php index cbc6739ba..e1cb3a30c 100644 --- a/lib/Service/Kcc/RoutingRuleService.php +++ b/lib/Service/Kcc/RoutingRuleService.php @@ -38,6 +38,8 @@ * Persists routing rules / agents and drives the routing engine. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-17 */ class RoutingRuleService { /** @@ -61,6 +63,8 @@ public function __construct( * List all routing rules. * * @return array> The routing rules. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-17 */ public function listRules(): array { [$objectService, $register, $schema] = $this->resolve(schemaKey: 'routing_rule_schema'); @@ -76,6 +80,8 @@ public function listRules(): array { * @return array The saved rule. * * @throws OCSBadRequestException When validation fails. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-17 */ public function createRule(array $data): array { $payload = $this->validateRule(data: $data); @@ -92,6 +98,8 @@ public function createRule(array $data): array { * @return array The saved rule. * * @throws OCSBadRequestException When validation fails or not found. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-17 */ public function updateRule(string $id, array $data): array { $payload = $this->validateRule(data: $data); @@ -165,6 +173,8 @@ public function route(array $contactMoment, ?\DateTimeImmutable $now = null): ar * List all KCC agents. * * @return array> The agents. + * + * @spec openspec/changes/kcc-routing-onto-or-decision-tables/specs/kcc-routing/spec.md#requirement-routing-rules-evaluate-through-the-shared-decision-table-engine */ public function listAgents(): array { [$objectService, $register, $schema] = $this->resolve(schemaKey: 'kcc_agent_schema'); diff --git a/lib/Service/Kcc/SentimentService.php b/lib/Service/Kcc/SentimentService.php index 27f87a412..d21628354 100644 --- a/lib/Service/Kcc/SentimentService.php +++ b/lib/Service/Kcc/SentimentService.php @@ -34,6 +34,8 @@ /** * Deterministic Dutch sentiment analyser for KCC transcripts. + * + * @spec openspec/changes/kcc-werkplek-zaaksysteem-bridge/tasks.md#T09 */ class SentimentService { /** diff --git a/lib/Service/Kcc/SlaCalculator.php b/lib/Service/Kcc/SlaCalculator.php index 77da9db76..517939ed5 100644 --- a/lib/Service/Kcc/SlaCalculator.php +++ b/lib/Service/Kcc/SlaCalculator.php @@ -37,6 +37,8 @@ * Deterministic SLA / working-day calculator for the KCC integration. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ class SlaCalculator { /** @@ -74,6 +76,8 @@ class SlaCalculator { * @param DateTimeInterface $date The date to inspect. * * @return bool True for Saturday or Sunday. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function isWeekend(DateTimeInterface $date): bool { $dow = (int)$date->format('N'); @@ -90,6 +94,8 @@ public function isWeekend(DateTimeInterface $date): bool { * @param DateTimeInterface $date The date to inspect. * * @return bool True when the date is a recognised public holiday. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function isDutchHoliday(DateTimeInterface $date): bool { $year = (int)$date->format('Y'); @@ -104,6 +110,8 @@ public function isDutchHoliday(DateTimeInterface $date): bool { * @param DateTimeInterface $date The date to inspect. * * @return bool True for a working day. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function isWorkingDay(DateTimeInterface $date): bool { return ($this->isWeekend(date: $date) === false && $this->isDutchHoliday(date: $date) === false); @@ -118,6 +126,8 @@ public function isWorkingDay(DateTimeInterface $date): bool { * @param int $days Number of working days to add (>= 0). * * @return DateTimeImmutable The resulting date-time. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function addWorkingDays(DateTimeImmutable $start, int $days): DateTimeImmutable { $result = $start; @@ -140,6 +150,8 @@ public function addWorkingDays(DateTimeImmutable $start, int $days): DateTimeImm * @param DateTimeImmutable $end Range end (inclusive). * * @return int Number of working days in the range (0 when end < start). + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function countWorkingDays(DateTimeImmutable $start, DateTimeImmutable $end): int { $startDay = $start->setTime(0, 0); @@ -172,6 +184,8 @@ public function countWorkingDays(DateTimeImmutable $start, DateTimeImmutable $en * @param DateTimeImmutable $start The contact start time. * * @return DateTimeImmutable The SLA deadline. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function deadlineFor(string $channel, DateTimeImmutable $start): DateTimeImmutable { if (isset(self::CHANNEL_SLA_WORKING_DAYS[$channel]) === true) { @@ -190,6 +204,8 @@ public function deadlineFor(string $channel, DateTimeImmutable $start): DateTime * @param DateTimeImmutable $now The reference (current) time. * * @return bool True when the deadline has passed. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function isBreached(string $channel, DateTimeImmutable $start, DateTimeImmutable $now): bool { return ($now > $this->deadlineFor(channel: $channel, start: $start)); @@ -204,6 +220,8 @@ public function isBreached(string $channel, DateTimeImmutable $start, DateTimeIm * @param int $attemptCount The number of attempts already made (>= 0). * * @return DateTimeImmutable The next attempt time. + * + * @spec openspec/changes/kcc-klantcontact-integratie/tasks.md#TASK-KCC-25 */ public function nextRetryAt(DateTimeImmutable $from, int $attemptCount): DateTimeImmutable { $baseMinutes = 15; diff --git a/lib/Service/MandaatEscalatieService.php b/lib/Service/MandaatEscalatieService.php index 2ddf8a563..25cb841eb 100644 --- a/lib/Service/MandaatEscalatieService.php +++ b/lib/Service/MandaatEscalatieService.php @@ -36,6 +36,8 @@ /** * Mandate escalation lifecycle. + * + * @spec openspec/changes/mandaat-matrix-03-escalation-engine/tasks.md */ class MandaatEscalatieService { use SearchesObjects; diff --git a/lib/Service/MandaatGebruikService.php b/lib/Service/MandaatGebruikService.php index 81e65e135..86cadc216 100644 --- a/lib/Service/MandaatGebruikService.php +++ b/lib/Service/MandaatGebruikService.php @@ -35,6 +35,8 @@ /** * Immutable audit log for mandate uses. + * + * @spec openspec/changes/mandaat-matrix-05-case-decision-integration/tasks.md */ class MandaatGebruikService { use SearchesObjects; diff --git a/lib/Service/MandaatImportService.php b/lib/Service/MandaatImportService.php index 157202fa9..a485970da 100644 --- a/lib/Service/MandaatImportService.php +++ b/lib/Service/MandaatImportService.php @@ -46,6 +46,8 @@ * The wire format is parsed by {@see MandaatCsvParser} and every register read * or write goes through {@see MandaatRepository}; what stays here is the import * decision — new vs changed vs removed — and the approval state machine. + * + * @spec openspec/changes/mandaat-matrix-04-decidesk-import/tasks.md */ class MandaatImportService { use SearchesObjects; diff --git a/lib/Service/MapTileService.php b/lib/Service/MapTileService.php index 0ee5ca478..cbd8acc90 100644 --- a/lib/Service/MapTileService.php +++ b/lib/Service/MapTileService.php @@ -37,6 +37,8 @@ /** * Stateless tile-list manifest builder for offline PWA pre-caching. + * + * @spec openspec/changes/mobiel-inspectie-offline/tasks.md#Task-6 */ class MapTileService { /** diff --git a/lib/Service/MentionNotificationService.php b/lib/Service/MentionNotificationService.php index 232e20865..049a8eed8 100644 --- a/lib/Service/MentionNotificationService.php +++ b/lib/Service/MentionNotificationService.php @@ -36,6 +36,8 @@ /** * Service for sending Nextcloud notifications for note `@mention`s. + * + * @spec openspec/specs/ncvue-w2-leaves-adoption/spec.md */ class MentionNotificationService { /** diff --git a/lib/Service/MilestoneService.php b/lib/Service/MilestoneService.php index 6708cc4aa..21939ac2d 100644 --- a/lib/Service/MilestoneService.php +++ b/lib/Service/MilestoneService.php @@ -40,6 +40,8 @@ * Reads go through {@see MilestoneRepository} and the stalled-case report is * owned by {@see StalledCaseDetector}; what stays here is milestone mutation * (mark/reverse) and per-case progress. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class MilestoneService { diff --git a/lib/Service/NoticeOfDefaultService.php b/lib/Service/NoticeOfDefaultService.php index fc54f9f7d..0ad554e9b 100644 --- a/lib/Service/NoticeOfDefaultService.php +++ b/lib/Service/NoticeOfDefaultService.php @@ -40,6 +40,8 @@ /** * AWB 4:17 ingebrekestelling registration + DwangsomBerekening creation. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-05-ingebrekestelling/tasks.md */ class NoticeOfDefaultService { use SearchesObjects; diff --git a/lib/Service/NotificatieService.php b/lib/Service/NotificatieService.php index 3d3c499c2..97eee5418 100644 --- a/lib/Service/NotificatieService.php +++ b/lib/Service/NotificatieService.php @@ -34,6 +34,8 @@ * Service for publishing ZGW notifications to subscribers. * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ class NotificatieService { diff --git a/lib/Service/ObjectSchemaSlugResolver.php b/lib/Service/ObjectSchemaSlugResolver.php index 5e537618f..b67700bc7 100644 --- a/lib/Service/ObjectSchemaSlugResolver.php +++ b/lib/Service/ObjectSchemaSlugResolver.php @@ -46,6 +46,8 @@ /** * Turns the schema id an OpenRegister object payload carries into its slug. + * + * @spec openspec/specs/bezwaar-lifecycle/spec.md */ class ObjectSchemaSlugResolver { diff --git a/lib/Service/Pdok/PdokBagService.php b/lib/Service/Pdok/PdokBagService.php index 5f1aef893..4eb9c990c 100644 --- a/lib/Service/Pdok/PdokBagService.php +++ b/lib/Service/Pdok/PdokBagService.php @@ -45,6 +45,8 @@ /** * Single ingress for PDOK BAG WFS v2_0 lookups. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class PdokBagService { diff --git a/lib/Service/PdokService.php b/lib/Service/PdokService.php index cbd92fcfe..9b46ecc3b 100644 --- a/lib/Service/PdokService.php +++ b/lib/Service/PdokService.php @@ -61,6 +61,8 @@ /** * Backend-side PDOK shim consuming the openconnector PDOK source adapters. + * + * @spec openspec/specs/gis-integration/spec.md */ class PdokService { /** @@ -125,6 +127,8 @@ public function __construct( * @param int $rows Maximum suggestions to return. * * @return array> Normalised suggestion list. + * + * @spec openspec/changes/migrate-pdok-to-openconnector/tasks.md */ public function searchAddress(string $query, array $filters = [], int $rows = 10): array { $this->lastWarning = null; @@ -154,6 +158,8 @@ public function searchAddress(string $query, array $filters = [], int $rows = 10 * * @return array|null The normalised address envelope, * or null when not found / degraded. + * + * @spec openspec/changes/migrate-pdok-to-openconnector/tasks.md */ public function lookupAddress(string $id): ?array { $this->lastWarning = null; @@ -233,6 +239,8 @@ public function searchParcel(array $criteria): array { * featureFlagActive: bool, * lastWarning: array{messageKey:string,status:int}|null, * } + * + * @spec exclude phpstan dead-code cleanup only — dropped an always-false `$route === null` */ public function getServiceStatus(): array { return [ @@ -247,6 +255,8 @@ public function getServiceStatus(): array { * `messageKey` to the UI for an i18n-backed banner. * * @return array{messageKey:string,status:int}|null + * + * @spec exclude phpstan dead-code cleanup only — dropped an always-false `$route === null` */ public function lastWarning(): ?array { return $this->lastWarning; diff --git a/lib/Service/ProcessMiningService.php b/lib/Service/ProcessMiningService.php index 1f731ecf2..973883304 100644 --- a/lib/Service/ProcessMiningService.php +++ b/lib/Service/ProcessMiningService.php @@ -56,6 +56,8 @@ /** * Computes process-mining bottleneck metrics from recorded status history. + * + * @spec openspec/changes/process-mining-bottlenecks/tasks.md#T01 */ class ProcessMiningService { /** diff --git a/lib/Service/SelectionReassignmentService.php b/lib/Service/SelectionReassignmentService.php index ca32e771a..01ede95e0 100644 --- a/lib/Service/SelectionReassignmentService.php +++ b/lib/Service/SelectionReassignmentService.php @@ -35,6 +35,8 @@ * separate operations that happen to share a write, and putting both on one * class took it past the complexity threshold. The shared write lives in * {@see WritesReassignments}, so the audit entry cannot drift between them. + * + * @spec openspec/changes/reassignment-is-a-bulk-action/specs/reassignment-bulk-action/spec.md */ class SelectionReassignmentService { diff --git a/lib/Service/ShillinqIntegrationService.php b/lib/Service/ShillinqIntegrationService.php index 6ff824454..1f2f24e1f 100644 --- a/lib/Service/ShillinqIntegrationService.php +++ b/lib/Service/ShillinqIntegrationService.php @@ -30,6 +30,8 @@ /** * Shillinq HTTP integration with retry + backoff. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-10-billing-shillinq/tasks.md */ class ShillinqIntegrationService { /** @@ -64,6 +66,8 @@ public function __construct( * @param array> $events Events. * * @return array>> Keyed by `:`. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-10-billing-shillinq/tasks.md */ public function groupForInvoicing(array $events): array { $grouped = []; @@ -93,6 +97,8 @@ public function groupForInvoicing(array $events): array { * @param array> $events Events. * * @return array + * + * @spec openspec/changes/tenant-zaaksysteem-saas-10-billing-shillinq/tasks.md */ public function buildInvoicePayload(string $tenantId, string $month, array $events): array { $lineItems = []; diff --git a/lib/Service/Stuf/CircuitBreakerService.php b/lib/Service/Stuf/CircuitBreakerService.php index cea402d58..2acad0aa8 100644 --- a/lib/Service/Stuf/CircuitBreakerService.php +++ b/lib/Service/Stuf/CircuitBreakerService.php @@ -38,6 +38,8 @@ /** * Per-endpoint circuit breaker. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-circuit-breaker-and-retry */ class CircuitBreakerService { public const THRESHOLD = 4; diff --git a/lib/Service/Stuf/CircuitOpenException.php b/lib/Service/Stuf/CircuitOpenException.php index 15388c0ad..4d5f2443e 100644 --- a/lib/Service/Stuf/CircuitOpenException.php +++ b/lib/Service/Stuf/CircuitOpenException.php @@ -29,6 +29,8 @@ /** * Short-circuited: circuit breaker is open for the endpoint. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md */ class CircuitOpenException extends StufException { }//end class diff --git a/lib/Service/Stuf/ContactBetrokkeneMapper.php b/lib/Service/Stuf/ContactBetrokkeneMapper.php index 3a157d5bd..5ea2c8d53 100644 --- a/lib/Service/Stuf/ContactBetrokkeneMapper.php +++ b/lib/Service/Stuf/ContactBetrokkeneMapper.php @@ -37,6 +37,8 @@ /** * Maps dossiq Contact entities to zaaksysteem betrokkenen. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-bidirectional-mapping */ class ContactBetrokkeneMapper { /** diff --git a/lib/Service/Stuf/NeedsInputDispatcher.php b/lib/Service/Stuf/NeedsInputDispatcher.php index ca3097a85..fb1644684 100644 --- a/lib/Service/Stuf/NeedsInputDispatcher.php +++ b/lib/Service/Stuf/NeedsInputDispatcher.php @@ -49,6 +49,8 @@ /** * Dispatches needs-input events for the StUF adapter. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-needs-input-escalation */ class NeedsInputDispatcher { /** diff --git a/lib/Service/Stuf/PayloadTooLargeException.php b/lib/Service/Stuf/PayloadTooLargeException.php index 1ce8ae50f..4c0f3bacc 100644 --- a/lib/Service/Stuf/PayloadTooLargeException.php +++ b/lib/Service/Stuf/PayloadTooLargeException.php @@ -29,6 +29,8 @@ /** * Pre-send domain error: payload too large for StUF envelope. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md */ class PayloadTooLargeException extends StufException { }//end class diff --git a/lib/Service/Stuf/StufException.php b/lib/Service/Stuf/StufException.php index fef98df1b..19b150305 100644 --- a/lib/Service/Stuf/StufException.php +++ b/lib/Service/Stuf/StufException.php @@ -28,6 +28,8 @@ /** * Base StUF adapter exception. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md */ class StufException extends RuntimeException { }//end class diff --git a/lib/Service/Stuf/StufHttpClient.php b/lib/Service/Stuf/StufHttpClient.php index 299e3d507..08ca23aa5 100644 --- a/lib/Service/Stuf/StufHttpClient.php +++ b/lib/Service/Stuf/StufHttpClient.php @@ -43,6 +43,8 @@ /** * Sends StUF SOAP envelopes over HTTPS with WSSE+mTLS auth. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-secure-transport */ class StufHttpClient { public const DEFAULT_TIMEOUT_SECONDS = 30; diff --git a/lib/Service/Stuf/StufMessageHandler.php b/lib/Service/Stuf/StufMessageHandler.php index 35cb8f22b..c553339fc 100644 --- a/lib/Service/Stuf/StufMessageHandler.php +++ b/lib/Service/Stuf/StufMessageHandler.php @@ -33,6 +33,8 @@ /** * Persists and updates StufMessage audit rows. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-outbound-audit-log */ class StufMessageHandler { diff --git a/lib/Service/Stuf/StufMessageParser.php b/lib/Service/Stuf/StufMessageParser.php index b480dd6ff..838aa9e76 100644 --- a/lib/Service/Stuf/StufMessageParser.php +++ b/lib/Service/Stuf/StufMessageParser.php @@ -37,6 +37,8 @@ /** * Parses StUF response envelopes. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-response-parsing */ class StufMessageParser { public const NS_SOAPENV = StufMessageBuilder::NS_SOAPENV; diff --git a/lib/Service/Stuf/StufVaultService.php b/lib/Service/Stuf/StufVaultService.php index c3d4d2d10..193eda05c 100644 --- a/lib/Service/Stuf/StufVaultService.php +++ b/lib/Service/Stuf/StufVaultService.php @@ -37,6 +37,8 @@ /** * Resolves vault references to plaintext secrets at send time. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-secure-credential-handling */ class StufVaultService { /** diff --git a/lib/Service/Stuf/TimeoutException.php b/lib/Service/Stuf/TimeoutException.php index 9c73b3af5..d17685308 100644 --- a/lib/Service/Stuf/TimeoutException.php +++ b/lib/Service/Stuf/TimeoutException.php @@ -29,6 +29,8 @@ /** * Synchronous vraag/antwoord exceeded the configured timeout. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md */ class TimeoutException extends StufException { }//end class diff --git a/lib/Service/Stuf/VrijBerichtNotRegisteredException.php b/lib/Service/Stuf/VrijBerichtNotRegisteredException.php index 1f2f12206..8b40a234b 100644 --- a/lib/Service/Stuf/VrijBerichtNotRegisteredException.php +++ b/lib/Service/Stuf/VrijBerichtNotRegisteredException.php @@ -29,6 +29,8 @@ /** * Pre-send domain error: vrijBericht template not registered. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md */ class VrijBerichtNotRegisteredException extends StufException { }//end class diff --git a/lib/Service/Stuf/ZaaktypeNotMappedException.php b/lib/Service/Stuf/ZaaktypeNotMappedException.php index 261f46fef..958af5d49 100644 --- a/lib/Service/Stuf/ZaaktypeNotMappedException.php +++ b/lib/Service/Stuf/ZaaktypeNotMappedException.php @@ -29,6 +29,8 @@ /** * Pre-send domain error: zaaktype not mapped. + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md */ class ZaaktypeNotMappedException extends StufException { }//end class diff --git a/lib/Service/StufFieldMappingService.php b/lib/Service/StufFieldMappingService.php index d45b70dbd..4ebe7df47 100644 --- a/lib/Service/StufFieldMappingService.php +++ b/lib/Service/StufFieldMappingService.php @@ -36,6 +36,8 @@ * (YYYYMMDD <-> ISO 8601) and enum value transformation. * * @psalm-suppress UnusedClass + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class StufFieldMappingService { /** diff --git a/lib/Service/StufMessageBuilder.php b/lib/Service/StufMessageBuilder.php index 9ebd7e85f..8d97e9ab7 100644 --- a/lib/Service/StufMessageBuilder.php +++ b/lib/Service/StufMessageBuilder.php @@ -54,6 +54,8 @@ * Service for constructing the outbound StUF-ZKN request envelopes. * * @psalm-suppress UnusedClass + * + * @spec openspec/specs/stuf-zkn-outbound/spec.md#requirement-outbound-envelope-construction */ class StufMessageBuilder { /** diff --git a/lib/Service/Subsidie/BeschikkingService.php b/lib/Service/Subsidie/BeschikkingService.php index aa6b0742e..fc742ef40 100644 --- a/lib/Service/Subsidie/BeschikkingService.php +++ b/lib/Service/Subsidie/BeschikkingService.php @@ -75,6 +75,8 @@ public function __construct( * @param DateTimeImmutable $publication The publication date. * * @return DateTimeImmutable The bezwaartermijn end. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function computeBezwaartermijn(DateTimeImmutable $publication): DateTimeImmutable { return $publication->add(new DateInterval('P' . (self::BEZWAARTERMIJN_WEKEN * 7) . 'D')); @@ -88,6 +90,8 @@ public function computeBezwaartermijn(DateTimeImmutable $publication): DateTimeI * @return void * * @throws OCSBadRequestException When validation fails. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function assertDraftValid(array $payload): void { $granted = (float)($payload['grantedAmount'] ?? 0); diff --git a/lib/Service/Subsidie/BewijsstukService.php b/lib/Service/Subsidie/BewijsstukService.php index 992c05986..cd45ec82e 100644 --- a/lib/Service/Subsidie/BewijsstukService.php +++ b/lib/Service/Subsidie/BewijsstukService.php @@ -91,6 +91,8 @@ public function __construct( * @param string $type The bewijsstuk type. * * @return bool True when the combination is on the whitelist. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function isTypeAllowed(string $linkedIn, string $type): bool { $allowed = self::TYPE_WHITELIST[$linkedIn] ?? null; @@ -109,6 +111,8 @@ public function isTypeAllowed(string $linkedIn, string $type): bool { * @param int|null $override Regeling-configured retention, if any. * * @return int The retention years. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function bewaartermijnJaren(string $linkedIn, ?int $override = null): int { if ($override !== null && $override > 0) { @@ -125,6 +129,8 @@ public function bewaartermijnJaren(string $linkedIn, ?int $override = null): int * @param int $jaren The retention years. * * @return DateTimeImmutable The retention end date. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function bewaartermijnEinde(DateTimeImmutable $from, int $jaren): DateTimeImmutable { return $from->add(new DateInterval('P' . max(1, $jaren) . 'Y')); @@ -136,6 +142,8 @@ public function bewaartermijnEinde(DateTimeImmutable $from, int $jaren): DateTim * @param string $contents The raw file contents. * * @return string The lowercase hex digest. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function computeHash(string $contents): string { return hash('sha256', $contents); @@ -148,6 +156,8 @@ public function computeHash(string $contents): string { * @param string $expectedHash The recorded digest. * * @return bool True when the hash matches (constant-time compare). + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function verifyHash(string $contents, string $expectedHash): bool { return hash_equals($expectedHash, $this->computeHash(contents: $contents)); @@ -208,6 +218,8 @@ public function create(array $payload, ?string $contents = null, ?int $regelingR * @return void * * @throws OCSBadRequestException When the document is immutable. + * + * @spec openspec/specs/subsidieverlening-keten/spec.md#requirement-req-sub-007-bewijsstukken-management-with-bewaartermijn */ public function assertMutable(array $bewijsstuk): void { if (($bewijsstuk['immutable'] ?? false) === true) { diff --git a/lib/Service/Subsidie/CofinancieringValidator.php b/lib/Service/Subsidie/CofinancieringValidator.php index 20daa92be..9cd1cc06f 100644 --- a/lib/Service/Subsidie/CofinancieringValidator.php +++ b/lib/Service/Subsidie/CofinancieringValidator.php @@ -50,6 +50,8 @@ class CofinancieringValidator { * @param array> $rows The contribution rows. * * @return float The total in EUR. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function sumBedragen(array $rows): float { $sum = 0.0; @@ -69,6 +71,8 @@ public function sumBedragen(array $rows): float { * @param float $projectTotal The project total. * * @return bool True when the funding sources reconcile to the total. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function reconciles(float $subsidyAmount, array $cofinanciering, float $projectTotal): bool { $total = ($subsidyAmount + $this->sumBedragen(rows: $cofinanciering)); @@ -81,6 +85,8 @@ public function reconciles(float $subsidyAmount, array $cofinanciering, float $p * @param array> $cofinanciering The co-financing rows. * * @return bool True when EU co-financing is present. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function hasEuCofinanciering(array $cofinanciering): bool { foreach ($cofinanciering as $row) { @@ -104,6 +110,8 @@ public function hasEuCofinanciering(array $cofinanciering): bool { * @param float $projectTotal The project total. * * @return array{valid: bool, error: string|null, euCofinanciering: bool} + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function validate(float $subsidyAmount, array $cofinanciering, float $projectTotal): array { if ($projectTotal <= 0.0) { diff --git a/lib/Service/Subsidie/StaatssteunClassifier.php b/lib/Service/Subsidie/StaatssteunClassifier.php index 62e9c51eb..883243b36 100644 --- a/lib/Service/Subsidie/StaatssteunClassifier.php +++ b/lib/Service/Subsidie/StaatssteunClassifier.php @@ -64,6 +64,8 @@ class StaatssteunClassifier { * @param float $eerdereDeMinimis The cumulative prior de-minimis aid in the window. * * @return bool True when the cumulative total stays within the ceiling. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function fitsDeMinimis(float $newAmount, float $eerdereDeMinimis): bool { return ($eerdereDeMinimis + $newAmount) <= self::DE_MINIMIS_PLAFOND; @@ -75,6 +77,8 @@ public function fitsDeMinimis(float $newAmount, float $eerdereDeMinimis): bool { * @param float $eerdereDeMinimis The cumulative prior de-minimis aid in the window. * * @return float The remaining headroom in EUR (never negative). + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function deMinimisHeadroom(float $eerdereDeMinimis): float { return max(0.0, (self::DE_MINIMIS_PLAFOND - $eerdereDeMinimis)); @@ -88,6 +92,8 @@ public function deMinimisHeadroom(float $eerdereDeMinimis): float { * @param float $eerdereDeMinimis The cumulative prior de-minimis aid. * * @return bool True when a state-aid ground must be recorded. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function requiresStaatssteunGrondslag(float $amount, float $eerdereDeMinimis): bool { return $this->fitsDeMinimis(newAmount: $amount, eerdereDeMinimis: $eerdereDeMinimis) === false; @@ -99,6 +105,8 @@ public function requiresStaatssteunGrondslag(float $amount, float $eerdereDeMini * @param string $artikel The AGVV article token. * * @return bool True when supported. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function isAgvvArtikel(string $artikel): bool { return in_array($artikel, self::AGVV_ARTIKELEN, true); @@ -116,6 +124,8 @@ public function isAgvvArtikel(string $artikel): bool { * * @SuppressWarnings(PHPMD.BooleanArgumentFlag) — $isDaeb is a classification * input (the activity either is or is not a DAEB), not a behaviour switch. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function classify(float $amount, float $eerdereDeMinimis, ?string $agvvArtikel = null, bool $isDaeb = false): string { if ($isDaeb === true) { @@ -145,6 +155,8 @@ public function classify(float $amount, float $eerdereDeMinimis, ?string $agvvAr * @param float $amount The granted amount. * * @return array The melding payload for async transmission. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function buildTamMelding(string $beschikkingnummer, string $agvvArtikel, float $amount): array { return [ diff --git a/lib/Service/Subsidie/SubsidieRegisterExporter.php b/lib/Service/Subsidie/SubsidieRegisterExporter.php index a14fa71dd..823445699 100644 --- a/lib/Service/Subsidie/SubsidieRegisterExporter.php +++ b/lib/Service/Subsidie/SubsidieRegisterExporter.php @@ -50,6 +50,8 @@ class SubsidieRegisterExporter { * @param array $request The application record. * * @return string The display name for the public register. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function publicOntvanger(array $request): string { $kvk = (string)($request['applicantKvkRef'] ?? ''); @@ -69,6 +71,8 @@ public function publicOntvanger(array $request): string { * @param array $decision The (latest) decision record. * * @return array The feed entry. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function toFeedEntry(array $request, array $regeling, array $decision): array { $determined = (string)($decision['beschikkingtype'] ?? '') === 'vaststellingsbeschikking'; @@ -100,6 +104,8 @@ public function toFeedEntry(array $request, array $regeling, array $decision): a * @param int $offset Page offset. * * @return array The feed document. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function buildFeed(array $entries, int $limit = 100, int $offset = 0): array { $limit = max(1, $limit); diff --git a/lib/Service/Subsidie/SubsidieService.php b/lib/Service/Subsidie/SubsidieService.php index b378400a9..442090bf7 100644 --- a/lib/Service/Subsidie/SubsidieService.php +++ b/lib/Service/Subsidie/SubsidieService.php @@ -107,6 +107,8 @@ public function __construct( * @param string $to Target status. * * @return bool True when the transition is allowed. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function isTransitionAllowed(string $from, string $to): bool { $allowed = self::TRANSITIONS[$from] ?? null; @@ -124,6 +126,8 @@ public function isTransitionAllowed(string $from, string $to): bool { * @param DateTimeImmutable|null $now Clock injection for tests. * * @return string The formatted beschikkingnummer. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function generateBeschikkingnummer(int $sequence, ?DateTimeImmutable $now = null): string { $now = ($now ?? new DateTimeImmutable()); @@ -139,6 +143,8 @@ public function generateBeschikkingnummer(int $sequence, ?DateTimeImmutable $now * @param int $weken The regeling term in weeks. * * @return DateTimeImmutable The decision deadline. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function computeBeslistermijn(DateTimeImmutable $registration, int $weken): DateTimeImmutable { $weken = max(1, $weken); @@ -153,6 +159,8 @@ public function computeBeslistermijn(DateTimeImmutable $registration, int $weken * @param float $grantedAmount The granted amount. * * @return bool True when the schedule reconciles to the granted amount. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function voorschotSchemaReconciles(array $advanceSchema, float $grantedAmount): bool { $sum = 0.0; @@ -174,6 +182,8 @@ public function voorschotSchemaReconciles(array $advanceSchema, float $grantedAm * @param array $approvedReports Approved tussenrapportage ids. * * @return bool True when the voorschot is releasable. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function isVoorschotReleasable(array $voorschot, array $approvedReports): bool { $voorwaarde = trim((string)($voorschot['voorwaarde'] ?? '')); @@ -197,6 +207,8 @@ public function isVoorschotReleasable(array $voorschot, array $approvedReports): * @param array> $verplichtingen Condition rows. * * @return array> The unmet conditions. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function unmetVerplichtingen(array $verplichtingen): array { $unmet = []; @@ -302,6 +314,8 @@ public function transitionAanvraag(string $id, string $toStatus): array { * @return array> The aanvragen. * * @throws OCSBadRequestException When OpenRegister is unavailable/unconfigured. + * + * @spec openspec/specs/subsidieverlening-keten/spec.md#requirement-req-sub-002-awb-termijn-binding-for-each-phase */ public function listAanvragen(array $filters = []): array { [$objectService, $register, $schema] = $this->resolve(schemaConfigKey: 'subsidie_aanvraag_schema'); @@ -322,6 +336,8 @@ public function listAanvragen(array $filters = []): array { * @param string $bsn The raw BSN. * * @return string The masked reference. + * + * @spec openspec/specs/subsidieverlening-keten/spec.md#requirement-req-sub-002-awb-termijn-binding-for-each-phase */ public function maskBsn(string $bsn): string { $digits = preg_replace('/\D/', '', $bsn); diff --git a/lib/Service/Subsidie/TerugvorderingService.php b/lib/Service/Subsidie/TerugvorderingService.php index 0e9a310a5..e4fc48dda 100644 --- a/lib/Service/Subsidie/TerugvorderingService.php +++ b/lib/Service/Subsidie/TerugvorderingService.php @@ -81,6 +81,8 @@ public function __construct( * @param DateTimeImmutable $publication The publication date. * * @return DateTimeImmutable The bezwaartermijn end. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function computeBezwaartermijn(DateTimeImmutable $publication): DateTimeImmutable { return $publication->add(new DateInterval('P' . (self::BEZWAARTERMIJN_WEKEN * 7) . 'D')); @@ -92,6 +94,8 @@ public function computeBezwaartermijn(DateTimeImmutable $publication): DateTimeI * @param DateTimeImmutable $publication The publication date. * * @return DateTimeImmutable The betaaltermijn end. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function computeBetaaltermijn(DateTimeImmutable $publication): DateTimeImmutable { return $publication->add(new DateInterval('P' . (self::BETAALTERMIJN_WEKEN * 7) . 'D')); @@ -108,6 +112,8 @@ public function computeBetaaltermijn(DateTimeImmutable $publication): DateTimeIm * @param float|null $yearFaction Annual rate fraction; defaults to the wettelijke rente. * * @return float The accrued rente in EUR. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function computeInvorderingsrente( float $openstaandBedrag, @@ -133,6 +139,8 @@ public function computeInvorderingsrente( * @param float $paid The cumulative amount paid. * * @return string The resulting status. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function statusAfterPayment(float $amount, float $paid): string { if ($paid <= 0.0) { diff --git a/lib/Service/Subsidie/TussenrapportageService.php b/lib/Service/Subsidie/TussenrapportageService.php index 6525cb838..c2d83db4e 100644 --- a/lib/Service/Subsidie/TussenrapportageService.php +++ b/lib/Service/Subsidie/TussenrapportageService.php @@ -91,6 +91,8 @@ public function __construct( * @param int $termWeken The regeling assessment term. * * @return DateTimeImmutable The assessment deadline. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function computeBeoordelingstermijn(DateTimeImmutable $periodEnd, int $termWeken): DateTimeImmutable { $termWeken = max(1, $termWeken); @@ -106,6 +108,8 @@ public function computeBeoordelingstermijn(DateTimeImmutable $periodEnd, int $te * @param int $year The calendar year. * * @return array The reporting periods. + * + * @spec openspec/changes/subsidieverlening-keten/specs.md */ public function periodsForFrequentie(string $frequency, int $year): array { if ($frequency === 'annually') { diff --git a/lib/Service/Support/SeedSummary.php b/lib/Service/Support/SeedSummary.php index dbaab03ba..45e15b1ca 100644 --- a/lib/Service/Support/SeedSummary.php +++ b/lib/Service/Support/SeedSummary.php @@ -61,6 +61,8 @@ class SeedSummary { * @param array $result The per-case-type counts. * * @return void + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function addCaseTypeResult(array $result): void { foreach (array_keys($this->created) as $kind) { @@ -72,6 +74,8 @@ public function addCaseTypeResult(array $result): void { * Record one refused write. * * @return void + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function recordFailure(): void { $this->failed++; @@ -81,6 +85,8 @@ public function recordFailure(): void { * Whether every write the run attempted landed. * * @return bool True when nothing was refused. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function isClean(): bool { return $this->failed === 0; @@ -93,6 +99,8 @@ public function isClean(): bool { * `caseTypes: 0` as "nothing left to do". * * @return array The summary. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function toArray(): array { $summary = ['success' => $this->isClean()] + $this->created + ['failed' => $this->failed]; diff --git a/lib/Service/TemplateLibraryService.php b/lib/Service/TemplateLibraryService.php index ab4bcdbc2..b8c393cf4 100644 --- a/lib/Service/TemplateLibraryService.php +++ b/lib/Service/TemplateLibraryService.php @@ -33,6 +33,8 @@ /** * Service for loading and activating zaaktype templates. + * + * @spec openspec/specs/template-library/spec.md */ class TemplateLibraryService { diff --git a/lib/Service/TenantAuditTrailService.php b/lib/Service/TenantAuditTrailService.php index 887a66a73..43467366f 100644 --- a/lib/Service/TenantAuditTrailService.php +++ b/lib/Service/TenantAuditTrailService.php @@ -47,6 +47,8 @@ /** * Tenant-stamped audit-trail emitter. + * + * @spec openspec/specs/tenant-compliance/spec.md */ class TenantAuditTrailService { /** @@ -225,6 +227,8 @@ private function resolveTenantEntity(string $tenantId): mixed { * @param array $bio Raw BIO context. * * @return array + * + * @spec openspec/specs/tenant-compliance/spec.md */ public function sanitiseBio(array $bio): array { $out = []; diff --git a/lib/Service/TenantAuthenticationService.php b/lib/Service/TenantAuthenticationService.php index 53ab67238..e7b3e4a26 100644 --- a/lib/Service/TenantAuthenticationService.php +++ b/lib/Service/TenantAuthenticationService.php @@ -36,6 +36,8 @@ /** * Mandate-matrix authorisation guard for tenant actions. + * + * @spec openspec/specs/multi-tenancy/spec.md#req-005-tenant-membership-and-status-helpers-for-middleware */ class TenantAuthenticationService { /** @@ -119,6 +121,8 @@ public function validateMandateMatrix(string $tenantId, string $userId, string $ * @param string $action Requested action. * * @return bool + * + * @spec openspec/specs/tenant-mandate/spec.md#requirement-mandate-matrix-validation-per-action-req-002-d-req-006-d */ public function isAllowed(array $matrix, string $role, string $action): bool { $roleEntry = ($matrix[$role] ?? null); @@ -152,6 +156,8 @@ public function isAllowed(array $matrix, string $role, string $action): bool { * @param string $tenantId Tenant UUID. * * @return array>|null Active matrix or null. + * + * @spec openspec/specs/tenant-mandate/spec.md#requirement-mandate-matrix-validation-per-action-req-002-d-req-006-d */ public function loadActiveMatrix(string $tenantId): ?array { $objectService = $this->getObjectService(); diff --git a/lib/Service/TenantBillingService.php b/lib/Service/TenantBillingService.php index 8c702a6a7..074edf67c 100644 --- a/lib/Service/TenantBillingService.php +++ b/lib/Service/TenantBillingService.php @@ -34,6 +34,8 @@ /** * Billing event service. + * + * @spec openspec/specs/tenant-billing/spec.md */ class TenantBillingService { /** @@ -215,6 +217,8 @@ public function emitEvent(string $tenantId, string $eventType, float $quantity = * @return array{eventCount:int, totalAmount:float, byType:array} * * @throws InvalidArgumentException When month is malformed. + * + * @spec openspec/specs/tenant-billing/spec.md#requirement-billing-event-emission-on-case-lifecycle-req-007-a */ public function getMonthBilling(string $tenantId, string $month): array { if (preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])$/', $month) !== 1) { @@ -231,6 +235,8 @@ public function getMonthBilling(string $tenantId, string $month): array { * @param array> $events Event rows. * * @return array{eventCount:int, totalAmount:float, byType:array} + * + * @spec openspec/specs/tenant-billing/spec.md#requirement-billing-event-emission-on-case-lifecycle-req-007-a */ public function aggregate(array $events): array { $byType = []; @@ -306,6 +312,8 @@ public function markExported(array $events, string $invoiceRef): int { * @param string $month YYYY-MM. * * @return array> + * + * @spec openspec/specs/tenant-billing/spec.md#requirement-daily-billing-export-to-shillinq-req-007-b */ public function fetchEventsForMonth(string $tenantId, string $month): array { $objectService = $this->getObjectService(); diff --git a/lib/Service/TenantConfigurationService.php b/lib/Service/TenantConfigurationService.php index a88b8f93d..a87ec84d5 100644 --- a/lib/Service/TenantConfigurationService.php +++ b/lib/Service/TenantConfigurationService.php @@ -37,6 +37,8 @@ * Branding validation is owned by {@see TenantBrandingSanitiser}; this service * owns configuration storage — read, merge, persist — plus locale and feature * flags. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-08-configuration-branding/tasks.md */ class TenantConfigurationService { /** @@ -103,6 +105,8 @@ public function __construct( * @param string $tenantId Tenant UUID. * * @return array|null + * + * @spec openspec/changes/tenant-zaaksysteem-saas-08-configuration-branding/tasks.md */ public function getConfig(string $tenantId): ?array { $objectService = $this->getObjectService(); @@ -161,6 +165,8 @@ public function getConfig(string $tenantId): ?array { * @param bool $enabled True to add, false to remove. * * @return array + * + * @spec openspec/changes/tenant-zaaksysteem-saas-08-configuration-branding/tasks.md */ public function setFeatureFlag(string $tenantId, string $flag, bool $enabled): array { $current = $this->getConfig(tenantId: $tenantId) ?? ['tenantRef' => $tenantId, 'features' => []]; @@ -228,6 +234,8 @@ public function sanitiseBranding(array $branding): array { * @param string $css Raw CSS. * * @return string Sanitised CSS. + * + * @spec openspec/specs/security-hardening/spec.md */ public function sanitiseCustomCss(string $css): string { return $this->sanitiser->sanitiseCustomCss(css: $css); @@ -242,6 +250,8 @@ public function sanitiseCustomCss(string $css): string { * @return void * * @throws InvalidArgumentException + * + * @spec openspec/specs/security-hardening/spec.md */ public function validateLogoUpload(string $mimeType, int $bytes): void { $this->sanitiser->validateLogoUpload(mimeType: $mimeType, bytes: $bytes); @@ -253,6 +263,8 @@ public function validateLogoUpload(string $mimeType, int $bytes): void { * @param string $val 6-digit hex (with leading #). * * @return bool + * + * @spec openspec/specs/security-hardening/spec.md */ public function isHexColor(string $val): bool { return $this->sanitiser->isHexColor(val: $val); diff --git a/lib/Service/TenantContext.php b/lib/Service/TenantContext.php index 3b3747f01..b70e6e9fe 100644 --- a/lib/Service/TenantContext.php +++ b/lib/Service/TenantContext.php @@ -35,6 +35,8 @@ * Implemented as a regular service whose lifetime is bound to the request * scope by the NC DI container (request-scoped via `IRequest` is sufficient * — every HTTP request gets a fresh container child). + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ class TenantContext { @@ -73,6 +75,8 @@ class TenantContext { * @param string $schemaName Tenant schema name. * * @return void + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function bind(array $tenant, string $schemaName): void { $this->tenant = $tenant; @@ -85,6 +89,8 @@ public function bind(array $tenant, string $schemaName): void { * Whether a tenant has been bound to the request. * * @return bool + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function isBound(): bool { return $this->tenant !== null; @@ -96,6 +102,8 @@ public function isBound(): bool { * @return array * * @throws RuntimeException When no tenant is bound. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function getTenant(): array { $this->assertBound(); @@ -108,6 +116,8 @@ public function getTenant(): array { * @return string * * @throws RuntimeException When no tenant is bound. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function getTenantId(): string { $this->assertBound(); @@ -120,6 +130,8 @@ public function getTenantId(): string { * @return string * * @throws RuntimeException When no tenant is bound. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function getSlug(): string { $this->assertBound(); @@ -132,6 +144,8 @@ public function getSlug(): string { * @return string * * @throws RuntimeException When no tenant is bound. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function getSchemaName(): string { $this->assertBound(); @@ -142,6 +156,8 @@ public function getSchemaName(): string { * Reset the context. Used in tests + at the end of each request. * * @return void + * + * @spec openspec/changes/tenant-zaaksysteem-saas-04-tenant-context-isolation/tasks.md */ public function reset(): void { $this->tenant = null; diff --git a/lib/Service/TenantJwtService.php b/lib/Service/TenantJwtService.php index 5998ad914..9fb488a8f 100644 --- a/lib/Service/TenantJwtService.php +++ b/lib/Service/TenantJwtService.php @@ -37,6 +37,8 @@ /** * HMAC-based JWT validation with first-class tenant claim support. Minting * lives with the external broker that issues the tokens — see the note below. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-05-auth-jwt-tenant-claim/tasks.md */ class TenantJwtService { /** @@ -98,6 +100,8 @@ public function __construct( * * @throws RuntimeException When the token is malformed, the signature * does not match, or the token is expired. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-05-auth-jwt-tenant-claim/tasks.md */ public function validate(string $token): array { $parts = explode('.', $token); @@ -132,6 +136,8 @@ public function validate(string $token): array { * @return string * * @throws RuntimeException When the claim is missing. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-05-auth-jwt-tenant-claim/tasks.md */ public function extractTenantId(array $claims): string { $tid = (string)($claims['tenant_id'] ?? ''); diff --git a/lib/Service/TenantLifecycleControlService.php b/lib/Service/TenantLifecycleControlService.php index b6d585185..27f3dddcc 100644 --- a/lib/Service/TenantLifecycleControlService.php +++ b/lib/Service/TenantLifecycleControlService.php @@ -31,6 +31,8 @@ /** * Suspension / reactivation / termination orchestration. + * + * @spec openspec/specs/tenant-lifecycle/spec.md#requirement-tenant-suspension-and-reactivation-req-008-a */ class TenantLifecycleControlService { /** @@ -139,6 +141,8 @@ public function terminate(string $tenantId, string $reason, int $retentionYears * @param string $tenantId Tenant UUID. * * @return int + * + * @spec openspec/specs/tenant-lifecycle/spec.md#requirement-tenant-termination-and-data-archival-req-008-b */ public function countUnsettledEvents(string $tenantId): int { $events = $this->billingService->fetchEventsForMonth( diff --git a/lib/Service/TenantOnboardingService.php b/lib/Service/TenantOnboardingService.php index e5f3a584c..f6373667d 100644 --- a/lib/Service/TenantOnboardingService.php +++ b/lib/Service/TenantOnboardingService.php @@ -34,6 +34,8 @@ /** * Onboarding workflow service. + * + * @spec openspec/specs/tenant-onboarding/spec.md#requirement-onboarding-checklist-and-progress-dashboard-req-003-a-req-003-d */ class TenantOnboardingService { /** @@ -244,6 +246,8 @@ public function markStepComplete(string $tenantId, string $step, string $complet * @param string $tenantId Tenant UUID. * * @return array{ready: bool, missing: array} + * + * @spec openspec/specs/tenant-onboarding/spec.md#requirement-onboarding-checklist-and-progress-dashboard-req-003-a-req-003-d */ public function validateGoLive(string $tenantId): array { $objectService = $this->getObjectService(); diff --git a/lib/Service/TenantProvisioningService.php b/lib/Service/TenantProvisioningService.php index 4cd259cc7..b29d14602 100644 --- a/lib/Service/TenantProvisioningService.php +++ b/lib/Service/TenantProvisioningService.php @@ -40,6 +40,8 @@ * * Returns the provisioning result (schemaName + steps performed) or throws * after rolling back any partial work. + * + * @spec openspec/specs/tenant-provisioning/spec.md#requirement-schema-per-tenant-provisioning-req-001-b */ class TenantProvisioningService { /** @@ -167,6 +169,8 @@ public function provision(string $tenantId): array { * @return string Schema name (≤63 chars, lowercase, identifier-safe). * * @throws InvalidArgumentException When uuid or slug is empty. + * + * @spec openspec/specs/tenant-provisioning/spec.md#requirement-schema-per-tenant-provisioning-req-001-b */ public function buildSchemaName(string $uuid, string $slug): string { if ($uuid === '' || $slug === '') { @@ -223,6 +227,8 @@ public function rollback(string $schemaName, array $steps): void { * Return the default roles seeded per tenant. * * @return array + * + * @spec openspec/specs/tenant-provisioning/spec.md#requirement-schema-per-tenant-provisioning-req-001-b */ public function getDefaultRoles(): array { return self::DEFAULT_ROLES; diff --git a/lib/Service/TenantQuotaService.php b/lib/Service/TenantQuotaService.php index 67601888e..9cf8c5a61 100644 --- a/lib/Service/TenantQuotaService.php +++ b/lib/Service/TenantQuotaService.php @@ -36,6 +36,8 @@ /** * Quota service. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-09-quotas-enforcement/tasks.md */ class TenantQuotaService { /** @@ -143,6 +145,8 @@ public function initialize(string $tenantId, string $tier): array { * @param string $quotaType Type. * * @return array|null + * + * @spec openspec/specs/tenant-quotas/spec.md#requirement-tier-based-quota-initialisation-req-005-a-req-005-e */ public function getQuota(string $tenantId, string $quotaType): ?array { $objectService = $this->getObjectService(); @@ -185,6 +189,8 @@ public function getQuota(string $tenantId, string $quotaType): ?array { * @param int $increment Requested increment. * * @return array{decision:string, soft:bool, reason:string} + * + * @spec openspec/specs/tenant-quotas/spec.md#requirement-tier-based-quota-initialisation-req-005-a-req-005-e */ public function decide(array $quota, int $increment = 1): array { $limit = $quota['limit'] ?? null; @@ -231,6 +237,8 @@ public function decide(array $quota, int $increment = 1): array { * @param int $amount Amount to consume. * * @return array{decision:string, soft:bool, reason:string, currentUsage?:int} + * + * @spec openspec/specs/tenant-quotas/spec.md#requirement-tier-based-quota-initialisation-req-005-a-req-005-e */ public function consume(string $tenantId, string $quotaType, int $amount = 1): array { $quota = $this->getQuota(tenantId: $tenantId, quotaType: $quotaType); @@ -257,6 +265,8 @@ public function consume(string $tenantId, string $quotaType, int $amount = 1): a * @param int|null $limit New limit (null = unlimited). * * @return array|null Persisted row. + * + * @spec openspec/specs/tenant-quotas/spec.md#requirement-tier-based-quota-initialisation-req-005-a-req-005-e */ public function setLimit(string $tenantId, string $quotaType, ?int $limit): ?array { $quota = $this->getQuota(tenantId: $tenantId, quotaType: $quotaType); @@ -275,6 +285,8 @@ public function setLimit(string $tenantId, string $quotaType, ?int $limit): ?arr * @param array $quota Quota row. * * @return array Updated row. + * + * @spec openspec/specs/tenant-quotas/spec.md#requirement-tier-based-quota-initialisation-req-005-a-req-005-e */ public function resetIfDue(array $quota): array { $resetAt = strtotime((string)($quota['resetAt'] ?? '')); @@ -295,6 +307,8 @@ public function resetIfDue(array $quota): array { * @param string $quotaType Type. * * @return string ISO-8601 timestamp. + * + * @spec openspec/specs/tenant-quotas/spec.md#requirement-tier-based-quota-initialisation-req-005-a-req-005-e */ public function nextResetAt(string $quotaType): string { if ($quotaType === 'api_calls_per_hour') { diff --git a/lib/Service/TenantSaasService.php b/lib/Service/TenantSaasService.php index 2f008db57..adcbc236d 100644 --- a/lib/Service/TenantSaasService.php +++ b/lib/Service/TenantSaasService.php @@ -48,6 +48,8 @@ * All persistence goes through OpenRegister's ObjectService — no bespoke * Doctrine entity. The state machine validates that only the documented * transitions are written. + * + * @spec openspec/specs/tenant-crud-lifecycle/spec.md */ class TenantSaasService { use SearchesObjects; @@ -323,6 +325,8 @@ public function delete(string $tenantId): bool { * @param string $name Display name. * * @return string Slug. + * + * @spec openspec/specs/tenant-crud-lifecycle/spec.md#requirement-tenant-lifecycle-state-machine-req-001-a-lifecycle */ public function slugify(string $name): string { $lower = mb_strtolower(trim($name), 'UTF-8'); @@ -348,6 +352,8 @@ public function slugify(string $name): string { * @return void * * @throws InvalidArgumentException When the transition is illegal. + * + * @spec openspec/specs/tenant-crud-lifecycle/spec.md#requirement-tenant-lifecycle-state-machine-req-001-a-lifecycle */ public function assertLegalTransition(string $current, string $target): void { if (array_key_exists($current, self::LIFECYCLE_TRANSITIONS) === false) { @@ -369,6 +375,8 @@ public function assertLegalTransition(string $current, string $target): void { * Return the full lifecycle transition graph (for tests / introspection). * * @return array> + * + * @spec openspec/specs/tenant-crud-lifecycle/spec.md#requirement-tenant-lifecycle-state-machine-req-001-a-lifecycle */ public function getLifecycleGraph(): array { return self::LIFECYCLE_TRANSITIONS; diff --git a/lib/Service/TenantSchemaProvisioner.php b/lib/Service/TenantSchemaProvisioner.php index 2c630932d..c0ac0c7da 100644 --- a/lib/Service/TenantSchemaProvisioner.php +++ b/lib/Service/TenantSchemaProvisioner.php @@ -41,6 +41,8 @@ * those stay in `public`). Shared tables are the SaaS-control plane: * `tenant`, `tenantConfiguration`, `tenantQuota`, `tenantUser`, * `tenantMandate`, `tenantBillingEvent`, `tenantOnboardingTask`. + * + * @spec openspec/specs/tenant-provisioning/spec.md#requirement-schema-per-tenant-provisioning-req-001-b */ class TenantSchemaProvisioner { /** @@ -115,6 +117,8 @@ public function __construct( * * @throws InvalidArgumentException When the name is invalid. * @throws RuntimeException When the DDL fails. + * + * @spec openspec/changes/tenant-zaaksysteem-saas-03-schema-provisioning/tasks.md */ public function createSchema(string $name): void { $this->assertSafeIdentifier(name: $name); @@ -189,6 +193,8 @@ public function cloneApplicationTables(string $schemaName): array { * @return void * * @throws RuntimeException On DDL failure. + * + * @spec openspec/specs/tenant-provisioning/spec.md#requirement-schema-per-tenant-provisioning-req-001-b */ public function dropSchema(string $name): void { $this->assertSafeIdentifier(name: $name); @@ -235,6 +241,8 @@ public function schemaExists(string $name): bool { * @return void * * @throws InvalidArgumentException When invalid. + * + * @spec openspec/specs/tenant-provisioning/spec.md#requirement-schema-per-tenant-provisioning-req-001-b */ public function assertSafeIdentifier(string $name): void { if ($name === '' || strlen($name) > self::PG_IDENTIFIER_MAX_LENGTH) { diff --git a/lib/Service/TenantSeedService.php b/lib/Service/TenantSeedService.php index 4ef67a0ad..cc1b79816 100644 --- a/lib/Service/TenantSeedService.php +++ b/lib/Service/TenantSeedService.php @@ -36,6 +36,8 @@ /** * Seed standard templates (zaaktypen, mandaat-matrix, roles) into a tenant. + * + * @spec openspec/specs/tenant-schemas/spec.md#requirement-seed-tier-templates-and-default-tenant-onboarding-template-req-001-b-seed */ class TenantSeedService { /** diff --git a/lib/Service/TenantService.php b/lib/Service/TenantService.php index d810f66c6..1b7a3f3cd 100644 --- a/lib/Service/TenantService.php +++ b/lib/Service/TenantService.php @@ -48,6 +48,8 @@ * `Organisation.groups` array carries the NC group IDs used by dossiq for * tenant routing; `Organisation.status` carries the lifecycle state enforced * by `TenantMiddleware`. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class TenantService { /** @@ -234,6 +236,8 @@ public function getResourceUsage(string $tenantId): array { * @param string $userId The Nextcloud user ID. * * @return bool True when the user is in the NC admin group. + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function isPlatformAdmin(string $userId): bool { return $this->groupManager->isAdmin($userId); diff --git a/lib/Service/TenantSessionService.php b/lib/Service/TenantSessionService.php index 14f783a06..8f2f2f6fd 100644 --- a/lib/Service/TenantSessionService.php +++ b/lib/Service/TenantSessionService.php @@ -41,6 +41,8 @@ * * So the session decides, a switch is an explicit act, and membership is * verified at the moment of switching rather than trusted per request. + * + * @spec openspec/specs/multi-tenancy/spec.md#req-002-user-to-tenant-resolution-via-or-organisation-with-nc-group-fallback */ class TenantSessionService { /** diff --git a/lib/Service/TenantWelcomeMailer.php b/lib/Service/TenantWelcomeMailer.php index 698530afa..57ee8bb68 100644 --- a/lib/Service/TenantWelcomeMailer.php +++ b/lib/Service/TenantWelcomeMailer.php @@ -32,6 +32,8 @@ /** * Welcome-mail dispatch for newly provisioned tenants. + * + * @spec openspec/specs/tenant-onboarding/spec.md#requirement-onboarding-checklist-and-progress-dashboard-req-003-a-req-003-d */ class TenantWelcomeMailer { /** @@ -87,6 +89,8 @@ public function sendWelcomeEmail(array $tenant): bool { * @param array $tenant Tenant row. * * @return string|null + * + * @spec openspec/specs/tenant-onboarding/spec.md#requirement-onboarding-checklist-and-progress-dashboard-req-003-a-req-003-d */ public function resolveAdminEmail(array $tenant): ?string { $candidates = [ diff --git a/lib/Service/TermijnNotificationService.php b/lib/Service/TermijnNotificationService.php index 435ffe91f..81a9e59db 100644 --- a/lib/Service/TermijnNotificationService.php +++ b/lib/Service/TermijnNotificationService.php @@ -37,6 +37,8 @@ /** * Burger notification template renderer + dispatcher. + * + * @spec openspec/changes/termijnbewaking-dwangsom-engine-08-burger-notifications/tasks.md */ class TermijnNotificationService { public const TEMPLATES = [ diff --git a/lib/Service/TermijnTimerService.php b/lib/Service/TermijnTimerService.php index 99869dfd6..46efdeabd 100644 --- a/lib/Service/TermijnTimerService.php +++ b/lib/Service/TermijnTimerService.php @@ -41,6 +41,8 @@ /** * Arms, suspends, resumes, extends and cancels engine timers for AWB terms. + * + * @spec openspec/changes/termijnbewaking-op-engine-timers/tasks.md */ class TermijnTimerService { /** diff --git a/lib/Service/TranscriptionService.php b/lib/Service/TranscriptionService.php index dffb628b2..4cee53555 100644 --- a/lib/Service/TranscriptionService.php +++ b/lib/Service/TranscriptionService.php @@ -41,6 +41,8 @@ /** * Transcription orchestrator for voice-memo FieldEvidence records. + * + * @spec openspec/changes/mobiel-inspectie-offline/tasks.md#Task-9 */ class TranscriptionService { /** diff --git a/lib/Service/Transitions/ActionHandlerRegistry.php b/lib/Service/Transitions/ActionHandlerRegistry.php index 0cdf18441..126769486 100644 --- a/lib/Service/Transitions/ActionHandlerRegistry.php +++ b/lib/Service/Transitions/ActionHandlerRegistry.php @@ -96,6 +96,8 @@ public function registerHandler(string $type, ActionHandlerInterface $handler): * @param string $type Action type * * @return ActionHandlerInterface|null + * + * @spec openspec/specs/status-transition-engine/spec.md */ public function getHandler(string $type): ?ActionHandlerInterface { return ($this->handlers[$type] ?? null); @@ -105,6 +107,8 @@ public function getHandler(string $type): ?ActionHandlerInterface { * Get all registered action types. * * @return array + * + * @spec openspec/specs/status-transition-engine/spec.md */ public function getRegisteredTypes(): array { return array_keys($this->handlers); diff --git a/lib/Service/Transitions/GuardFailedException.php b/lib/Service/Transitions/GuardFailedException.php index 180e33476..06002783a 100644 --- a/lib/Service/Transitions/GuardFailedException.php +++ b/lib/Service/Transitions/GuardFailedException.php @@ -57,6 +57,8 @@ public function __construct(array $failedGuards, string $message = 'guard_failed * Get the failed guard snapshots. * * @return array> + * + * @spec openspec/changes/status-transition-engine/tasks.md#T10 */ public function getFailedGuards(): array { return $this->failedGuards; diff --git a/lib/Service/ZaakdossierService.php b/lib/Service/ZaakdossierService.php index 7a7dcf47c..066f34a8e 100644 --- a/lib/Service/ZaakdossierService.php +++ b/lib/Service/ZaakdossierService.php @@ -45,6 +45,8 @@ * The per-document status state machine is owned by * {@see InformatieobjectStatusLifecycle}; this service orchestrates the * dossier around it. + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T02 */ class ZaakdossierService { use SearchesObjects; diff --git a/lib/Service/ZgwAuthValidationException.php b/lib/Service/ZgwAuthValidationException.php index 924c60adb..9b0d99c55 100644 --- a/lib/Service/ZgwAuthValidationException.php +++ b/lib/Service/ZgwAuthValidationException.php @@ -27,6 +27,8 @@ /** * Exception for ZGW JWT validation failures. + * + * @spec openspec/specs/zgw-autorisaties-api/spec.md */ class ZgwAuthValidationException extends \Exception { }//end class diff --git a/lib/Service/ZgwBrcRulesService.php b/lib/Service/ZgwBrcRulesService.php index 23136ad4d..c00f3d29b 100644 --- a/lib/Service/ZgwBrcRulesService.php +++ b/lib/Service/ZgwBrcRulesService.php @@ -73,6 +73,8 @@ * @psalm-suppress UnusedClass * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZgwBrcRulesService extends ZgwRulesBase { /** diff --git a/lib/Service/ZgwDrcRulesService.php b/lib/Service/ZgwDrcRulesService.php index 13e7607ea..e01809d22 100644 --- a/lib/Service/ZgwDrcRulesService.php +++ b/lib/Service/ZgwDrcRulesService.php @@ -70,6 +70,8 @@ * @psalm-suppress UnusedClass * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZgwDrcRulesService extends ZgwRulesBase { /** diff --git a/lib/Service/ZgwMappingService.php b/lib/Service/ZgwMappingService.php index 6cc41603a..ce2c71992 100644 --- a/lib/Service/ZgwMappingService.php +++ b/lib/Service/ZgwMappingService.php @@ -36,6 +36,8 @@ * `zgw_mapping_zaak`, `zgw_mapping_zaaktype`, etc. * * @SuppressWarnings(PHPMD.ExcessiveClassLength) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZgwMappingService { /** @@ -187,6 +189,8 @@ public function deleteMapping(string $resourceKey): void { * Get all known ZGW resource keys. * * @return string[] + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function getResourceKeys(): array { return self::RESOURCE_KEYS; @@ -198,6 +202,8 @@ public function getResourceKeys(): array { * @param string $resourceKey The ZGW resource key * * @return bool + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ public function hasMapping(string $resourceKey): bool { return $this->getMapping(resourceKey: $resourceKey) !== null; diff --git a/lib/Service/ZgwPaginationHelper.php b/lib/Service/ZgwPaginationHelper.php index a0edc4954..4af75509e 100644 --- a/lib/Service/ZgwPaginationHelper.php +++ b/lib/Service/ZgwPaginationHelper.php @@ -33,6 +33,8 @@ * @package OCA\Dossiq\Service * * @psalm-suppress UnusedClass + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ class ZgwPaginationHelper { /** diff --git a/lib/Service/ZgwService.php b/lib/Service/ZgwService.php index 5890400b4..4a7048b4a 100644 --- a/lib/Service/ZgwService.php +++ b/lib/Service/ZgwService.php @@ -45,6 +45,8 @@ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.TooManyPublicMethods) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZgwService { /** @@ -184,6 +186,8 @@ public function __construct( * Get the OpenRegister ObjectService. * * @return object|null + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function getObjectService(): ?object { return $this->objectService; @@ -193,6 +197,8 @@ public function getObjectService(): ?object { * Get the OpenRegister ConsumerMapper. * * @return object|null + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function getConsumerMapper(): ?object { return $this->consumerMapper; @@ -202,6 +208,8 @@ public function getConsumerMapper(): ?object { * Get the ZGW mapping service. * * @return ZgwMappingService + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function getZgwMappingService(): ZgwMappingService { return $this->zgwMappingService; @@ -211,6 +219,8 @@ public function getZgwMappingService(): ZgwMappingService { * Get the pagination helper. * * @return ZgwPaginationHelper + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function getPaginationHelper(): ZgwPaginationHelper { return $this->paginationHelper; @@ -220,6 +230,8 @@ public function getPaginationHelper(): ZgwPaginationHelper { * Get the document service. * * @return ZgwDocumentService + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function getDocumentService(): ZgwDocumentService { return $this->documentService; @@ -229,6 +241,8 @@ public function getDocumentService(): ZgwDocumentService { * Get the business rules service. * * @return ZgwBusinessRulesService + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function getBusinessRulesService(): ZgwBusinessRulesService { return $this->businessRulesService; @@ -238,6 +252,8 @@ public function getBusinessRulesService(): ZgwBusinessRulesService { * Get the logger. * * @return LoggerInterface + * + * @spec openspec/specs/zgw-api-mapping/spec.md */ public function getLogger(): LoggerInterface { return $this->logger; diff --git a/lib/Service/ZgwZrcRulesService.php b/lib/Service/ZgwZrcRulesService.php index 7bffa895d..4b70ab922 100644 --- a/lib/Service/ZgwZrcRulesService.php +++ b/lib/Service/ZgwZrcRulesService.php @@ -61,6 +61,8 @@ * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) * @SuppressWarnings(PHPMD.ExcessiveClassLength) + * + * @spec openspec/specs/status-transition-engine/spec.md */ class ZgwZrcRulesService extends ZgwRulesBase { /** diff --git a/lib/Service/ZgwZtcRulesService.php b/lib/Service/ZgwZtcRulesService.php index b6c201322..997c0220e 100644 --- a/lib/Service/ZgwZtcRulesService.php +++ b/lib/Service/ZgwZtcRulesService.php @@ -61,6 +61,8 @@ * @psalm-suppress UnusedClass * * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + * + * @spec openspec/changes/retrofit-2026-05-24-case-management/tasks.md */ class ZgwZtcRulesService extends ZgwRulesBase { /** diff --git a/lib/Service/ZipManifestBuilder.php b/lib/Service/ZipManifestBuilder.php index b6d47c30d..4def0e681 100644 --- a/lib/Service/ZipManifestBuilder.php +++ b/lib/Service/ZipManifestBuilder.php @@ -38,6 +38,8 @@ /** * Builds a manifest-bearing, type-foldered ZIP export of a dossier. + * + * @spec openspec/changes/document-zaakdossier/tasks.md#T04 */ class ZipManifestBuilder { /** diff --git a/lib/Settings/AdminSettings.php b/lib/Settings/AdminSettings.php index 94f6e80ab..35fb7c607 100644 --- a/lib/Settings/AdminSettings.php +++ b/lib/Settings/AdminSettings.php @@ -37,6 +37,8 @@ * Implements IDelegatedSettings so the form can be guarded by * #[AuthorizedAdminSetting(settings: AdminSettings::class)] on the * controllers that mutate Dossiq configuration. + * + * @spec openspec/specs/admin-settings/spec.md */ class AdminSettings implements IDelegatedSettings { /** @@ -64,6 +66,8 @@ public function __construct( * the same silent failure as procest#794's dead write routes. * * @return TemplateResponse + * + * @spec openspec/specs/admin-settings/spec.md */ public function getForm(): TemplateResponse { $version = $this->appManager->getAppVersion(appId: Application::APP_ID); @@ -142,6 +146,8 @@ private function mandateSettings(): array { * Get the section ID this settings page belongs to. * * @return string + * + * @spec openspec/specs/admin-settings/spec.md */ public function getSection(): string { return 'dossiq'; @@ -151,6 +157,8 @@ public function getSection(): string { * Get the priority for ordering within the section. * * @return int + * + * @spec openspec/specs/admin-settings/spec.md */ public function getPriority(): int { return 10; @@ -160,6 +168,8 @@ public function getPriority(): int { * Human-readable name of the delegated settings section. * * @return string|null The section name, or null to use the section default. + * + * @spec openspec/specs/admin-settings/spec.md */ public function getName(): ?string { return null; @@ -173,6 +183,8 @@ public function getName(): ?string { * the attribute still scopes the endpoint to full admins. * * @return array Map of appId to allowed config keys. + * + * @spec openspec/specs/admin-settings/spec.md */ public function getAuthorizedAppConfig(): array { return []; diff --git a/lib/Settings/EmailSettings.php b/lib/Settings/EmailSettings.php index 944ef8168..14e426b35 100644 --- a/lib/Settings/EmailSettings.php +++ b/lib/Settings/EmailSettings.php @@ -102,6 +102,8 @@ public function getForm(): TemplateResponse { * Get the section ID this settings page belongs to. * * @return string + * + * @spec openspec/specs/case-email-integration/spec.md */ public function getSection(): string { return 'dossiq'; @@ -114,6 +116,8 @@ public function getSection(): string { * this entry orders after it within the same section. * * @return int + * + * @spec openspec/specs/case-email-integration/spec.md */ public function getPriority(): int { return 60; @@ -123,6 +127,8 @@ public function getPriority(): int { * Human-readable name of the delegated settings entry. * * @return string|null + * + * @spec openspec/specs/case-email-integration/spec.md */ public function getName(): ?string { return 'Case email (shared mailbox)'; @@ -136,6 +142,8 @@ public function getName(): ?string { * flag and never surfaced as a readable delegated value. * * @return array Map of appId to allowed config keys. + * + * @spec openspec/specs/case-email-integration/spec.md */ public function getAuthorizedAppConfig(): array { return [Application::APP_ID => self::MANAGED_KEYS]; From 418e3b4ce27f943af44be134eb0d0d1d9b4319e5 Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Fri, 4 Sep 2026 09:37:55 +0200 Subject: [PATCH 5/7] docs(jsdoc): type and describe the last of the bare @param tags 59 more, in 27 files. These are the names the first two passes refused because no suffix rule covered them: ct, st, rt, def, duration, dir, out, mode, tpl and the rest. Each was read at its call site rather than pattern-matched, so `ct` is documented as a case type and `st` as a status type because that is what the functions taking them do with them. `value`, `val`, `newVal` and `v` are the payload of an input or update event. Their concrete type differs per call site, so they are typed as the union the call sites actually pass rather than as `*`, which jsdoc/reject-any-type flags for the same reason. eslint warnings 109 -> 50, and lint exits 0. What is left is not annotation debt: unused props and refs, deprecated OC globals, undefined components, one v-html. Those are code questions and get read one at a time. --- eslint-suppressions.json | 84 +------------------ src/components/map/AddressSearch.vue | 2 +- src/components/map/LocationPicker.vue | 4 +- src/dialogs/AiClassifyDialog.vue | 2 +- src/dialogs/AiExtractDialog.vue | 2 +- src/dialogs/ConsultationCreateDialog.vue | 2 +- src/dialogs/ConsultationResponseForm.vue | 2 +- src/dialogs/ZgwMappingDialog.vue | 2 +- src/views/cases/components/AdviesPanel.vue | 4 +- .../cases/components/InspectionPanel.vue | 2 +- .../components/EmailTemplateAdmin.vue | 4 +- src/views/public/PublicAppointmentPage.vue | 2 +- src/views/settings/CaseTypeDetail.vue | 2 +- src/views/settings/CaseTypeList.vue | 12 +-- src/views/settings/WorkflowEditor.vue | 4 +- .../settings/components/DurationPicker.vue | 4 +- .../components/MandaatToewijzingenTable.vue | 8 +- .../components/OrganisatieRolManager.vue | 4 +- .../settings/components/StepConfigPanel.vue | 12 +-- .../components/TransitionConfigPanel.vue | 6 +- .../settings/components/WorkflowNode.vue | 2 +- src/views/settings/tabs/AiSettingsTab.vue | 2 +- .../settings/tabs/FinancialIntegrationTab.vue | 4 +- src/views/settings/tabs/MandaatMatrixTab.vue | 4 +- src/views/settings/tabs/ResultsTab.vue | 6 +- src/views/settings/tabs/RolesTab.vue | 6 +- src/views/settings/tabs/StatusesTab.vue | 8 +- .../settings/tabs/TermijnDefinitiesTab.vue | 6 +- 28 files changed, 60 insertions(+), 142 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 69e189401..1546fe027 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -31,9 +31,6 @@ "src/components/map/AddressSearch.vue": { "@nextcloud/l10n-enforce-ellipsis": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/components/map/LocationPicker.vue": { @@ -41,7 +38,7 @@ "count": 3 }, "jsdoc/require-param-type": { - "count": 3 + "count": 1 } }, "src/components/tabs/CaseDocumentsTab.vue": { @@ -76,17 +73,11 @@ "src/dialogs/AiClassifyDialog.vue": { "@nextcloud/no-deprecated-library-props": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/dialogs/AiExtractDialog.vue": { "@nextcloud/no-deprecated-library-props": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/dialogs/BerichtenboxComposeDialog.vue": { @@ -132,9 +123,6 @@ }, "@nextcloud/no-deprecated-library-props": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/dialogs/ConsultationResponseForm.vue": { @@ -143,9 +131,6 @@ }, "@nextcloud/no-deprecated-library-props": { "count": 3 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/dialogs/CreateFederatedShareDialog.vue": { @@ -234,9 +219,6 @@ "src/dialogs/ZgwMappingDialog.vue": { "@nextcloud/no-deprecated-library-props": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/main.js": { @@ -425,9 +407,6 @@ "@typescript-eslint/no-unused-vars": { "count": 1 }, - "jsdoc/require-param-type": { - "count": 2 - }, "no-console": { "count": 3 } @@ -485,9 +464,6 @@ }, "@nextcloud/no-deprecated-library-props": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/views/cases/components/ShareTab.vue": { @@ -521,9 +497,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 2 } }, "src/views/dashboard/WooDeadlinePanel.vue": { @@ -556,9 +529,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/views/public/PublicFederatedTransferPage.vue": { @@ -586,17 +556,11 @@ }, "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/views/settings/CaseTypeList.vue": { "@nextcloud/no-deprecated-library-props": { "count": 3 - }, - "jsdoc/require-param-type": { - "count": 6 } }, "src/views/settings/EmailSettings.vue": { @@ -659,9 +623,6 @@ "src/views/settings/WorkflowEditor.vue": { "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 2 } }, "src/views/settings/ZgwMappingSettings.vue": { @@ -669,11 +630,6 @@ "count": 2 } }, - "src/views/settings/components/DurationPicker.vue": { - "jsdoc/require-param-type": { - "count": 2 - } - }, "src/views/settings/components/MandaatImportPanel.vue": { "@nextcloud/no-deprecated-library-props": { "count": 2 @@ -690,9 +646,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 4 } }, "src/views/settings/components/OrganisatieRolManager.vue": { @@ -701,9 +654,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 2 } }, "src/views/settings/components/RolNode.vue": { @@ -720,23 +670,14 @@ }, "eqeqeq": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 6 } }, "src/views/settings/components/TransitionConfigPanel.vue": { "@nextcloud/no-deprecated-library-props": { "count": 6 - }, - "jsdoc/require-param-type": { - "count": 3 } }, "src/views/settings/components/WorkflowNode.vue": { - "jsdoc/require-param-type": { - "count": 1 - }, "vue/custom-event-name-casing": { "count": 12 } @@ -752,9 +693,6 @@ "src/views/settings/tabs/AiSettingsTab.vue": { "@typescript-eslint/no-unused-vars": { "count": 2 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/views/settings/tabs/ChecklistsTab.vue": { @@ -794,11 +732,6 @@ "count": 3 } }, - "src/views/settings/tabs/FinancialIntegrationTab.vue": { - "jsdoc/require-param-type": { - "count": 2 - } - }, "src/views/settings/tabs/GeneralTab.vue": { "@typescript-eslint/no-unused-vars": { "count": 1 @@ -818,9 +751,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 4 - }, - "jsdoc/require-param-type": { - "count": 2 } }, "src/views/settings/tabs/PropertiesTab.vue": { @@ -831,25 +761,16 @@ "src/views/settings/tabs/ResultsTab.vue": { "@nextcloud/no-deprecated-library-props": { "count": 5 - }, - "jsdoc/require-param-type": { - "count": 3 } }, "src/views/settings/tabs/RolesTab.vue": { "@nextcloud/no-deprecated-library-props": { "count": 5 - }, - "jsdoc/require-param-type": { - "count": 3 } }, "src/views/settings/tabs/StatusesTab.vue": { "@nextcloud/no-deprecated-library-props": { "count": 5 - }, - "jsdoc/require-param-type": { - "count": 4 } }, "src/views/settings/tabs/SubCaseTypesTab.vue": { @@ -866,9 +787,6 @@ "src/views/settings/tabs/TermijnDefinitiesTab.vue": { "@nextcloud/no-deprecated-library-props": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 3 } }, "src/views/settings/tabs/WorkflowTab.vue": { diff --git a/src/components/map/AddressSearch.vue b/src/components/map/AddressSearch.vue index 0fb8b2729..b9c2ab920 100644 --- a/src/components/map/AddressSearch.vue +++ b/src/components/map/AddressSearch.vue @@ -66,7 +66,7 @@ export default { methods: { /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ async onInput(value) { diff --git a/src/components/map/LocationPicker.vue b/src/components/map/LocationPicker.vue index b9d81ab6d..9bba993e1 100644 --- a/src/components/map/LocationPicker.vue +++ b/src/components/map/LocationPicker.vue @@ -168,7 +168,7 @@ export default { }, /** - * @param mode + * @param {string} mode The drawing mode the picker is in. * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ setMode(mode) { @@ -236,7 +236,7 @@ export default { }, /** - * @param root0 + * @param {object} root0 The destructured argument object. * @param root0.coordinates * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ diff --git a/src/dialogs/AiClassifyDialog.vue b/src/dialogs/AiClassifyDialog.vue index 0e9e122b1..4f4d4d452 100644 --- a/src/dialogs/AiClassifyDialog.vue +++ b/src/dialogs/AiClassifyDialog.vue @@ -101,7 +101,7 @@ export default { watch: { /** - * @param val + * @param {string|number|boolean|object} val The new value. * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ show(val) { diff --git a/src/dialogs/AiExtractDialog.vue b/src/dialogs/AiExtractDialog.vue index 790ac87eb..00a69a878 100644 --- a/src/dialogs/AiExtractDialog.vue +++ b/src/dialogs/AiExtractDialog.vue @@ -149,7 +149,7 @@ export default { watch: { /** - * @param val + * @param {string|number|boolean|object} val The new value. * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ show(val) { diff --git a/src/dialogs/ConsultationCreateDialog.vue b/src/dialogs/ConsultationCreateDialog.vue index c79905911..80dabc229 100644 --- a/src/dialogs/ConsultationCreateDialog.vue +++ b/src/dialogs/ConsultationCreateDialog.vue @@ -180,7 +180,7 @@ export default { watch: { /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-05 */ open(value) { diff --git a/src/dialogs/ConsultationResponseForm.vue b/src/dialogs/ConsultationResponseForm.vue index db2c6969e..1c5d3aa1b 100644 --- a/src/dialogs/ConsultationResponseForm.vue +++ b/src/dialogs/ConsultationResponseForm.vue @@ -216,7 +216,7 @@ export default { watch: { /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/consultation-management/tasks.md#TASK-CN-05 */ open(value) { diff --git a/src/dialogs/ZgwMappingDialog.vue b/src/dialogs/ZgwMappingDialog.vue index 4d3c2a77d..5eec3254e 100644 --- a/src/dialogs/ZgwMappingDialog.vue +++ b/src/dialogs/ZgwMappingDialog.vue @@ -145,7 +145,7 @@ export default { open: { immediate: true, /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/retrofit-2026-05-24-zgw-api-mapping/tasks.md */ handler(value) { diff --git a/src/views/cases/components/AdviesPanel.vue b/src/views/cases/components/AdviesPanel.vue index eb3851265..5bef3e0f7 100644 --- a/src/views/cases/components/AdviesPanel.vue +++ b/src/views/cases/components/AdviesPanel.vue @@ -132,7 +132,7 @@ export default { caseId: { immediate: true, /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ handler(value) { @@ -274,7 +274,7 @@ export default { }, /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/retrofit-2026-05-24-advice-management/tasks.md */ formatDate(value) { diff --git a/src/views/cases/components/InspectionPanel.vue b/src/views/cases/components/InspectionPanel.vue index 45d40792d..caa42c9a8 100644 --- a/src/views/cases/components/InspectionPanel.vue +++ b/src/views/cases/components/InspectionPanel.vue @@ -371,7 +371,7 @@ export default { }, /** - * @param checklist + * @param {object} checklist The checklist. * @spec openspec/changes/retrofit-2026-05-24-inspection-checklists/tasks.md */ selectedChecklist(checklist) { diff --git a/src/views/casetypes/components/EmailTemplateAdmin.vue b/src/views/casetypes/components/EmailTemplateAdmin.vue index 89200f623..e5b10d884 100644 --- a/src/views/casetypes/components/EmailTemplateAdmin.vue +++ b/src/views/casetypes/components/EmailTemplateAdmin.vue @@ -239,7 +239,7 @@ export default { }, /** - * @param group + * @param {object} group The group. * @spec openspec/specs/case-email-integration/spec.md */ groupLabel(group) { @@ -301,7 +301,7 @@ export default { }, /** - * @param tpl + * @param {object} tpl The tpl. * @spec openspec/specs/case-email-integration/spec.md */ selectTemplate(tpl) { diff --git a/src/views/public/PublicAppointmentPage.vue b/src/views/public/PublicAppointmentPage.vue index 5b1987701..1f1fa9f81 100644 --- a/src/views/public/PublicAppointmentPage.vue +++ b/src/views/public/PublicAppointmentPage.vue @@ -78,7 +78,7 @@ export default { methods: { t, /** - * @param dt + * @param {string} dt The date-time to format. * @spec openspec/changes/retrofit-2026-05-25-appointment-booking/tasks.md */ formatDateTime(dt) { diff --git a/src/views/settings/CaseTypeDetail.vue b/src/views/settings/CaseTypeDetail.vue index f16595ab1..3a0505bdc 100644 --- a/src/views/settings/CaseTypeDetail.vue +++ b/src/views/settings/CaseTypeDetail.vue @@ -300,7 +300,7 @@ export default { /** * @param {object} field The field. - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ onFieldUpdate(field, value) { diff --git a/src/views/settings/CaseTypeList.vue b/src/views/settings/CaseTypeList.vue index 0abc8e041..8abb31ddd 100644 --- a/src/views/settings/CaseTypeList.vue +++ b/src/views/settings/CaseTypeList.vue @@ -177,7 +177,7 @@ export default { }, /** - * @param duration + * @param {string} duration An ISO 8601 duration, for example P30D. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ formatDeadline(duration) { @@ -185,7 +185,7 @@ export default { }, /** - * @param ct + * @param {object} ct The case type. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ formatValidity(ct) { @@ -205,7 +205,7 @@ export default { }, /** - * @param ct + * @param {object} ct The case type. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ validityClass(ct) { @@ -225,7 +225,7 @@ export default { }, /** - * @param ct + * @param {object} ct The case type. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ async setDefault(ct) { @@ -242,7 +242,7 @@ export default { }, /** - * @param ct + * @param {object} ct The case type. * @spec openspec/changes/retrofit-2026-05-24-case-types/tasks.md */ async confirmDelete(ct) { @@ -340,7 +340,7 @@ export default { /** * Deep-copy a case type into a new draft, then navigate to it. * - * @param ct + * @param {object} ct The case type. * @spec openspec/changes/zaaktype-copy/tasks.md#T09 */ async duplicate(ct) { diff --git a/src/views/settings/WorkflowEditor.vue b/src/views/settings/WorkflowEditor.vue index 88824791b..03883682d 100644 --- a/src/views/settings/WorkflowEditor.vue +++ b/src/views/settings/WorkflowEditor.vue @@ -655,7 +655,7 @@ export default { }, /** - * @param updatedStep + * @param {object} updatedStep The updated step. * @spec openspec/specs/workflow-definition-model/spec.md */ onStepUpdate(updatedStep) { @@ -666,7 +666,7 @@ export default { // --- Transition management --- /** - * @param updatedTransition + * @param {object} updatedTransition The updated transition. * @spec openspec/specs/workflow-definition-model/spec.md */ onTransitionUpdate(updatedTransition) { diff --git a/src/views/settings/components/DurationPicker.vue b/src/views/settings/components/DurationPicker.vue index 3973d6116..c996a05c6 100644 --- a/src/views/settings/components/DurationPicker.vue +++ b/src/views/settings/components/DurationPicker.vue @@ -100,7 +100,7 @@ export default { methods: { /** - * @param val + * @param {string|number|boolean|object} val The new value. * @spec openspec/changes/retrofit-2026-05-24-milestone-tracking/tasks.md */ onDaysChange(val) { @@ -113,7 +113,7 @@ export default { }, /** - * @param preset + * @param {object} preset The preset. * @spec openspec/changes/retrofit-2026-05-24-milestone-tracking/tasks.md */ selectPreset(preset) { diff --git a/src/views/settings/components/MandaatToewijzingenTable.vue b/src/views/settings/components/MandaatToewijzingenTable.vue index 84796aa43..1ee4a0dc9 100644 --- a/src/views/settings/components/MandaatToewijzingenTable.vue +++ b/src/views/settings/components/MandaatToewijzingenTable.vue @@ -133,7 +133,7 @@ export default { methods: { t, /** - * @param a + * @param {object} a The item to compare. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ isWaarnemer(a) { @@ -142,7 +142,7 @@ export default { }, /** - * @param a + * @param {object} a The item to compare. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ typeClass(a) { @@ -152,7 +152,7 @@ export default { }, /** - * @param a + * @param {object} a The item to compare. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ roleLabel(a) { @@ -161,7 +161,7 @@ export default { }, /** - * @param a + * @param {object} a The item to compare. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ openEnd(a) { diff --git a/src/views/settings/components/OrganisatieRolManager.vue b/src/views/settings/components/OrganisatieRolManager.vue index 2882324ba..b40f2799d 100644 --- a/src/views/settings/components/OrganisatieRolManager.vue +++ b/src/views/settings/components/OrganisatieRolManager.vue @@ -137,7 +137,7 @@ export default { methods: { t, /** - * @param role + * @param {object} role The role. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ openEditor(role) { @@ -152,7 +152,7 @@ export default { }, /** - * @param role + * @param {object} role The role. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ confirmDelete(role) { diff --git a/src/views/settings/components/StepConfigPanel.vue b/src/views/settings/components/StepConfigPanel.vue index 3c054a7b1..fb1fff91e 100644 --- a/src/views/settings/components/StepConfigPanel.vue +++ b/src/views/settings/components/StepConfigPanel.vue @@ -399,7 +399,7 @@ export default { watch: { step: { /** - * @param newStep + * @param {object} newStep The new step. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ handler(newStep) { @@ -534,7 +534,7 @@ export default { }, /** - * @param index + * @param {number} index Index of the row in the list. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ removeRequiredField(index) { @@ -548,7 +548,7 @@ export default { }, /** - * @param checklist + * @param {object} checklist The checklist. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ parseChecklist(checklist) { @@ -606,7 +606,7 @@ export default { }, /** - * @param index + * @param {number} index Index of the row in the list. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ removeChecklistItem(index) { @@ -615,7 +615,7 @@ export default { }, /** - * @param index + * @param {number} index Index of the row in the list. * @param {Event} event The originating DOM event. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ @@ -648,7 +648,7 @@ export default { }, /** - * @param index + * @param {number} index Index of the row in the list. * @spec openspec/changes/retrofit-2026-05-25-process-step-configuration/tasks.md */ removeAction(index) { diff --git a/src/views/settings/components/TransitionConfigPanel.vue b/src/views/settings/components/TransitionConfigPanel.vue index cc50f6c75..7d7b2f024 100644 --- a/src/views/settings/components/TransitionConfigPanel.vue +++ b/src/views/settings/components/TransitionConfigPanel.vue @@ -319,7 +319,7 @@ export default { watch: { transition: { /** - * @param newVal + * @param {string|number|boolean|object} newVal The new value. * @spec openspec/specs/status-transition-engine/spec.md */ handler(newVal) { @@ -397,7 +397,7 @@ export default { }, /** - * @param index + * @param {number} index Index of the row in the list. * @spec openspec/specs/status-transition-engine/spec.md */ removeGuard(index) { @@ -412,7 +412,7 @@ export default { }, /** - * @param index + * @param {number} index Index of the row in the list. * @spec openspec/specs/status-transition-engine/spec.md */ removeAction(index) { diff --git a/src/views/settings/components/WorkflowNode.vue b/src/views/settings/components/WorkflowNode.vue index 040ce0474..482f0d4dd 100644 --- a/src/views/settings/components/WorkflowNode.vue +++ b/src/views/settings/components/WorkflowNode.vue @@ -235,7 +235,7 @@ export default { }, /** - * @param targetStep + * @param {object} targetStep The target step. * @param {Event} event The originating DOM event. * @spec openspec/specs/workflow-definition-model/spec.md */ diff --git a/src/views/settings/tabs/AiSettingsTab.vue b/src/views/settings/tabs/AiSettingsTab.vue index 4f9fb28e9..831b3d5a4 100644 --- a/src/views/settings/tabs/AiSettingsTab.vue +++ b/src/views/settings/tabs/AiSettingsTab.vue @@ -234,7 +234,7 @@ export default { t, /** * @param {string} key The key. - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/retrofit-2026-05-24-ai-assistance/tasks.md */ async updateSetting(key, value) { diff --git a/src/views/settings/tabs/FinancialIntegrationTab.vue b/src/views/settings/tabs/FinancialIntegrationTab.vue index b83673d12..147bb80db 100644 --- a/src/views/settings/tabs/FinancialIntegrationTab.vue +++ b/src/views/settings/tabs/FinancialIntegrationTab.vue @@ -83,7 +83,7 @@ export default { methods: { t, /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/enforce-dwangsom-callback-signature/tasks.md#task-2 */ async onSecretInput(value) { @@ -103,7 +103,7 @@ export default { }, /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/changes/enforce-dwangsom-callback-signature/tasks.md#task-2 */ async persist(value) { diff --git a/src/views/settings/tabs/MandaatMatrixTab.vue b/src/views/settings/tabs/MandaatMatrixTab.vue index ce9c8f1ad..451bde7f4 100644 --- a/src/views/settings/tabs/MandaatMatrixTab.vue +++ b/src/views/settings/tabs/MandaatMatrixTab.vue @@ -122,7 +122,7 @@ export default { active: { immediate: true, /** - * @param v + * @param {string|number|boolean|object} v The new value. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ handler(v) { @@ -187,7 +187,7 @@ export default { }, /** - * @param mandaat + * @param {object} mandaat The mandaat. * @spec openspec/changes/mandaat-matrix-07-admin-ui/tasks.md */ openEditor(mandaat) { diff --git a/src/views/settings/tabs/ResultsTab.vue b/src/views/settings/tabs/ResultsTab.vue index 2418df19b..de8385702 100644 --- a/src/views/settings/tabs/ResultsTab.vue +++ b/src/views/settings/tabs/ResultsTab.vue @@ -287,7 +287,7 @@ export default { methods: { /** - * @param period + * @param {object} period The period. * @spec openspec/changes/retrofit-2026-05-25-admin-settings/tasks.md */ formatPeriod(period) { @@ -340,7 +340,7 @@ export default { }, /** - * @param rt + * @param {object} rt The type being edited in this tab. * @spec openspec/changes/retrofit-2026-05-25-admin-settings/tasks.md */ startEdit(rt) { @@ -384,7 +384,7 @@ export default { }, /** - * @param rt + * @param {object} rt The type being edited in this tab. * @spec openspec/changes/retrofit-2026-05-25-admin-settings/tasks.md */ async deleteResultType(rt) { diff --git a/src/views/settings/tabs/RolesTab.vue b/src/views/settings/tabs/RolesTab.vue index f251eb666..840d5f536 100644 --- a/src/views/settings/tabs/RolesTab.vue +++ b/src/views/settings/tabs/RolesTab.vue @@ -233,7 +233,7 @@ export default { methods: { /** - * @param value + * @param {string|number|boolean|object} value The new value. * @spec openspec/specs/role-based-step-routing/spec.md */ genericRoleLabel(value) { @@ -284,7 +284,7 @@ export default { }, /** - * @param rt + * @param {object} rt The type being edited in this tab. * @spec openspec/specs/role-based-step-routing/spec.md */ startEdit(rt) { @@ -326,7 +326,7 @@ export default { }, /** - * @param rt + * @param {object} rt The type being edited in this tab. * @spec openspec/specs/role-based-step-routing/spec.md */ async deleteRoleType(rt) { diff --git a/src/views/settings/tabs/StatusesTab.vue b/src/views/settings/tabs/StatusesTab.vue index 794f30b10..4750f50f3 100644 --- a/src/views/settings/tabs/StatusesTab.vue +++ b/src/views/settings/tabs/StatusesTab.vue @@ -377,7 +377,7 @@ export default { }, /** - * @param st + * @param {object} st The status type. * @spec openspec/specs/status-transition-engine/spec.md */ startEdit(st) { @@ -455,7 +455,7 @@ export default { }, /** - * @param st + * @param {object} st The status type. * @spec openspec/specs/status-transition-engine/spec.md */ async deleteStatusType(st) { @@ -495,7 +495,7 @@ export default { // Drag and drop /** - * @param index + * @param {number} index Index of the row in the list. * @param {Event} event The originating DOM event. * @spec openspec/specs/status-transition-engine/spec.md */ @@ -505,7 +505,7 @@ export default { }, /** - * @param index + * @param {number} index Index of the row in the list. * @spec openspec/specs/status-transition-engine/spec.md */ onDragOver(index) { diff --git a/src/views/settings/tabs/TermijnDefinitiesTab.vue b/src/views/settings/tabs/TermijnDefinitiesTab.vue index afbcd3f3d..13a583dcd 100644 --- a/src/views/settings/tabs/TermijnDefinitiesTab.vue +++ b/src/views/settings/tabs/TermijnDefinitiesTab.vue @@ -178,7 +178,7 @@ export default { }, /** - * @param def + * @param {object} def The definition being edited. * @spec openspec/changes/termijnbewaking-dwangsom-engine-11-tests-admin-docs/tasks.md */ isActive(def) { @@ -189,7 +189,7 @@ export default { }, /** - * @param def + * @param {object} def The definition being edited. * @spec openspec/changes/termijnbewaking-dwangsom-engine-11-tests-admin-docs/tasks.md */ formatDuur(def) { @@ -204,7 +204,7 @@ export default { }, /** - * @param def + * @param {object} def The definition being edited. * @spec openspec/changes/termijnbewaking-dwangsom-engine-11-tests-admin-docs/tasks.md */ openEdit(def) { From 6e47232cd4122d8aed85f49087f0512c4c0c37aa Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Fri, 4 Sep 2026 16:08:52 +0200 Subject: [PATCH 6/7] fix(demo): a re-install stores nothing and is still an install The only failing E2E test on development, on every CI run since 2026-09-03: installing the demo data reports HOW MUCH landed, not just success Error: install failed: The demo import stored 0 of 444 object(s) (24 refused by OpenRegister). The step's own body tells the operator it is "safe to run more than once", and `demo-data-setup-step.spec.ts:132` asserts the server keeps that promise. It could not: an idempotent import necessarily stores zero the second time, and the guard read `objects === 0` as failure. Reproduced on a pristine rig. OpenRegister's debug log shows what is actually happening to the 444: 840 [ImportHandler] Found 1 results 840 [ImportHandler] Skipped object update: imported version not higher 420 were already present at the same version and correctly left alone, 24 were refused with logged reasons, 0 needed storing. So the question is whether anything SURVIVED, not whether anything moved. `unchanged` is the importer's own count, added in openregister#3410, which this reads. It is NOT computed here as `requested - stored - refused`: that subtraction looks equivalent and reclassifies an object the importer dropped without saying so as "already present", which is the exact failure the guard exists to catch. An import where everything failed still throws, and the three unit tests that pin that behaviour still pass unchanged. The operator message gains the count that explains a zero: "0 of 444 objects stored ... (24 refused, 420 already present)" rather than a bare zero that reads as a broken install. Verified against a pristine instance running both changes: demo-data-setup-step.spec.ts goes from 1 failed + 1 flaky to 3 passed. REQUIRES openregister#3410. Without it `unchanged` is absent, reads as 0, and the guard behaves exactly as it does today: no crash, no change. --- lib/Controller/SetupController.php | 5 ++- lib/Service/DemoDataService.php | 35 +++++++++++++---- src/views/settings/CaseTypeList.vue | 3 +- tests/Unit/Service/DemoDataServiceTest.php | 44 +++++++++++++++++++--- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/lib/Controller/SetupController.php b/lib/Controller/SetupController.php index 9598ce739..f2afe7082 100644 --- a/lib/Controller/SetupController.php +++ b/lib/Controller/SetupController.php @@ -297,11 +297,12 @@ private function installDemoData(): DataResponse { [ 'success' => true, 'message' => sprintf( - 'Demo data installed: %d of %d objects stored across %d schemas (%d refused).', + 'Demo data installed: %d of %d objects stored across %d schemas (%d refused, %d already present).', $imported['objects'], $imported['requested'], $imported['schemas'], - $imported['refused'] + $imported['refused'], + $imported['unchanged'] ), 'detail' => $imported, ] diff --git a/lib/Service/DemoDataService.php b/lib/Service/DemoDataService.php index 5714cafb4..3b2f1a3da 100644 --- a/lib/Service/DemoDataService.php +++ b/lib/Service/DemoDataService.php @@ -116,9 +116,11 @@ public function isAvailable(): bool { * `skipped.objects` — the ones it refused. Both are read here, and both are * returned, so a caller can print the landing next to the ask. * - * @return array{objects: integer, requested: integer, refused: integer, registers: integer, schemas: integer} What was asked for and what landed. + * @return array{objects: integer, requested: integer, refused: integer, unchanged: integer, + * registers: integer, schemas: integer} What was asked for and what landed. * - * @throws RuntimeException When the descriptor is missing or unreadable, OpenRegister is absent, or the import stored nothing. + * @throws RuntimeException When the descriptor is missing or unreadable, OpenRegister is + * absent, or nothing was stored and nothing was already present. * * @spec openspec/changes/first-time-setup/specs/first-time-setup/spec.md */ @@ -155,11 +157,19 @@ public function install(): array { // The LANDING. An importer reply with no `objects` key has said nothing // about objects, and nothing is zero — never "as many as we asked for". - $skipped = (array)($result['skipped'] ?? []); - $imported = [ + $skipped = (array)($result['skipped'] ?? []); + $unchanged = (array)($result['unchanged'] ?? []); + $imported = [ 'objects' => count((array)($result['objects'] ?? [])), 'requested' => $requested, 'refused' => (int)($skipped['objects'] ?? 0), + // Already present at the same version, so correctly left alone. + // REPORTED BY THE IMPORTER, not inferred here: deriving it as + // `requested - stored - refused` looks equivalent and is not, because + // it silently reclassifies an object the importer dropped WITHOUT + // saying so as "already present", which is the exact failure this + // guard exists to catch. + 'unchanged' => (int)($unchanged['objects'] ?? 0), 'registers' => count((array)($result['registers'] ?? [])), 'schemas' => count((array)($result['schemas'] ?? [])), ]; @@ -170,12 +180,21 @@ public function install(): array { // recorded themselves as done. A descriptor that ships no objects at // all is a different condition and stays a success: registers and // schemas are a legitimate thing to ship on their own. - if ($requested > 0 && $imported['objects'] === 0) { + // STORING NOTHING IS NOT THE SAME AS FAILING. This read `objects === 0` + // alone, which refuses an import whose objects are already there, and + // that is the normal case on a second run. The step's own body promises + // it is "safe to run more than once", and an idempotent import + // necessarily stores zero the second time. Measured on CI, dossiq + // development, every run since 2026-09-03: 444 requested, 0 stored, + // reported as a hard failure on an install with nothing left to do. + // + // So the question is whether anything SURVIVED, not whether anything + // moved. + if ($requested > 0 && $imported['objects'] === 0 && $imported['unchanged'] === 0) { throw new RuntimeException( 'The demo import stored 0 of ' . $requested . ' object(s) (' - . $imported['refused'] . ' refused by OpenRegister). Nothing was written, so this is not ' - . 'an install. Check the OpenRegister log for the refusals, and note that an object whose ' - . 'version has not moved is left alone: re-importing an already-imported demo set lands nothing.' + . $imported['refused'] . ' refused by OpenRegister) and none was already present. ' + . 'Nothing was written, so this is not an install. Check the OpenRegister log for the refusals.' ); } diff --git a/src/views/settings/CaseTypeList.vue b/src/views/settings/CaseTypeList.vue index 8abb31ddd..648c893aa 100644 --- a/src/views/settings/CaseTypeList.vue +++ b/src/views/settings/CaseTypeList.vue @@ -85,7 +85,7 @@ import { CnIndexPage } from '@conduction/nextcloud-vue' import axios from '@nextcloud/axios' import { generateUrl } from '@nextcloud/router' -import { NcLoadingIcon } from '@nextcloud/vue' +import { NcButton, NcLoadingIcon } from '@nextcloud/vue' import ContentDuplicateIcon from 'vue-material-design-icons/ContentDuplicate.vue' import DeleteIcon from 'vue-material-design-icons/Delete.vue' import StarIcon from 'vue-material-design-icons/Star.vue' @@ -99,6 +99,7 @@ export default { StarIcon, DeleteIcon, ContentDuplicateIcon, + NcButton, NcLoadingIcon, CnIndexPage, }, diff --git a/tests/Unit/Service/DemoDataServiceTest.php b/tests/Unit/Service/DemoDataServiceTest.php index 8d926f058..b6e271452 100644 --- a/tests/Unit/Service/DemoDataServiceTest.php +++ b/tests/Unit/Service/DemoDataServiceTest.php @@ -100,16 +100,21 @@ private function shipDescriptor(int $objects = 2): void { * * @return object The fake. */ - private function importerSpy(int $landed = 2, int $refused = 0): object { - return new class($landed, $refused) { + private function importerSpy(int $landed = 2, int $refused = 0, int $unchanged = 0): object { + return new class($landed, $refused, $unchanged) { /** @var array */ public array $seen = []; /** - * @param integer $landed Objects created or updated. - * @param integer $refused Objects refused. + * @param integer $landed Objects created or updated. + * @param integer $refused Objects refused. + * @param integer $unchanged Objects already present at the same version. */ - public function __construct(private readonly int $landed, private readonly int $refused) { + public function __construct( + private readonly int $landed, + private readonly int $refused, + private readonly int $unchanged, + ) { } /** @@ -127,6 +132,7 @@ public function importFromApp(string $appId, array $data, string $version, bool 'schemas' => ['Thing'], 'objects' => array_fill(0, $this->landed, 'entity'), 'skipped' => ['registers' => 0, 'schemas' => 0, 'objects' => $this->refused], + 'unchanged' => ['objects' => $this->unchanged], ]; } }; @@ -187,6 +193,34 @@ public function testAnImportThatStoresNothingThrowsRatherThanReportingSuccess(): $this->service->install(); } + /** + * A RE-INSTALL STORES NOTHING AND IS STILL A SUCCESS. + * + * The setup step's own body tells the operator it is "safe to run more than + * once", and an idempotent import necessarily stores zero the second time. + * Reading `objects === 0` as failure broke that promise: measured on CI, + * dossiq development, every run since 2026-09-03 reported a hard failure on + * an install of 444 objects that had nothing left to do. + * + * `unchanged` is the importer's own count, added in openregister for this, + * NOT `requested - stored - refused`. The subtraction looks equivalent and + * is not: it reclassifies an object the importer dropped without saying so + * as "already present", which is the failure the guard above exists to catch. + * + * @return void + * + * @spec openspec/changes/first-time-setup/specs/first-time-setup/spec.md + */ + public function testAnImportThatOnlyFoundExistingObjectsIsStillASuccess(): void { + $this->shipDescriptor(objects: 4); + $this->container->method('get')->willReturn($this->importerSpy(landed: 0, unchanged: 4)); + + $result = $this->service->install(); + + $this->assertSame(0, $result['objects'], 'nothing needed storing'); + $this->assertSame(4, $result['unchanged'], 'and the reason is that all four were already there'); + } + /** * The refusal count is what tells an operator WHY nothing landed, so it has * to survive into the message rather than being folded into a bare zero. From 03909497e6dca6f078b62ba3940d312f900bebfd Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Fri, 4 Sep 2026 17:10:39 +0200 Subject: [PATCH 7/7] fix(lint): clear the last 50 warnings, and one of them was a real defect eslint is now at ZERO warnings, from 823 at the start of this branch. The one that mattered: `CaseTypeList.vue` used three times and neither imported nor registered it. Every other file that uses NcButton imports it and there is no global registration, so those three buttons could not render. vue/no-undef-components had been reporting it as a warning among 822 others. Real fixes: - NcButton imported and registered in CaseTypeList. - `OC.currentUser` replaced with `getCurrentUser()` from @nextcloud/auth at four sites. Deprecated since Nextcloud 19, and three of the four already called getCurrentUser() first and only fell back to the deprecated global. - `caseRelationApi.addRelation` documented `params.notes`, a property the function never had: it destructures `{targetId, aardRelatie, toelichting}`. The tag now names the parameter that exists. - One dead prop (`InspectionChecklistPanel.caseId`, passed by nobody, read by nobody) and two dead template refs removed. False positives, annotated with the reason rather than "fixed": - The 7 dashboard widgets' `title` prop IS passed by their mount scripts, and the Nextcloud host renders the heading. Removing the declaration would not remove the prop, it would make it a fallthrough attribute and put a title="" tooltip on the root element. - `RedactionAssistDialog.open` and `InspectionPanel.canInspect` default to true deliberately and nothing passes them. Flipping the default to satisfy vue/no-boolean-default would change behaviour, not style: the dialog would mount closed and inspection would be off everywhere. - `EmailTemplateAdmin`'s v-html renders renderPreview(), which escapes &, < and > in the body and emits only its own fixed-class and
. No caller-supplied markup can reach the DOM. - `CnNotesTabComponent` is a computed component behind a v-if guard, which vue/no-undef-components cannot resolve. The rest were annotation: 33 files needed a blank line between a docblock description and its first tag, six `{*}` types became the specific type each doc already described in prose, and two `@type` tags were moved out of prose where jsdoc read them as inline tags. lint, format, stylelint, vitest, phpunit, phpcs, phpstan and psalm all exit 0. --- eslint-suppressions.json | 17 ----------------- scripts/vue3-compile-sweep.cjs | 8 ++++++-- src/components/map/LocationPicker.vue | 2 +- src/dialogs/EndAssignmentDialog.vue | 4 ++++ src/dialogs/RedactionAssistDialog.vue | 4 ++++ src/dialogs/StufEnvelopeDialog.vue | 2 +- src/modals/DeelzaakCreateModal.vue | 7 ++++--- src/services/analyticsSeriesApi.js | 3 +++ src/services/bagApi.js | 3 +++ src/services/besluitvormingApi.js | 1 + src/services/brkApi.js | 2 ++ src/services/caseRelationApi.js | 3 +-- src/services/formatters.js | 2 +- src/services/pdokService.js | 4 ++-- src/services/wozApi.js | 3 +++ src/store/modules/workflow.js | 2 ++ src/utils/caseExportHelpers.js | 2 +- src/utils/i18nResolver.js | 2 +- src/utils/routerBase.js | 1 + src/views/CasesOnMapView.vue | 4 ++-- src/views/MyWorkCards.vue | 7 ++----- src/views/cases/DeelzaakDetail.vue | 1 + .../cases/components/AiConfidenceBadge.vue | 4 ++++ src/views/cases/components/CaseNotesTab.vue | 4 ++++ .../components/InspectionChecklistPanel.vue | 4 ---- src/views/cases/components/InspectionPanel.vue | 13 +++++++++---- .../components/EmailTemplateAdmin.vue | 7 +++++-- src/views/doorlooptijd/widgets/DtKpiWidget.vue | 1 + src/views/doorlooptijd/widgets/DtWooWidget.vue | 1 + src/views/processMining/pmWidgetMixin.js | 1 + .../processMining/processMiningShaping.js | 1 + src/views/public/PublicStatusPage.vue | 2 +- src/views/settings/SubstitutionSettings.vue | 3 ++- src/views/settings/tabs/ChecklistsTab.vue | 2 +- src/views/termijn/TdAnnualWidget.vue | 1 + src/views/termijn/TdKpiWidget.vue | 1 + src/views/termijn/TdQuarterlyWidget.vue | 2 ++ src/views/widgets/CasesOverviewWidget.vue | 6 ++++++ src/views/widgets/DeadlineAlertsWidget.vue | 6 ++++++ src/views/widgets/MyTasksWidget.vue | 6 ++++++ src/views/widgets/OverdueCasesWidget.vue | 6 ++++++ src/views/widgets/StalledCasesWidget.vue | 6 ++++++ src/views/widgets/StartCaseWidget.vue | 6 ++++++ src/views/widgets/TaskRemindersWidget.vue | 6 ++++++ src/views/workflow-board/WorkflowBoard.vue | 1 + tests/e2e/case-create-form.spec.ts | 1 + tests/e2e/case-detail-kpis-and-tabs.spec.ts | 1 - tests/e2e/demo-caseload.spec.ts | 1 + tests/e2e/helpers/addressFixtures.ts | 3 +++ tests/e2e/helpers/becomes-visible.js | 2 ++ tests/e2e/helpers/fixtures.ts | 18 ++++++++++++++++++ tests/e2e/helpers/nav.ts | 6 ++++++ .../case-email-integration.spec.ts | 1 + ...an-board-keyboard-status-transition.spec.ts | 1 + tests/e2e/workflows/case-lifecycle.spec.ts | 1 + tests/e2e/workflows/cases-crud.spec.ts | 1 + tests/e2e/workflows/complaints-bezwaar.spec.ts | 2 ++ .../e2e/workflows/deelzaak-case-email.spec.ts | 1 + tests/vitest/bagApi.spec.js | 1 + tests/vitest/brkApi.spec.js | 1 + tests/vitest/pdokService.spec.js | 2 ++ tests/vitest/wozApi.spec.js | 1 + 62 files changed, 166 insertions(+), 52 deletions(-) diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 1546fe027..b25f768c0 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -36,9 +36,6 @@ "src/components/map/LocationPicker.vue": { "@nextcloud/no-deprecated-library-props": { "count": 3 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/components/tabs/CaseDocumentsTab.vue": { @@ -235,9 +232,6 @@ } }, "src/modals/DeelzaakCreateModal.vue": { - "@nextcloud/no-deprecated-library-props": { - "count": 2 - }, "no-console": { "count": 3 } @@ -458,14 +452,6 @@ "count": 1 } }, - "src/views/cases/components/InspectionPanel.vue": { - "@nextcloud/l10n-enforce-ellipsis": { - "count": 1 - }, - "@nextcloud/no-deprecated-library-props": { - "count": 2 - } - }, "src/views/cases/components/ShareTab.vue": { "@nextcloud/l10n-enforce-ellipsis": { "count": 2 @@ -545,9 +531,6 @@ }, "@typescript-eslint/no-unused-vars": { "count": 1 - }, - "jsdoc/require-param-type": { - "count": 1 } }, "src/views/settings/CaseTypeDetail.vue": { diff --git a/scripts/vue3-compile-sweep.cjs b/scripts/vue3-compile-sweep.cjs index e2249d26a..9c094c504 100644 --- a/scripts/vue3-compile-sweep.cjs +++ b/scripts/vue3-compile-sweep.cjs @@ -2,6 +2,7 @@ * Vue 3 compile-readiness sweep (ADR-066, openspec vue-3-migration). * * Compiles every SFC template + script under src/ with @vue/compiler-sfc in + * * @vue/compat MODE 2, and reports which components fail to COMPILE on Vue 3. * This is the fastest signal for the migration: compile failures are hard * blockers, and this needs no bundle/install of the runtime deps. @@ -31,9 +32,12 @@ const root = path.resolve(__dirname, '..', 'src') const compat = { compatConfig: { MODE: 2, COMPILER_FILTERS: true } } /** + * Collect every file path under a directory, recursively. + * + * @param {string} dir Directory to walk. + * @param {Array} out Accumulator the paths are appended to. * - * @param dir - * @param out + * @return {Array} The same accumulator, for convenience. */ function walk(dir, out = []) { for (const e of fs.readdirSync(dir, { withFileTypes: true })) { diff --git a/src/components/map/LocationPicker.vue b/src/components/map/LocationPicker.vue index 9bba993e1..b4fcadff7 100644 --- a/src/components/map/LocationPicker.vue +++ b/src/components/map/LocationPicker.vue @@ -237,7 +237,7 @@ export default { /** * @param {object} root0 The destructured argument object. - * @param root0.coordinates + * @param {Array} root0.coordinates The [lon, lat] pair the picker selected. * @spec openspec/changes/retrofit-2026-05-25-map-component/tasks.md */ onAddressSelect({ coordinates }) { diff --git a/src/dialogs/EndAssignmentDialog.vue b/src/dialogs/EndAssignmentDialog.vue index f5c98ebb2..ddb874a36 100644 --- a/src/dialogs/EndAssignmentDialog.vue +++ b/src/dialogs/EndAssignmentDialog.vue @@ -55,6 +55,10 @@ export default { name: 'EndAssignmentDialog', components: { NcButton, NcDialog }, props: { + // MandaatToewijzingenTable passes `:assignment="ending"`. The dialog acts + // on it through its own emit rather than rendering it, and the declaration + // is what keeps it a prop instead of a fallthrough attribute. + // eslint-disable-next-line vue/no-unused-properties assignment: { type: Object, required: true }, }, diff --git a/src/dialogs/RedactionAssistDialog.vue b/src/dialogs/RedactionAssistDialog.vue index 9b6e1af44..4b89bf551 100644 --- a/src/dialogs/RedactionAssistDialog.vue +++ b/src/dialogs/RedactionAssistDialog.vue @@ -186,8 +186,12 @@ export default { }, props: { + // Defaults to true deliberately: nothing passes this, and the dialog is + // mounted to be shown. Flipping the default to satisfy the rule would + // change behaviour, not style, and the dialog would mount closed. open: { type: Boolean, + // eslint-disable-next-line vue/no-boolean-default default: true, }, diff --git a/src/dialogs/StufEnvelopeDialog.vue b/src/dialogs/StufEnvelopeDialog.vue index f5b259582..249f0621e 100644 --- a/src/dialogs/StufEnvelopeDialog.vue +++ b/src/dialogs/StufEnvelopeDialog.vue @@ -77,7 +77,7 @@ export default { /** * Pretty-print a value as indented JSON for display. * - * @param {*} value The value to render. + * @param {unknown} value The value to render. * @spec exclude presentational JSON formatter — no business logic */ pretty(value) { diff --git a/src/modals/DeelzaakCreateModal.vue b/src/modals/DeelzaakCreateModal.vue index a4879ce95..ee2791efe 100644 --- a/src/modals/DeelzaakCreateModal.vue +++ b/src/modals/DeelzaakCreateModal.vue @@ -121,12 +121,12 @@