This repository contains the source code for the Linked Data Explorer. Full documentation is maintained separately in the iou-architectuur repository and published at iou-architectuur.open-regels.nl/linked-data-explorer.
🌐 Production: linkeddata.open-regels.nl
🧪 Acceptance: acc.linkeddata.open-regels.nl
The Linked Data Explorer is a web application for discovering, composing, and executing DMN decision model chains from Dutch government knowledge graphs. It is built as part of the Regels Overheid Nederland (RONL) initiative and connects directly to TriplyDB knowledge graphs and the Operaton DMN execution engine.
The Linked Data Explorer lets you work with government decision models end-to-end — from discovery to execution:
- Discover available DMN decision models published to TriplyDB by government agencies
- Build chains by drag-and-drop, connecting DMN outputs to DMN inputs across agency boundaries
- Execute chains sequentially or as unified DRDs, with automatic variable orchestration
- Query any SPARQL endpoint with syntax highlighting and interactive graph visualisation
- Model processes with a BPMN 2.0 editor that links directly to DMN decision models
- Track governance status: see which DMNs have been validated by competent authorities
- Discover vendor implementations of reference decision models
The Linked Data Explorer is one of three components in the RONL ecosystem:
graph TB
CPSV[CPSV Editor<br/>cpsv-editor.open-regels.nl]
LDE[Linked Data Explorer<br/>linkeddata.open-regels.nl]
BACKEND[Shared Backend<br/>backend.linkeddata.open-regels.nl]
TRIPLY[TriplyDB<br/>Knowledge Graph]
OPERATON[Operaton<br/>DMN Engine]
CPSV -->|publishes TTL + DMN| TRIPLY
LDE -->|discovers DMNs via SPARQL| TRIPLY
LDE -->|executes decisions via REST| OPERATON
LDE -->|API calls| BACKEND
BACKEND -->|SPARQL| TRIPLY
BACKEND -->|REST| OPERATON
The CPSV Editor produces the data — government service definitions and DMN decision models published as Linked Data to TriplyDB. The Linked Data Explorer consumes that data — discovering, chaining, and executing those decisions. The Shared Backend handles orchestration logic that both applications depend on.
| Frontend | Backend | |
|---|---|---|
| Production | linkeddata.open-regels.nl | backend.linkeddata.open-regels.nl |
| Acceptance | acc.linkeddata.open-regels.nl | acc.backend.linkeddata.open-regels.nl |
| Branch | main / acc |
main / acc |
| Platform | Azure Static Web Apps | Azure App Service (Linux, Node.js 22) |
| Layer | Technology | Version |
|---|---|---|
| Frontend framework | React | 19.2.3 |
| Language | TypeScript | 5.8.x |
| Build tool | Vite | 6.2.x |
| Graph visualisation | D3.js | 7.9.x |
| BPMN editor | bpmn-js | 18.12.0 |
| Drag-and-drop | dnd-kit | 6.x / 10.x |
| Backend framework | Node.js + Express | 22 / 4.18.x |
| DMN engine | Operaton | — |
| Knowledge graph | TriplyDB | — |
| Package structure | npm workspaces | monorepo |
linked-data-explorer/
├── packages/
│ ├── frontend/ # React TypeScript SPA
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── ChainBuilder/ # DMN chain builder (main feature)
│ │ │ │ ├── BpmnModeler/ # BPMN 2.0 process editor
│ │ │ │ ├── GraphView.tsx # D3.js SPARQL graph visualisation
│ │ │ │ ├── ResultsTable.tsx
│ │ │ │ └── Changelog.tsx
│ │ │ ├── services/
│ │ │ │ ├── sparqlService.ts
│ │ │ │ └── templateService.ts
│ │ │ ├── utils/
│ │ │ │ └── exportService.ts
│ │ │ ├── types/
│ │ │ ├── changelog.json
│ │ │ └── tutorial.json
│ │ ├── .env.development
│ │ ├── .env.acceptance
│ │ └── .env.production
│ │
│ ├── backend/ # Node.js/Express orchestration API
│ │ ├── src/
│ │ │ ├── routes/ # /v1/dmns, /v1/chains, /v1/health
│ │ │ ├── services/ # SPARQL, Operaton, orchestration
│ │ │ ├── middleware/
│ │ │ └── utils/
│ │ └── .env.example
│ │
│ └── ropa-site/ # Public ROPA register (static, no build step)
│
├── examples/ttl/ # Test DMN data (6 models)
├── .github/workflows/ # CI/CD pipelines (acc + production)
└── package.json # Workspace root
packages/ropa-site is a static page that reads GET /v1/ropa/public from a backend chosen by the hostname it is served on. Serve it on localhost; do not open index.html as a file. Opened from disk, the page has no hostname and talks to the production backend.
With the LDE backend running on port 3001:
cd packages/ropa-site
npx serve . -l 5500Then open http://localhost:5500. The page calls http://localhost:3001. Port 5500 is used because the LDE frontend already takes 3000. See packages/ropa-site/README.md for the hostname-to-backend table and deployment.
The backend's API is a published contract, not just its code: packages/backend/openapi/openapi.yaml describes every /v1 route, and a gate (src/openapi/coverage.test.ts) fails npm test when a served operation is undocumented or a documented one is not served. Adding or changing a route means:
- Document the operation in
packages/backend/openapi/openapi.yaml— path, parameters, request and response bodies, and every status it can answer. - Add an
expectToMatchOperationassertion per documented status to the route's test file, so a response that drifts from its schema fails the test that touches it. - If the handler genuinely cannot answer
400(there is no invalid input for it to reject), add a narrowly scoped override toopenapi/.spectral.yamlwith a reason a reviewer can check, rather than documenting a status the handler never returns. - Run
npm run test:contract --workspace=packages/backendandnpm run lint:openapi --workspace=packages/backendbefore opening a pull request.
npm run test:contract --workspace=packages/backend runs the coverage gate together with every expectToMatchOperation assertion across the route tests — the one command that answers "does the code still match its description?" A narrower npm run test:openapi-coverage --workspace=packages/backend runs only src/openapi — the served-vs-documented coverage gate and the document's own tests (that the YAML parses, builds and is internally consistent); it is fast, but validates no route's actual response.
Full documentation is at iou-architectuur.open-regels.nl/linked-data-explorer.
| Section | URL |
|---|---|
| Getting started | /linked-data-explorer/user-guide/getting-started/ |
| Local development | /linked-data-explorer/developer/local-development/ |
| Architecture | /linked-data-explorer/developer/architecture/ |
| API reference | /linked-data-explorer/reference/api-reference/ |
| Changelog & roadmap | /linked-data-explorer/developer/changelog-roadmap/ |