What goes wrong
The contract-expiry warning can never fire, because it filters on a status value no contract can have. Separately, the rule that a contract only becomes Active after an approved decision is not enforced: anyone who can edit a contract can set it to Active in the form.
Evidence, re-read at c9760e0
Expiry warning, lib/Settings/softwarecatalogus_register.json:3252-3265 (catalogContract, x-openregister-notifications.contract-expiry):
- The scheduled trigger filters
"status": {"operator": "equals", "value": "Actief"} together with endDate withinNext P90D (:3255).
- The
status property allows only Active, Expired, In negotiation (:3428-3434). No contract can hold Actief, so the filter matches nothing.
- The subject uses
{{contractNummer}} and {{eindDatum}} (:3262-3263). The schema's fields are contractNumber and endDate; there is no contractNummer or eindDatum property, so even a matching contract would get a subject with empty placeholders.
- The Contracts page quick filter "Expiring / expired" (
src/manifest.json:527 page) is the only other expiry surface the matrix cites, and it filters on Expired only, so no page lists contracts that are about to expire.
Approval not enforced:
status (:3428) has no readOnly or hideOnForm, so it is editable in the generic create and edit form of the Contracts page (src/manifest.json:527).
approvalState comes from the overlay lib/Settings/register.d/contracts-to-decidesk.json:14 (merged by SettingsService.php:1653-1658). It is not readOnly either, although its own description says it is a projection of the decidiq outcome and that stackiq never sets Active on its own authority.
- The only code path that sets Active is
lib/Service/ContractApprovalService.php:432-437, on an approved outcome.
- The declared
x-openregister-lifecycle on the same schema (:3531-3560) uses In onderhandeling, Actief and Verlopen, which match none of the enum values, so it offers no transition either.
Why it matters
Admins get no warning before a contract lapses, and the contract approval workflow can be skipped by typing a status into a form, which undermines the audit value of the decidiq approval.
Needs a live check
Code reading. Whether OpenRegister dispatches scheduled notifications at all is outside this repo; the filter mismatch holds regardless.
Surfaced by the capability matrix in stackiq#1072 (merge 38b9938), rows ctr-expiry-alert and ctr-approval.
What goes wrong
The contract-expiry warning can never fire, because it filters on a status value no contract can have. Separately, the rule that a contract only becomes Active after an approved decision is not enforced: anyone who can edit a contract can set it to Active in the form.
Evidence, re-read at c9760e0
Expiry warning,
lib/Settings/softwarecatalogus_register.json:3252-3265(catalogContract,x-openregister-notifications.contract-expiry):"status": {"operator": "equals", "value": "Actief"}together withendDate withinNext P90D(:3255).statusproperty allows onlyActive,Expired,In negotiation(:3428-3434). No contract can holdActief, so the filter matches nothing.{{contractNummer}}and{{eindDatum}}(:3262-3263). The schema's fields arecontractNumberandendDate; there is nocontractNummeroreindDatumproperty, so even a matching contract would get a subject with empty placeholders.src/manifest.json:527page) is the only other expiry surface the matrix cites, and it filters onExpiredonly, so no page lists contracts that are about to expire.Approval not enforced:
status(:3428) has noreadOnlyorhideOnForm, so it is editable in the generic create and edit form of the Contracts page (src/manifest.json:527).approvalStatecomes from the overlaylib/Settings/register.d/contracts-to-decidesk.json:14(merged bySettingsService.php:1653-1658). It is notreadOnlyeither, although its own description says it is a projection of the decidiq outcome and that stackiq never sets Active on its own authority.lib/Service/ContractApprovalService.php:432-437, on anapprovedoutcome.x-openregister-lifecycleon the same schema (:3531-3560) usesIn onderhandeling,ActiefandVerlopen, which match none of the enum values, so it offers no transition either.Why it matters
Admins get no warning before a contract lapses, and the contract approval workflow can be skipped by typing a status into a form, which undermines the audit value of the decidiq approval.
Needs a live check
Code reading. Whether OpenRegister dispatches scheduled notifications at all is outside this repo; the filter mismatch holds regardless.
Surfaced by the capability matrix in stackiq#1072 (merge 38b9938), rows
ctr-expiry-alertandctr-approval.