Board portal — migration guide
Audience: corporate secretaries and IT integrators migrating an existing board portal onto Decidesk.
Scope: practical, schema-level migration from the three most common incumbent stacks — Diligent Boards, Boardvantage / Nasdaq Directors Desk, and SharePoint-based ad-hoc portals — onto the Decidesk
Board,BoardMember,BoardMeeting,Resolution,Vote,Minutes,ConflictOfInterest,BoardMaterial, andAuditLogEntryschemas. The guide assumes the target Decidesk instance is already installed (docs/admin/board-portal-admin.md§1) and the legacy export is in hand.
1. Migration principles
- Lift on slugs, not on legacy IDs — every Decidesk schema is keyed on
a slug (
oc_openregister_table_<reg>_<schema>). Pick the slug at import time (e.g.rvc-strategy-q3); do not try to preserve legacy GUIDs. - Preserve the audit trail as separate
AuditLogEntryrecords — the board-portal audit trail is hash-chained (docs/Technical/board-portal-architecture.md§5). Imported history goes in as a single migration entry per source record (source: "migration",previousSystem: "diligent"), not as forged contemporaneous events. - Re-sign canonical artefacts where possible — eIDAS QES does not
carry across portals. Re-sign the last N years of board minutes on the
Decidesk side where the relevant directors are still serving; flag the
older artefacts as
qesLevel: "legacy"and surface that in the regulator-export bundle. - Migrate in waves — boards → members → meetings → resolutions → materials. Earlier waves are blockers for later ones (a Resolution requires a BoardMeeting; a BoardMeeting requires a Board; etc.).
2. Migrating from Diligent Boards
Diligent's Director REST API exposes:
/api/v1/personas(members),/api/v1/books(board-book = meeting + materials bundle),/api/v1/resolutions(Diligent Resolutions module).
2.1 Field mapping
| Diligent field | Decidesk schema.field | Notes |
|---|---|---|
persona.id | BoardMember.legacyId (custom) | retained for cross-reference |
persona.fullName | BoardMember.name | |
persona.role | BoardMember.role | map chair, vice-chair, member, secretary |
persona.independent | BoardMember.independenceStatus | true → independent, false → executive |
book.id | BoardMeeting.legacyId (custom) | |
book.scheduledStart | BoardMeeting.scheduledStart | ISO 8601 |
book.agenda[] | AgendaItem records linked via boardMeetingId | one per Diligent agenda entry |
book.attachments[] | BoardMaterial records | accessLevel defaults to board-only |
resolution.id | Resolution.legacyId (custom) | |
resolution.text | Resolution.text | |
resolution.adoptedAt | Resolution.decidedAt | |
resolution.votes[] | BoardVote records via resolutionId | one per Diligent vote row |
2.2 Recipe
- Export Diligent personas + books + resolutions via the REST API; persist as JSON.
- Run a 2-pass import:
- Pass 1 —
Board+BoardMember(no dependencies); - Pass 2 —
BoardMeeting+AgendaItem+BoardMaterial+Resolution+BoardVote+ConflictOfInterest(depend on Pass 1).
- Pass 1 —
- Drive every write through the OR REST surface (
POST /apps/openregister/api/objects/decidesk/<schema>), not via direct DB writes — this keeps OR's per-object RBAC + audit mirrors honest. - Verify by walking
GET /api/audit-logfor each imported record'sobjectUuidand asserting at least onemigrationentry exists.
2.3 Known gaps
- eIDAS QES — Diligent uses its in-platform SES; re-sign with QES on the Decidesk side for any minutes that are still legally live (typically the most recent 7 years for Dutch entities under Article 2:10 BW).
- Diligent annotations — board members' personal annotations on materials are user-private; they do not migrate. Communicate this to the directors before the cutover.
3. Migrating from Boardvantage / Nasdaq Directors Desk
Boardvantage uses a SOAP-ish export bundle (ZIP of XML + PDF). The shape:
Members.xmlMeetings.xmlResolutions.xmlAttachments/<meetingId>/<file>.pdf
3.1 Field mapping (delta from §2)
| Boardvantage field | Decidesk schema.field |
|---|---|
Members/Member/IndependenceDeclaration | BoardMember.independenceStatus |
Meetings/Meeting/QuorumRequired | BoardMeeting.quorumRequired (numeric) |
Resolutions/Resolution/Threshold | Resolution.threshold (e.g. majority, two-thirds, unanimous) |
Resolutions/Resolution/Outcome | Resolution.status (adopted, rejected, withdrawn) |
3.2 Recipe
- Unzip the Boardvantage bundle locally.
- Parse the XML files with an XSLT transform (sample at
tools/migration/boardvantage-to-decidesk.xslt— to be added per project) into the JSON shape Decidesk's REST surface expects. - Same 2-pass import as §2.2.
- Upload the
Attachments/<meetingId>/*.pdfset asBoardMaterialrecords; the binary itself is delegated to the docudesk leaf (perBoardMaterialController§4 of the architecture doc).
3.3 Known gaps
- Boardvantage uses
Threshold: "simple-majority"ambiguously — verify with the corporate secretary whether that means majority of votes cast vs. majority of board strength, and setResolution.thresholdexplicitly. - PDF annotations — same caveat as Diligent (§2.3).
4. Migrating from SharePoint-based ad-hoc portals
SharePoint board sites are typically a Document Library + a SharePoint List ("Meetings") + an emailed-around minutes Word file. There is no canonical export; the migration is bespoke.
4.1 Recipe
- Audit the SharePoint site — produce a CSV with one row per past
board meeting (
date,agenda items,attendees,minutes file,resolutions adopted). The corporate secretary owns this audit; it is the unit of work, not the SharePoint export itself. - Build a Board + roster — manually configure the current Board and BoardMember rows in the Decidesk UI before any history is imported.
- Backfill meetings — for each row in the audit CSV,
POSTaBoardMeetingrecord withlifecycle: "archived"and the resolutions as linkedResolutionrecords (status= the row's outcome). - Upload minutes —
BoardMaterialrecords pointing at the legacy Word/PDF files (accessLevel: "board-only"). - Stop accepting board work outside Decidesk — communicate the cutover date; from that date all new board work goes through the Decidesk UI.
4.2 Known gaps
- No structured vote records — SharePoint sites typically do not have
per-director vote tallies. Backfill the resolutions as
Resolutionrows with a singleBoardVoteper director-of-record markedvoteMethod: "imported"andvoteValue: "abstain"if unknown. Surface the gap in the next regulator-export bundle. - No conflict declarations — start the conflict-of-interest register cleanly from the cutover date.
5. Post-migration validation
For every migration path:
- Run
GET /api/audit-log/{id}/verifyover the head of the audit log; assertchecked: true. - Run
POST /api/regulator-exportsover the imported range and audit the sha256 against a sample of the source bundle. - Walk the
BoardDashboardKPIs (board-meetings-this-quarter,resolutions-this-quarter,attendance-current-quarter,conflicts-active) and confirm they match the secretary's expected numbers for the current quarter. - Have the chair sign one fresh test minutes record QES end-to-end
(
docs/compliance/board-portal-compliance.md§5) and confirm the signature appears on the minutes record and in the audit log.
If any of those four checks fail, do not declare the migration done.