⚠️ OpenSpec-managed issue — this content is automatically synced
from the openspec/ directory. Manual edits will be overwritten on next sync.
Artifacts
Summary
softwarecatalog owns a contract schema and a top-level Contracts nav
group (manifest pages Contracten index + ContractDetail detail). The
contract schema carries a status enum Actief / Verlopen / In onderhandeling
("Active / Expired / In negotiation"). The transition In onderhandeling
→ Actief is an approval / sign-off decision: a human or governance body
deciding the contract terms are agreed and the contract may take effect. The
same is true for a renewal (re-approving an expiring contract).
Per cross-app interface contract #1, decidesk is the canonical decision
authority and its hub is merged: a consuming app raises a Decision via the
ADR-019 integration registry (POST /api/v1/decisions with
decisionType: contract / contract-renewal + provenance fields) and
consumes the outcome (GET /api/v1/decisions/{id}/outcome, or a
push subscription), keeping its own domain record as a projection of that
outcome. softwarecatalog must NOT own a parallel approval/sign-off surface.
This change draws the boundary precisely:
- Stays in softwarecatalog (contract RECORD / catalog metadata): the
contract schema and its fields (dienst, gebruik, startDatum,
eindDatum, contractNummer, contractType, kosten, kostenPeriode,
contactpersoonAanbieder/Gebruiker, documentReferentie, opmerkingen),
the Contracten index + ContractDetail pages, and the catalog need to
know which contract governs which software/gebruik/dienst. The catalog
must federate and export contracts with the rest of the GEMMA/VNG data model.
- Delegated to decidesk (contract APPROVAL / sign-off / renewal DECISION):
the act of approving an In onderhandeling contract into Actief, and the
act of approving a renewal of an expiring contract. softwarecatalog raises a
decidesk Decision and projects the outcome back onto the contract record;
it never flips status to Actief on its own authority.
The status field becomes a projection of the decidesk outcome for the
approval transitions, plus the date-driven Actief → Verlopen expiry
transition (which is NOT a decision and stays catalog-local).
Specs
Tasks
Design
See design.md for technical design details.
Synced from openspec/changes/archive/2026-06-15-softwarecatalog-contracts-to-decidesk by OpenSpec workflow
App: stackiq
Artifacts
Summary
softwarecatalog owns a
contractschema and a top-level Contracts navgroup (manifest pages
Contractenindex +ContractDetaildetail). Thecontract schema carries a
statusenumActief / Verlopen / In onderhandeling("Active / Expired / In negotiation"). The transition
In onderhandeling→
Actiefis an approval / sign-off decision: a human or governance bodydeciding the contract terms are agreed and the contract may take effect. The
same is true for a renewal (re-approving an expiring contract).
Per cross-app interface contract #1, decidesk is the canonical decision
authority and its hub is merged: a consuming app raises a Decision via the
ADR-019 integration registry (
POST /api/v1/decisionswithdecisionType: contract/contract-renewal+ provenance fields) andconsumes the outcome (
GET /api/v1/decisions/{id}/outcome, or apush subscription), keeping its own domain record as a projection of that
outcome. softwarecatalog must NOT own a parallel approval/sign-off surface.
This change draws the boundary precisely:
contractschema and its fields (dienst,gebruik,startDatum,eindDatum,contractNummer,contractType,kosten,kostenPeriode,contactpersoonAanbieder/Gebruiker,documentReferentie,opmerkingen),the
Contractenindex +ContractDetailpages, and the catalog need toknow which contract governs which software/
gebruik/dienst. The catalogmust federate and export contracts with the rest of the GEMMA/VNG data model.
the act of approving an
In onderhandelingcontract intoActief, and theact of approving a renewal of an expiring contract. softwarecatalog raises a
decidesk Decision and projects the outcome back onto the contract record;
it never flips
statustoActiefon its own authority.The
statusfield becomes a projection of the decidesk outcome for theapproval transitions, plus the date-driven
Actief → Verlopenexpirytransition (which is NOT a decision and stays catalog-local).
Specs
Tasks
lib/Settings/register.d/*.jsonadd to thecontractschema:approvalStateis a PROJECTION of theContractDetailpageContractennav entry, thelib/Repair/*idempotent, fail-safe step backfillscd softwarecatalog && openspec validate softwarecatalog-contracts-to-decidesk --strictpasses.Design
See design.md for technical design details.
Synced from
openspec/changes/archive/2026-06-15-softwarecatalog-contracts-to-decideskby OpenSpec workflowApp:
stackiq