Skip to main content

Decidesk — Architecture & Data Model

1. Overview

Decidesk is a universal decision-making platform for Nextcloud, built as a thin client on OpenRegister. It manages meetings, agendas, motions, amendments, voting, minutes, and decision tracking with configurable workflows. Decidesk covers five governance domains: legislative bodies (municipal councils, provincial states), associations (ALV, boards), corporate governance (AGM, supervisory boards), corporate operations (management teams, steering committees), and citizen participation (citizens' assemblies, referenda).

Architecture Pattern

+------------------------------------------------------------+
| Decidesk Frontend (Vue 2 + Pinia) |
| - Organization & body management |
| - Meeting calendar & agenda builder |
| - Decision lifecycle & state machine visualization |
| - Motion & amendment editor (Akoma Ntoso-inspired) |
| - Voting & ballot collection (configurable methods) |
| - Resolution register |
| - Minutes editor & approval workflow |
| - Process template designer (Symfony Workflow YAML) |
| - Admin settings |
+---------------------------+--------------------------------+
| REST API calls
+---------------------------v--------------------------------+
| OpenRegister API |
| /api/objects/{register}/{schema}/{id} |
| - CRUD operations |
| - Search, pagination, filtering |
| - Symfony Workflow state transitions |
+---------------------------+--------------------------------+
|
+---------------------------v--------------------------------+
| OpenRegister Storage (PostgreSQL) |
| - JSON object storage |
| - Schema validation |
+------------------------------------------------------------+

Decidesk owns no database tables. All data is stored as OpenRegister objects, defined by schemas in a dedicated register. State machine logic is driven by Symfony Workflow definitions stored as ProcessTemplate objects.

2. Standards Research

Before defining our data model, we evaluated standards across four categories: semantic web, legislative/parliamentary, Dutch legal, and workflow/process.

2.1 Standards Evaluated

StandardTypeCoverageMaturityRelevance
Schema.org Event/Action/VoteActionInternationalEvent, Organization, VoteAction, CreativeWorkVery matureHIGH — primary vocabulary for meetings, voting, documents
Akoma Ntoso / LegalDocMLOASISDebate, motion, amendment, resolution, vote, speechMature (OASIS v1.0)HIGH — defines document structure for legislative acts
BPMN 2.0ISOProcess modeling, gateways, events, pools/lanesVery mature (ISO 19510)MEDIUM — inspiration for visualization, but Symfony Workflow replaces full engine
DMN 1.xOMGDecision tables, hit policies, FEEL expressionsMatureMEDIUM — inspiration for configurable voting rules (quorum, majority)
Awb / Gemeentewet / BW Boek 2Dutch lawBesluit requirements, quorum, voting, secret ballotBinding lawHIGH — non-negotiable legal requirements for valid decisions
OpenRaadsinformatie (ORI)Dutch open dataCouncil events, agenda items, motions, votes, personsActive (265/345 municipalities)HIGH — API compatibility for Dutch council systems
ELIEuropeanLegislation identification via HTTP URIs, metadata ontologyEU standardMEDIUM — cross-reference European legislation identifiers
MDTODutch govMetadata for durable accessible government informationForum StandaardisatieMEDIUM — archival metadata for decisions and minutes
Robert's Rules of OrderInternationalParliamentary procedure: motions, amendments, debate, voting order12th edition (2020)LOW — UX patterns for procedural flow, not a technical standard
Symfony Workflow ComponentPHP libraryState machine, guards, parallel states, event-driven auditStable (Symfony 7.x)HIGH — exact implementation technology for decision lifecycle

2.2 Design Principle: International First

Data storage uses international standards (Schema.org, Akoma Ntoso concepts). Dutch legal requirements are enforcement rules. Dutch open data standards (ORI) are an API mapping layer.

This means:

  • Objects in OpenRegister are modeled after Schema.org vocabulary for meetings, organizations, and actions
  • Document structure concepts follow Akoma Ntoso conventions for motions, amendments, and resolutions
  • Dutch legal requirements (Awb, Gemeentewet, BW Boek 2) are encoded as configurable rules in ProcessTemplate, not hardcoded into entities
  • When exposing ORI-compatible data, we map our international objects to Popolo/ORI field names
  • This makes Decidesk usable for any governance domain (corporate boards, associations, international bodies) while remaining interoperable with Dutch government systems

2.3 Key Findings

  1. Schema.org provides the primary vocabulary: Event for meetings, Organization for bodies, VoteAction for voting, CreativeWork for minutes and resolutions. Every entity carries a schema: type annotation for linked data compatibility.

  2. Akoma Ntoso (OASIS LegalDocML) defines the canonical structure for legislative and parliamentary documents. We adopt its conceptual model for motions (motion), amendments (amendment), and resolutions (resolution), but store as JSON in OpenRegister rather than XML. The hierarchical document structure (preface, preamble, body, conclusions) informs our text fields.

  3. Dutch legal requirements are non-negotiable system constraints:

    • Awb Art. 1:3: Decisions (besluiten) must be in writing with motivation
    • Gemeentewet Art. 20/29/30: Quorum >50%, absolute majority, tie-breaking, mandatory secret ballot for appointments
    • BW Boek 2 Art. 2:38/230/238: Configurable majority/quorum per statutes, written procedure requires unanimous consent to the method
    • Wet digitaal vergaderen: Permanent law enabling digital meetings for decentrale overheden (excludes secret meetings)
    • These are encoded as configurable rules in ProcessTemplate, not hardcoded — because each organization type has different requirements
  4. OpenRaadsinformatie (ORI) connects 265 of 345 Dutch municipalities. The Popolo-based data model (Event, AgendaItem, Motion, VoteEvent, Person) maps cleanly to our Schema.org entities. We provide ORI export capability for legislative domain users.

  5. Symfony Workflow Component is the implementation choice for decision state machines. It provides: YAML-based configuration (stored as ProcessTemplate objects), guard events for enforcing quorum/majority rules before transitions, audit trail via event listeners, and parallel states (a decision can be simultaneously "in committee A" and "in committee B"). This avoids the overhead of full BPMN engines (Camunda, Flowable) which are Java-based.

  6. DMN-inspired decision tables provide the pattern for configurable voting rules. Rather than implementing a full DMN engine, we use PHP decision tables that evaluate: quorum percentage, majority type (simple/absolute/qualified/unanimous), required roles per transition, time limits, and secret ballot requirements.

  7. MDTO (Metagegevens voor Duurzaam Toegankelijke Overheidsinformatie) provides the archival metadata standard. Decisions, resolutions, and minutes must carry MDTO-compliant metadata for transfer to permanent archives under the Archiefwet 2021 (10-year transfer period).

  8. ELI (European Legislation Identifier) provides the URI pattern for cross-referencing legislation. Resolutions that reference or implement EU directives can carry ELI identifiers for linked data interoperability.

  9. Market intelligence confirms strong demand: the board portal market is growing to $5-7B by 2030 (11-20% CAGR). Dutch RIS market leader Notubiz (50%+ share) is criticized as a "maze" by NOS Nieuwsuur. No competitor covers all 5 governance domains — council tools (GO, Notubiz) lack board governance; board portals (Diligent at $48-155K/year, OnBoard) lack legislative features; meeting tools (Fellow) lack formal voting. No self-hosted privacy-first alternative exists.

3. Data Model Decisions

3.1 Standards Hierarchy

We adopt a layered standards approach:

LayerStandardPurpose
Primary (storage)Schema.org + Akoma Ntoso conceptsInternational data model for meetings, decisions, documents
SemanticSchema.org JSON-LDType annotations for linked data
Legal enforcementAwb, Gemeentewet, BW Boek 2Configurable rules per organization type
API mappingOpenRaadsinformatie (Popolo)Dutch open data interoperability for legislative domain
ArchivalMDTO + Archiefwet 2021Long-term preservation metadata

3.2 Entity Definitions

Organization

The top-level governance entity. An organization defines the legal context in which decision-making bodies operate.

AspectDecisionRationale
Schema.org typeschema:OrganizationInternational standard for organizational entities
Domain typingFive governance domains from intelligence researchCovers all market segments identified in competitive analysis
Rules as configJSON configuration object, not hardcodedBW Boek 2 allows custom statutes; Gemeentewet has fixed rules — both via config

Core properties:

PropertyTypeSchema.orgAkoma NtosoRequiredDefault
namestringschema:nameTLCOrganization/@showAsYes--
typeenumschema:additionalType--Yes--
descriptionstringschema:description--No--
legalNamestringschema:legalName--No--
identifierstringschema:identifierTLCOrganization/@eIdNo--
kvkNumberstringschema:taxID--No--
addressobjectschema:address--No--
websitestringschema:url--No--
logostring (file ref)schema:logo--No--
defaultProcessTemplatereference----No--
rulesobject (JSON)----No{}
archivalPolicyobject----No--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Organization type values (from intelligence research — 5 domains, 92 stakeholder roles):

TypeDutchDomainLegal Framework
legislativeVolksvertegenwoordigingLegislative & Democratic BodiesGemeentewet, Provinciewet, Waterschapswet
associationVerenigingAssociations & NGOsBW Boek 2 Title 2, WBTR
corporate-governanceVennootschapsbestuurCorporate GovernanceBW Boek 2 Title 4-6, Corporate Governance Code
corporate-operationsBedrijfsorganisatieCorporate & Organisational OperationsInternal regulations, CAO
citizen-participationBurgerparticipatieCitizen & Public ParticipationGemeentewet Art. 150, Omgevingswet

Body

A specific decision-making body within an organization. A municipality has a council, committees, and college; a company has an AGM, supervisory board, and management team.

AspectDecisionRationale
Schema.org typeschema:Organization (subOrganization)Bodies are sub-organizations of the parent
HierarchyBodies can have parent bodies (committee under council)Gemeentewet committees; corporate sub-committees
Configurable rulesQuorum, voting method, majority type per bodyBW Boek 2 allows statutes to specify per body; Gemeentewet has fixed rules per body type

Core properties:

PropertyTypeSchema.orgORI MappingRequiredDefault
namestringschema:nameOrganization.nameYes--
typeenumschema:additionalTypeOrganization.classificationYes--
organizationreferenceschema:parentOrganization--Yes--
parentBodyreferenceschema:subOrganization (inverse)Organization.parent_idNo--
descriptionstringschema:descriptionOrganization.descriptionNo--
quorumRuleobject----No{"type": "percentage", "value": 50}
votingMethodenum----Noshow_of_hands
defaultMajorityenum----Nosimple
meetingFrequencystring (RRULE)schema:eventSchedule--No--
membersarray (user UIDs)schema:memberMembership.person_idNo[]
chairstring (user UID)schema:employee--No--
secretarystring (user UID)----No--
processTemplatereference----No--
isActiveboolean----Notrue
startDatedateschema:foundingDateOrganization.start_dateNo--
endDatedateschema:dissolutionDateOrganization.end_dateNo--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Body type values:

TypeDutchTypical OrganizationLegal Basis
councilRaadLegislativeGemeentewet Art. 7
committeeCommissieLegislative, AssociationGemeentewet Art. 82-84
executiveCollege / Dagelijks BestuurLegislativeGemeentewet Art. 34
boardBestuurAssociation, CorporateBW 2:37, 2:291
general_assemblyALV / AVAAssociation, CorporateBW 2:38, 2:217
supervisory_boardRaad van CommissarissenCorporateBW 2:250, Corporate Governance Code
management_teamManagementteamCorporate OperationsInternal regulations
steering_committeeStuurgroepCorporate OperationsInternal regulations
citizens_assemblyBurgerberaadCitizen ParticipationGemeentewet Art. 150
advisory_boardAdviesraadAll domainsVarious

Voting method values:

MethodDutchDescriptionLegal Reference
show_of_handsHandopstekingVisual count, default for most bodiesGemeentewet Art. 32
roll_callHoofdelijke stemmingNamed vote, recorded per memberGemeentewet Art. 32 lid 2
secret_ballotGeheime stemmingMandatory for appointmentsGemeentewet Art. 31
electronicElektronischDigital voting with audit trailWet digitaal vergaderen
written_procedureSchriftelijke rondeDecision outside meetingBW 2:238
acclamationAcclamatieUnanimous consent without formal voteParliamentary convention
weightedGewogen stemmingVotes weighted by shares/seatsBW 2:228

Majority type values:

TypeDutchThresholdUse Case
simpleGewone meerderheid>50% of votes castDefault for most decisions
absoluteVolstrekte meerderheid>50% of all membersGemeentewet Art. 30
qualifiedGekwalificeerde meerderheid2/3 of votes castStatute amendments (BW 2:42)
unanimousUnanimiteit100% of votes castWritten procedure consent (BW 2:238)
relativeRelatieve meerderheidMost votes winsElections with multiple candidates

Meeting

A scheduled gathering of a body for deliberation and decision-making.

AspectDecisionRationale
Schema.org typeschema:EventInternational standard for scheduled events
ORI mappingEvent (Popolo)Dutch open data compatibility
Calendar syncCalDAV event via OCP\Calendar\IManagerMeetings appear in Nextcloud Calendar
Status machineSymfony Workflow: draft -> convened -> in_progress -> adjourned -> completed -> minutes_approvedFormal lifecycle required by law

Core properties:

PropertyTypeSchema.orgORI MappingRequiredDefault
namestringschema:nameEvent.nameYes--
bodyreferenceschema:organizerEvent.organization_idYes--
statusenumschema:eventStatusEvent.statusYesdraft
scheduledStartdatetimeschema:startDateEvent.start_dateNo--
scheduledEnddatetimeschema:endDateEvent.end_dateNo--
actualStartdatetime----No--
actualEnddatetime----No--
locationstringschema:locationEvent.locationNo--
isDigitalboolean----Nofalse
digitalMeetingUrlstringschema:url--No--
chairstring (user UID)--Event.chair_idNo--
secretarystring (user UID)----No--
attendeesarray (user UIDs)schema:attendeeEventAttendeeNo[]
absenteesarray (user UIDs)----No[]
quorumPresentinteger----No--
quorumMetboolean----No--
convocationDatedatetime----No--
convocationDocumentsarray (file refs)----No[]
calendarEventUidstring----No--
talkTokenstring----No--
numberinteger----No--
seriesstring----No--
createdAtdatetimeschema:dateCreatedEvent.created_atAuto--
updatedAtdatetimeschema:dateModifiedEvent.updated_atAuto--

Meeting status values:

StatusDutchDescriptionLegal Significance
draftConceptMeeting being planned, not yet announced--
convenedBijeengeroepenConvocation sent, agenda publishedGemeentewet Art. 19: min 2 days notice
in_progressLopendMeeting is activeQuorum must be verified (Gemeentewet Art. 20)
adjournedGeschorstTemporarily suspendedChair may adjourn (Gemeentewet Art. 26)
completedAfgelopenMeeting ended, minutes pending--
minutes_approvedNotulen vastgesteldMinutes approved by bodyOfficial record complete
cancelledGeannuleerdMeeting cancelled before occurrence--

AgendaItem

An item on a meeting's agenda. Agenda items structure the meeting flow and can reference decisions, motions, or informational topics.

AspectDecisionRationale
Schema.org typeschema:Event (part of meeting)Sub-event within parent meeting
ORI mappingAgendaItem (Popolo)Dutch open data compatibility
Drag-and-drop orderingorder integer fieldIndustry standard for agenda management

Core properties:

PropertyTypeSchema.orgORI MappingRequiredDefault
meetingreferenceschema:superEventAgendaItem.event_idYes--
titlestringschema:nameAgendaItem.nameYes--
descriptionstringschema:descriptionAgendaItem.descriptionNo--
orderintegerschema:positionAgendaItem.positionYes0
durationinteger (minutes)schema:duration--No--
typeenumschema:additionalType--Yesdiscussion
statusenum----Yespending
presenterstring (user UID)schema:performer--No--
decisionreference----No--
documentsarray (file refs)schema:associatedMediaAgendaItem.media_urlsNo[]
parentItemreference--AgendaItem.parent_idNo--
speakingTimeinteger (minutes)----No--
notesstring----No--
outcomestring----No--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Agenda item type values:

TypeDutchDescription
openingOpeningMeeting opening, attendance, quorum check
approval_minutesVaststelling notulenApproval of previous meeting's minutes
approval_agendaVaststelling agendaApproval of current agenda
informationInformatie / MededelingenInformational item, no decision required
discussionBesprekingDiscussion item, may lead to decision
decisionBesluitDecision item with linked Decision entity
question_hourVragenuurQuestion time (legislative bodies)
interpellationInterpellatieFormal questioning of executive (legislative)
round_tableRondvraagClosing round of questions
closingSluitingMeeting closing

Agenda item status values:

StatusDutchDescription
pendingGeplandNot yet discussed
activeIn behandelingCurrently being discussed
completedAfgehandeldDiscussion completed
deferredUitgesteldDeferred to future meeting
withdrawnIngetrokkenWithdrawn from agenda

Decision-maker model: Person, Membership, Post, ContactDetail

Cycle-1 refactor (C2 popolo-decision-makers): The Popolo decision-maker model is now the implemented standard. The flat Participant schema is DEPRECATED — a compatibility shim is retained for quorum/voting only; removal is tracked as the retire-participant-shim change.

EntityPopolo equivalentRole
Personpopolo:PersonIdentity record for an individual (name, birthdate, image, email). Board disclosure fields: nationality as beyond-Popolo extension.
Membershippopolo:MembershipRelationship between a Person and a GovernanceBody, with role, time bounds, voting weight. Board disclosure fields: independenceStatus, otherPositions as beyond-Popolo extensions.
Postpopolo:PostA formal position within a body (Chair, Secretary, Treasurer) that a Membership fills.
ContactDetailpopolo:ContactDetailTyped, multi-value contact channels for a Person or GovernanceBody.

ORI /persons and /memberships now serve real Popolo objects. Person.email is exposed as a top-level convenience field (full contacts via ContactDetail).

Decision

The universal supertype for all formal decisions (ADR-005, Cycle-1 refactor 2026-06-14). decisionType is a required discriminator replacing the former separate Motion, Amendment, and Resolution schemas. ORI/Popolo compatibility is preserved at the serialization layer: /api/ori/v1/motions sources decisionType=motion decisions.

AspectDecisionRationale
Schema.org typeschema:Action + schema:VoteActionAction with voting outcome
Akoma Ntosobill / decision / actLegislative document lifecycle
State machineSymfony Workflow (configurable per ProcessTemplate)Different domains have different approval chains
Awb complianceWritten form + motivation fieldsAwb Art. 1:3 / 3:46 requirements
decisionType valuesmotion, amendment, resolution, contract, appointment, management-point, policy, meeting-outcomeRequired discriminator (ADR-005); replaces separate schema per type

Core properties:

PropertyTypeSchema.orgAkoma NtosoRequiredDefault
titlestringschema:namepreface/docTitleYes--
decisionTypeenum----Yes--
descriptionstringschema:descriptionpreambleNo--
bodyreferenceschema:agent--Yes--
statusenumschema:actionStatuslifecycle/@sourceYesdraft
categorystringschema:category--No--
proposerstring (user UID)schema:creatorpreface/docProponentNo--
coProposersarray (user UIDs)----No[]
motivationstring (rich text)--preamble/recitalsNo--
legalBasisstring--citationsNo--
requiredMajorityenum----Nosimple
resultenum----No--
dossierFolderstring (file ref)----No--
processTemplatereference----No--
currentWorkflowPlacestring----Nodraft
workflowHistoryarray (objects)----No[]
relatedDecisionsarray (references)schema:isRelatedToreferencesNo[]
dueDatedateschema:deadline--No--
priorityenum----Nonormal
tagsarray (strings)schema:keywords--No[]
mdtoClassificationstring----No--
archivalDatedate----No--
numberstring--docNumberNo--
publicationDatedate----No--
effectiveDatedate----No--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Decision status values (default workflow — configurable per ProcessTemplate):

StatusDutchDescriptionAwb Relevance
draftConceptBeing drafted by proposer--
submittedIngediendSubmitted for consideration--
agendaGeagendeerdPlaced on meeting agenda--
committeeIn commissieBeing considered by committee(s)Awb Art. 3:9 (advisory)
debatedBesprokenDebated in plenary/full body--
votedGestemdVote completed, result pending formal declaration--
approvedAangenomenApproved by required majorityAwb Art. 1:3 (besluit)
rejectedVerworpenRejected by vote--
deferredAangehoudenPostponed to future meeting--
implementedUitgevoerdDecision has been executed--
archivedGearchiveerdTransferred to archiveArchiefwet 2021

Decision result values:

ResultDutchDescription
approvedAangenomenPassed by required majority
rejectedVerworpenFailed to achieve required majority
withdrawnIngetrokkenWithdrawn by proposer before vote
deferredAangehoudenPostponed, no vote taken
amended_approvedGeamendeerd aangenomenApproved with amendments

Motion

RETIRED (ADR-005, Cycle-1 refactor 2026-06-14): Motion is no longer a separate schema. Use Decision with decisionType=motion. The documentation below is kept for historical reference. ORI /api/ori/v1/motions continues to serve motion-type decisions for backwards compatibility.

A formal proposal for a decision, following Akoma Ntoso's motion concept. Motions can be standalone (requesting action) or attached to a decision (proposing specific text).

AspectDecisionRationale
Schema.org typeschema:ActionProposed action
Akoma NtosomotionOASIS standard for parliamentary motions
Robert's RulesMain motion, subsidiary motion, privileged motionProcedural classification
GemeentewetArt. 33: moties, Art. 147a: amendementLegal basis for council motions

Core properties:

PropertyTypeSchema.orgAkoma NtosoRequiredDefault
titlestringschema:namepreface/docTitleYes--
textstring (rich text)schema:textbody/mainBodyYes--
decisionreferenceschema:object--No--
bodyreferenceschema:agent--Yes--
typeenumschema:additionalType--Nosubstantive
proposerstring (user UID)schema:creatorpreface/docProponentYes--
coSignersarray (user UIDs)----No[]
secondedBystring (user UID)----No--
statusenum----Yesdraft
votingResultenum----No--
requestsActionstring--conclusionsNo--
addressedTostring----No--
deadlinedate----No--
meetingreference----No--
agendaItemreference----No--
documentsarray (file refs)schema:associatedMedia--No[]
numberstring--docNumberNo--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Motion type values:

TypeDutchDescriptionRobert's Rules Equivalent
substantiveMotieRequest for action from executiveMain motion
orderMotie van ordeProcedural motion about meeting conductPrivileged motion
censureMotie van wantrouwenVote of no confidence--
amendmentAmendementTextual change to a decision (see Amendment entity)Subsidiary motion (amend)
resolutionResolutieStatement of position without binding actionResolution

Motion status values:

StatusDutchDescription
draftConceptBeing drafted
submittedIngediendFormally submitted
secondedOndersteundSeconded by another member
debatedBesprokenUnder debate
votedGestemdVote completed
adoptedAangenomenPassed
rejectedVerworpenFailed
withdrawnIngetrokkenWithdrawn by proposer

Amendment

RETIRED (ADR-005, Cycle-1 refactor 2026-06-14): Amendment is no longer a separate schema. Use Decision with decisionType=amendment. The documentation below is kept for historical reference.

A proposed textual change to a motion or decision. Follows Akoma Ntoso's amendment pattern with explicit change tracking.

AspectDecisionRationale
Akoma Ntosoamendment / amendmentBodyOASIS standard for textual modifications
GemeentewetArt. 147aLegal basis for council amendments
Voting orderAmendments voted before main motionRobert's Rules: most distant amendment first

Core properties:

PropertyTypeSchema.orgAkoma NtosoRequiredDefault
titlestringschema:namepreface/docTitleYes--
textstring (rich text)schema:textamendmentBodyYes--
motionreference--references/activeRefNo--
decisionreference----No--
bodyreferenceschema:agent--Yes--
typeenum----Notextual
proposerstring (user UID)schema:creatorpreface/docProponentYes--
coSignersarray (user UIDs)----No[]
statusenum----Yesdraft
votingResultenum----No--
originalTextstring--mod/quotedText (old)No--
proposedTextstring--mod/quotedText (new)No--
changeTypeenum--mod/@typeNosubstitution
meetingreference----No--
agendaItemreference----No--
orderinteger----No0
documentsarray (file refs)----No[]
numberstring--docNumberNo--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Amendment change type values (Akoma Ntoso mod types):

TypeDutchDescription
substitutionVervangingReplace existing text
insertionToevoegingInsert new text
deletionSchrappingRemove existing text
renumberingHernummeringChange article/section numbering

Amendment status values: Same as Motion status values.

Vote

A voting round on a decision, motion, or amendment. Captures the procedural context of a vote: method, quorum, timing, and aggregate result.

AspectDecisionRationale
Schema.org typeschema:VoteActionInternational standard for voting
ORI mappingVoteEvent (Popolo)Dutch open data compatibility
Subject polymorphismReferences decision, motion, or amendmentAll three can be voted on
Quorum enforcementChecked before vote starts (guard event)Gemeentewet Art. 20: quorum mandatory

Core properties:

PropertyTypeSchema.orgORI MappingRequiredDefault
subjectreferenceschema:objectVoteEvent.motion_idYes--
subjectTypeenum: decision, motion, amendment----Yes--
bodyreferenceschema:agentVoteEvent.organization_idYes--
meetingreference--VoteEvent.event_idNo--
agendaItemreference----No--
methodenum----Yesshow_of_hands
majorityRequiredenum----Nosimple
quorumRequiredinteger----No--
quorumPresentinteger----No--
quorumMetboolean----No--
resultenum--VoteEvent.resultNo--
votesForinteger--VoteEvent.countsNo0
votesAgainstinteger--VoteEvent.countsNo0
votesAbstaininteger--VoteEvent.countsNo0
votesBlankinteger----No0
totalVotesinteger----No0
startTimedatetimeschema:startTimeVoteEvent.start_dateNo--
endTimedatetimeschema:endTimeVoteEvent.end_dateNo--
isSecretboolean----Nofalse
tieBreakerstring----No--
remarksstring----No--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Vote result values:

ResultDutchDescription
passedAangenomenRequired majority achieved
failedVerworpenRequired majority not achieved
tiedStaken der stemmenTied vote (Gemeentewet Art. 30 applies)
invalidatedOngeldigVote invalidated (quorum lost, procedural error)
deferredUitgesteldVote deferred (Gemeentewet Art. 30: tied vote on next meeting)

Ballot

An individual vote cast by a member. For secret ballots, the voter field is null and ballots are anonymized.

AspectDecisionRationale
Schema.org typeschema:VoteAction (individual)Individual voting action
ORI mappingVote (Popolo)Individual vote record
Secret ballotVoter field null when isSecret=true on parent VoteGemeentewet Art. 31: secret ballot for appointments
Weighted votingweight field for share-weighted votesBW 2:228: votes proportional to share ownership

Core properties:

PropertyTypeSchema.orgORI MappingRequiredDefault
votereferenceschema:objectVote.vote_event_idYes--
voterstring (user UID)schema:agentVote.voter_idNo--
choiceenumschema:actionOptionVote.optionYes--
weightnumber--Vote.weightNo1
groupstring--Vote.group_idNo--
delegatedBystring (user UID)----No--
timestampdatetimeschema:startTime--Auto--
isProxyboolean----Nofalse
remarksstring----No--
createdAtdatetimeschema:dateCreated--Auto--

Ballot choice values:

ChoiceDutchDescription
forVoorIn favor
againstTegenOpposed
abstainOnthoudingAbstaining from vote
blankBlancoBlank vote (secret ballot only)
invalidOngeldigInvalid ballot (secret ballot only)

Resolution

RETIRED (ADR-005, Cycle-1 refactor 2026-06-14): Resolution is no longer a separate schema. Use Decision with decisionType=resolution. The documentation below is kept for historical reference. In mode=corp, resolutions appear as Decision objects with decisionType=resolution; the corporate experience is served by mode-adaptation (ADR-006), not a parallel schema.

The formal output of an approved decision. Resolutions are the official, published acts that result from the decision-making process.

AspectDecisionRationale
Schema.org typeschema:LegislationLegislation/act type
Akoma Ntosoact / decisionOASIS standard for enacted legislation
ELIURI-based identificationEuropean cross-reference for legislation
AwbArt. 1:3 (besluit), Art. 3:40 (bekendmaking)Must be written, motivated, published

Core properties:

PropertyTypeSchema.orgAkoma NtosoRequiredDefault
titlestringschema:namepreface/docTitleYes--
textstring (rich text)schema:textbody/mainBodyYes--
decisionreferenceschema:isBasedOn--Yes--
bodyreferenceschema:creator--Yes--
numberstringschema:legislationIdentifierdocNumberNo--
dateAdopteddateschema:dateCreatedFRBRdate/@dateYes--
effectiveDatedateschema:legislationDate--No--
expirationDatedateschema:expires--No--
signatoriesarray (user UIDs)schema:accountablePersonconclusions/signatureNo[]
motivationstring (rich text)--preamble/recitalsNo--
legalBasisstring--preamble/citationsNo--
publicationDatedate----No--
publicationMediumstring----No--
eliUristring----No--
mdtoMetadataobject----No--
supersedesreference--references/passiveRefNo--
supersededByreference----No--
documentsarray (file refs)schema:associatedMedia--No[]
statusenum----Yesactive
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Resolution status values:

StatusDutchDescription
activeActiefCurrently in force
supersededVervangenReplaced by newer resolution
repealedIngetrokkenFormally repealed
expiredVerlopenExpired by its own terms
archivedGearchiveerdTransferred to permanent archive

Minutes

The official record of a meeting. Minutes capture attendance, agenda items discussed, decisions taken, and action items assigned.

AspectDecisionRationale
Schema.org typeschema:CreativeWorkWritten document
Akoma Ntosodebate / debateReportParliamentary debate record structure
GemeentewetArt. 23: minutes must be keptLegal requirement for council meetings
Approval flowdraft -> review -> approvedMinutes must be formally approved

Core properties:

PropertyTypeSchema.orgAkoma NtosoRequiredDefault
meetingreferenceschema:about--Yes--
titlestringschema:namepreface/docTitleNoAuto-generated
textstring (rich text)schema:textdebateBodyNo--
statusenum----Yesdraft
authorstring (user UID)schema:author--No--
attendeesarray (user UIDs)schema:attendee--No[]
absenteesarray (user UIDs)----No[]
approvedByreference (body)----No--
approvedDatedate----No--
approvalMeetingreference----No--
actionItemsarray (objects)----No[]
correctionsarray (objects)----No[]
documentsarray (file refs)schema:associatedMedia--No[]
mdtoMetadataobject----No--
transcriptSourceenum----No--
createdAtdatetimeschema:dateCreated--Auto--
updatedAtdatetimeschema:dateModified--Auto--

Minutes status values:

StatusDutchDescription
draftConceptBeing written/edited
reviewTer inzagePublished for review by members
approvedVastgesteldFormally approved by the body
correctedGecorrigeerdApproved with corrections

Action item structure (embedded object, not separate entity):

PropertyTypeRequired
descriptionstringYes
assignedTostring (user UID)No
dueDatedateNo
statusenum: open, in_progress, completedYes
taskUidstring (Nextcloud Tasks ref)No

ProcessTemplate

A configurable decision process definition using Symfony Workflow YAML structure. Templates encode the complete state machine for a decision lifecycle, including states, transitions, guards (quorum/majority rules), and role requirements.

AspectDecisionRationale
TechnologySymfony Workflow ComponentPHP-native state machine with guards, parallel states, audit trail
StorageJSON in OpenRegister (YAML-equivalent structure)Configurable per organization/body without code changes
DMN-inspiredDecision tables for voting rulesConfigurable quorum/majority without full DMN engine overhead

Core properties:

PropertyTypeRequiredDefault
namestringYes--
descriptionstringNo--
organizationreferenceNo--
bodyreferenceNo--
typeenumYesstate_machine
initialPlacestringYesdraft
placesarray (objects)Yes--
transitionsarray (objects)Yes--
rulesobjectNo{}
isDefaultbooleanNofalse
isActivebooleanNotrue
versionintegerNo1
createdAtdatetimeAuto--
updatedAtdatetimeAuto--

Place (state) structure (embedded object):

PropertyTypeDescription
namestringMachine name (e.g., draft, voted)
labelstringDisplay name
labelNlstringDutch display name
colorstring (hex)Visual indicator
isFinalbooleanTerminal state
metadataobjectCustom metadata

Transition structure (embedded object):

PropertyTypeDescription
namestringTransition name (e.g., submit, approve)
labelstringDisplay name
labelNlstringDutch display name
fromstring or arraySource place(s)
tostringTarget place
guardobjectGuard rules (evaluated before transition)
requiredRolesarrayRoles that may trigger this transition
notificationTemplatestringNotification on transition

Guard rules structure (DMN-inspired decision table):

PropertyTypeDescription
quorumRequiredbooleanMust quorum be met?
quorumPercentageintegerMinimum quorum %
majorityTypeenumRequired majority type
secretBallotbooleanForce secret ballot?
requiresSeconderbooleanMotion must be seconded?
minDebateTimeinteger (minutes)Minimum debate duration
requiresMotivationbooleanDecision must include motivation?
customConditionsarrayAdditional PHP-evaluable conditions

Default legislative template (Gemeentewet-compliant):

PlaceTransitions OutGuard
draftsubmitRequires proposer role
submittedagenda, reject, withdrawRequires clerk role for agenda
agendacommittee, debate, withdraw--
committeedebate, defer--
debatedvote, defer, withdraw--
votedapprove, rejectQuorum: 50%, Majority: absolute
approvedimplement--
rejected-- (final)--
deferredagenda--
implementedarchive--
archived-- (final)--

3.3 Status/Enum Values

All status enums are defined in entity sections above. Cross-entity summary:

Cycle-1 refactor (ADR-005): Motion, Amendment, and Resolution are no longer separate schemas. Their lifecycle statuses are now expressed as Decision statuses on the appropriate decisionType. The rows below are retained for historical reference.

EntityStatusesDefault
Meetingdraft, convened, in_progress, adjourned, completed, minutes_approved, cancelleddraft
AgendaItempending, active, completed, deferred, withdrawnpending
Decision (universal)draft, submitted, agenda, committee, debated, voted, approved, rejected, deferred, implemented, archiveddraft
Motion (retired)draft, submitted, seconded, debated, voted, adopted, rejected, withdrawndraft
Amendment (retired)draft, submitted, seconded, debated, voted, adopted, rejected, withdrawndraft
Vote(result enum) passed, failed, tied, invalidated, deferred--
Ballot(choice enum) for, against, abstain, blank, invalid--
Resolution (retired)active, superseded, repealed, expired, archivedactive
Minutesdraft, review, approved, correcteddraft

3.3b Retired Board-* Entities (ADR-006)

Cycle-1 refactor (C3 retire-board-portal, ADR-006): The parallel corporate "board portal" entity set was retired. The seven board-* schemas (Board, BoardMember, BoardMeeting, BoardVote, BoardMinutes, BoardMaterial, BoardAuditLogEntry) no longer exist. Corporate governance is now served by mode-adaptation of the universal entities with organisatie_modus=corp:

Former board-* entityNow expressed as
BoardGovernanceBody with bodyType=supervisory-board or bodyType=executive-board
BoardMeetingMeeting (universal)
BoardMemberPerson + Membership
BoardVoteVote (universal)
BoardMinutesMinutes (universal)
BoardMaterialDigitalDocument (universal)
BoardAuditLogEntryOR built-in auditTrail
Resolution (board sense)Decision with decisionType=resolution

Coupled governance features (eIDAS signing, conflict-of-interest, proxy voting, governance reporting, regulator export, multilingual reconciliation) were retargeted onto the unified entities, not removed.

3.4 Cross-App Relationships

Decidesk integrates with Procest (case management) and Docudesk (document generation) within the Conduction app ecosystem:

Decidesk (Decision-making)          Procest (Case Management)
+--------------------+ +--------------------+
| Organization | | |
| Body | | |
| Meeting | | |
| AgendaItem | | |
| Decision -------+-- implements +--> Case |
| Motion | | Task |
| Amendment | | |
| Vote / Ballot | | |
| Resolution ------+-- triggers +--> Case |
| Minutes | | |
| ProcessTemplate | | |
+--------------------+ +--------------------+
| |
| generates | generates
v v
+------------------------------------------------------------+
| Docudesk (Document Generation) |
| - Resolution PDFs (Akoma Ntoso-structured) |
| - Meeting convocations |
| - Minutes documents |
| - Decision notifications |
| - Voting certificates |
+------------------------------------------------------------+

Decision -> Case flow: An approved decision that requires execution can create a Procest case. The resolution, motivation, and dossier documents are linked to the case.

Resolution -> Document flow: Docudesk generates formal resolution documents following Akoma Ntoso structural conventions (preface, preamble, body, conclusions, signatures).

Minutes -> Document flow: Docudesk generates minutes documents from the structured minutes data, including attendance records, agenda items, and decision summaries.

3.5 Integration Strategy

REUSE from Nextcloud

FeatureOCP InterfaceWhat to ReuseHow
CalendarOCP\Calendar\IManagerMeeting schedule as CalDAV eventsCreate events for meetings. Expose meeting calendar via ICalendarProvider. Reference by event UID in calendarEventUid.
TasksOCP\Calendar\IManagerAction items from minutes as VTODOCreate tasks from minutes action items. Reference by task UID. Track completion state.
FilesOCP\Files\IRootFolderDossier documents per decision, agenda attachmentsAuto-create folder structure: Decidesk/{Body}/{Year}/{Decision-NR}/. Reference by file ID.
MailOCP\Mail\IMailerMeeting convocations, vote reminders, digest notificationsSend convocation emails with agenda. Link incoming emails to decisions via message-ID.
TalkOCP\Talk\IBrokerDeliberation channels per decision/bodyCreate conversation per decision for informal deliberation between meetings. Store token.
ContactsOCP\Contacts\IManagerMember/participant identity dataReference members by vCard UID. Lookup display names, roles, organizational membership.
ActivityOCP\Activity\IManagerAudit trail of decision lifecyclePublish events: "Decision submitted", "Vote completed", "Resolution adopted". Implement IProvider.
NotificationsOCP\Notification\IManagerState change alerts, vote remindersNotify on: meeting convened, vote starting, decision approved, action item assigned.

BUILD in OpenRegister (Decidesk-specific)

WhatWhy Not Reuse
Organizations & bodiesGovernance hierarchy with domain-specific rules (quorum, voting method, majority type)
MeetingsFormal meeting lifecycle with quorum enforcement, agenda management, attendance tracking
DecisionsConfigurable state machine with legal compliance requirements per domain
Motions & amendmentsLegislative document lifecycle with Akoma Ntoso-inspired structure
Votes & ballotsFormal voting with quorum checks, majority calculation, secret ballot support, weighted votes
ResolutionsFormal acts with legal publication requirements, ELI identifiers, archival metadata
MinutesStructured meeting records with approval workflow and action item tracking
Process templatesSymfony Workflow definitions configurable per organization/body

3.6 @conduction/nextcloud-vue Library

Decidesk uses shared components from @conduction/nextcloud-vue:

ComponentUsage in Decidesk
ObjectList / MagicTableList views for decisions, meetings, motions, resolutions
ObjectDetailDetail views for all entities with tab navigation
KanbanBoardDecision pipeline visualization (by workflow place)
TimelineViewDecision audit trail / workflow history
FormBuilderDynamic forms for motion text, amendment proposals
FileAttachmentsDossier document management on decisions
CommentThreadDiscussion threads on decisions and motions
UserPickerMember selection for bodies, proposer assignment
StatusBadgeDecision/meeting/motion status indicators
SearchBarFull-text search across all decision entities

3.7 Vue Router

Cycle-1 IA refactor (C7 ia-six-item-nav): The top-level navigation was restructured to ADR-004's 6-item IA. organisatie_modus (gov/corp/assoc/ops/citizen) drives per-mode label adaptation via src/config/modeLabels.js — e.g. Bodies renders as "Fracties & Organen" (gov), "Board" (corp), or "Teams" (ops); mode=corp relabels Decisions as "Resolutions". Minutes, Workspaces, and Engagement are demoted from top-level (routes retained).

Top-level navigation (6 items):

Nav itemRouteDescription
Dashboard/Landing: upcoming meetings, pending decisions, my votes, action items
Meetings/meetingsAll meetings (calendar + list toggle)
Decisions/decisionsAll decisions / mode=corp: Resolutions (decisionType discriminated)
Action items/action-itemsAction items from minutes, assigned to me or all
Motions/motionsDecision objects with decisionType=motion or amendment
Bodies/bodiesFracties & Organen / Board / Teams — mode-adapted label

All routes:

RouteViewDescription
/DashboardOverview: upcoming meetings, pending decisions, my votes, action items
/organizationsOrganizationListAll organizations
/organizations/:idOrganizationDetailOrganization with bodies, settings
/bodiesBodyListAll decision-making bodies (mode-adapted label)
/bodies/:idBodyDetailBody with members, meetings, decisions
/meetingsMeetingListAll meetings (calendar + list toggle)
/meetings/:idMeetingDetailMeeting with agenda, attendance, documents
/meetings/:id/agendaAgendaEditorDrag-and-drop agenda builder
/meetings/:id/liveLiveMeetingActive meeting view: current item, voting, timer
/decisionsDecisionListAll decisions (filterable by status, body, category, decisionType)
/decisions/:idDecisionDetailDecision with full lifecycle, dossier, votes
/decisions/:id/voteVotingViewActive voting interface
/motionsMotionListDecisions with decisionType=motion (mode label: Motions)
/motions/:idMotionDetailMotion decision with amendments, voting results
/minutesMinutesListAll minutes (demoted from top nav; route retained)
/minutes/:idMinutesEditorRich text editor with structured sections
/templatesTemplateListProcess template management
/templates/:idTemplateEditorVisual workflow editor
/settingsAdminSettingsApp configuration (includes organisatie_modus selector)

3.8 Nextcloud Integration Strategy

Principle: reuse Nextcloud native objects where possible, reference by ID, don't duplicate.

OpenRegister objects store governance-specific fields plus foreign keys (calendar event UID, task UID, file ID, user UID, Talk token) pointing to Nextcloud native entities. The PHP service layer uses OCP interfaces to read/write native data.

Key OCP Interfaces

// Calendar - create meeting events as CalDAV
$calendarManager = \OCP\Server::get(\OCP\Calendar\IManager::class);
$builder = $calendarManager->createEventBuilder(); // NC 31+
$builder->setSummary('Council Meeting #42')
->setDescription('Regular council meeting')
->setStartDate($meetingStart)
->setEndDate($meetingEnd)
->setLocation('Council Chamber');
$eventUid = $builder->createInCalendar($calendarId);
// Store $eventUid on Meeting object for sync

// Calendar Provider - expose meetings as virtual calendar
use OCP\Calendar\ICalendarProvider;

class MeetingCalendarProvider implements ICalendarProvider {
public function getCalendars(
string $principalUri,
array $calendarUris = []
): array {
// Return virtual calendar with all meetings
// the user is invited to or is a member of the body
return [new MeetingCalendar($this->meetingService, $principalUri)];
}
}

// Tasks - create action items from minutes as VTODO
$calendarManager = \OCP\Server::get(\OCP\Calendar\IManager::class);
$taskBuilder = $calendarManager->createEventBuilder();
$taskBuilder->setSummary('Draft implementation plan for resolution 2024-42')
->setDueDate($dueDate)
->setStatus('NEEDS-ACTION');
$taskUid = $taskBuilder->createInCalendar($taskCalendarId);
// Store $taskUid in Minutes.actionItems[].taskUid

// Files - dossier folder structure per decision
$rootFolder = \OCP\Server::get(\OCP\Files\IRootFolder::class);
$userFolder = $rootFolder->getUserFolder($userId);
$dossierPath = "Decidesk/{$bodyName}/{$year}/{$decisionNumber}";
if (!$userFolder->nodeExists($dossierPath)) {
$userFolder->newFolder($dossierPath);
}
// Store folder path on Decision.dossierFolder

// Mail - send meeting convocation
$mailer = \OCP\Server::get(\OCP\Mail\IMailer::class);
$message = $mailer->createMessage();
$message->setTo($memberEmails);
$message->setSubject("Convocation: {$meeting->getName()} - {$meeting->getScheduledStart()->format('d-m-Y')}");
$template = $mailer->createEMailTemplate('decidesk.convocation');
$template->addHeader();
$template->addHeading($meeting->getName());
$template->addBodyText('You are invited to the following meeting:');
// Attach agenda items, documents
$message->useTemplate($template);
$mailer->send($message);

// Talk - create deliberation channel per decision
$broker = \OCP\Server::get(\OCP\Talk\IBroker::class);
$conversation = $broker->createConversation(
"Decision: {$decision->getTitle()}",
$bodyMemberUids
);
// Store $conversation->getToken() on Decision.talkToken

// Contacts - resolve member identity
$contactsManager = \OCP\Server::get(\OCP\Contacts\IManager::class);
$results = $contactsManager->search($userId, ['UID'], ['limit' => 1]);
// Use display name, organization, role from contact card

// Activity - audit trail for decision lifecycle
$activityManager = \OCP\Server::get(\OCP\Activity\IManager::class);
$event = $activityManager->generateEvent();
$event->setApp('decidesk')
->setType('decision_lifecycle')
->setAffectedUser($proposerUid)
->setSubject('decision_approved', [
'decision' => $decision->getTitle(),
'body' => $body->getName(),
'votes_for' => $vote->getVotesFor(),
'votes_against' => $vote->getVotesAgainst(),
])
->setObject('decision', $decision->getId(), $decision->getTitle());
$activityManager->publish($event);

// Notifications - state change alerts
$notificationManager = \OCP\Server::get(\OCP\Notification\IManager::class);
$notification = $notificationManager->createNotification();
$notification->setApp('decidesk')
->setUser($memberUid)
->setDateTime(new \DateTime())
->setObject('vote', (string)$vote->getId())
->setSubject('vote_starting', [
'decision' => $decision->getTitle(),
'body' => $body->getName(),
'method' => $vote->getMethod(),
]);
$notificationManager->notify($notification);

4. OpenRegister Configuration

Register

FieldValue
Namedecidesk
Slugdecidesk
DescriptionUniversal decision-making and governance register

Schema Definitions

Schemas MUST be defined in lib/Settings/decidesk_register.json using OpenAPI 3.0.0 format (not inline PHP), following the pattern used by opencatalogi and softwarecatalog.

Schemas (Cycle-1 state — ADR-005/006 applied):

  • organization — Governance body (schema:Organization)
  • body / governanceBody — Decision-making body within organization (schema:Organization subOrganization); bodyType values include supervisory-board, executive-board for corporate mode
  • meeting — Scheduled gathering (schema:Event); universal — serves both council and board meetings in mode=corp
  • agendaItem — Meeting agenda item (schema:Event part)
  • decision — Universal supertype for all formal decisions (schema:Action); required decisionType discriminator: motion, amendment, resolution, contract, appointment, management-point, policy, meeting-outcome
  • person — Individual identity (foaf:Person / Popolo:Person); replaces Participant
  • membership — Person-body relationship with role and time bounds (Popolo:Membership)
  • post — Formal position within a body (Popolo:Post)
  • contactDetail — Typed contact channels for a Person or GovernanceBody (Popolo:ContactDetail)
  • vote — Voting round (schema:VoteAction / Popolo:VoteEvent)
  • ballot — Individual vote cast (schema:VoteAction individual)
  • minutes — Meeting record (schema:CreativeWork); universal
  • processTemplate — Configurable workflow definition (Symfony Workflow)
  • motion — RETIRED; use decision with decisionType=motion
  • amendment — RETIRED; use decision with decisionType=amendment
  • resolution — RETIRED; use decision with decisionType=resolution
  • participant — DEPRECATED; use person + membership
  • board* — RETIRED (7 schemas); replaced by mode-adapted universal entities (ADR-006)

The configuration is imported via ConfigurationService::importFromApp() in the repair step.

5. Open Research Questions

The following questions need further investigation as the app matures:

  1. ORI API compliance depth — OpenRaadsinformatie connects 265/345 Dutch municipalities. Should Decidesk expose a full ORI-compatible REST API, or just export data in ORI format? Current decision: start with ORI export, add API later based on demand.

  2. AI meeting transcription — Market intelligence shows AI meeting assistant adoption grew 17x in 2024, but Otter.ai and Fireflies.ai face privacy lawsuits. Should Decidesk integrate with Nextcloud's ExApp AI infrastructure (Whisper, LLM summarization) for self-hosted transcription? Current decision: design Minutes entity to accept AI transcription (transcriptSource field), implement integration as a separate phase.

  3. E-voting security level — Council of Europe CM/Rec(2017)5 defines 49 standards for e-voting. POLYAS is the only BSI Common Criteria certified voting software. For legislative domain users, what security certification is needed? Current decision: start with non-binding votes and internal governance; formal e-voting certification is a future phase.

  4. Speaking time tracking — Equal Time case study shows 65% increase in women's speaking time when tracked. Should Decidesk include real-time speaking time tracking in the LiveMeeting view? Current decision: include as optional feature in live meeting view.

  5. Multi-language resolutions — ELI supports multilingual legislation. Should resolutions support multiple language versions? Current decision: single language per resolution, with schema:inLanguage field. Multilingual support via separate resolution objects with schema:translationOfWork references.

  6. Archival integration — Archiefwet 2021 mandates 10-year transfer to permanent archive. Should Decidesk integrate with specific archival systems (e-Depot, DMS)? Current decision: store MDTO metadata on decisions and resolutions; export capability for archival transfer as a future phase.

  7. Citizen access portal — Woo (Wet open overheid) requires active publication of decision documents. Should Decidesk include a public-facing portal? Current decision: expose public read-only API for ZaakAfhandelApp or external portals to consume. Woo publication via Docudesk export.

  8. Real-time collaborative editing — Should motion/amendment text editing support real-time collaboration (like Nextcloud Text)? Current decision: use Nextcloud Text integration for collaborative drafting, store final text in OpenRegister.

6. References

Primary Standards (International)

Schema.org Types Used

Dutch Standards

Technology

Competitive Landscape

  • GO Raadsinformatie — Dutch RIS market (proprietary SaaS)
  • Notubiz — Dutch RIS market leader, 50%+ share (proprietary SaaS)
  • iBabs — Board portal and meeting management (proprietary SaaS)
  • Diligent Boards — Enterprise board portal, $48-155K/year (proprietary)
  • OnBoard — Growing board portal challenger (proprietary SaaS)
  • OpenSlides — Open source assembly management (MIT, Python/Angular)
  • Loomio — Open source collaborative decision-making (AGPL-3.0, Ruby/Vue)
  • Decidim — Open source citizen participation (AGPL-3.0, Ruby on Rails)
  • Fellow.app — AI meeting management (proprietary SaaS)