Developer Guide
Technical documentation for developers building and extending the Health Dataspace v2 platform.
Technology Stack
Frontend
- Next.js 14 — App Router, React Server Components
- Tailwind CSS — Utility-first styling with custom layer colours
- react-force-graph-2d — Force-directed graph visualisation
- Mermaid.js — Architecture diagrams
- Lucide React — Icon library
Backend
- Neo4j 5 — Graph database with APOC + n10s plugins
- Neo4j Proxy — Node.js proxy service (:3001)
- NextAuth.js — Authentication with Keycloak OIDC
- EDC-V — Eclipse Dataspace Connector (Control + Data Plane)
- DCore / CFM — Data plane and credential framework
Quick Start
1. Prerequisites
# Required Node.js 20+, Docker & Docker Compose, Git # Optional Java 17+ (for EDC-V connector build) Python 3.11+ (for Synthea data loading)
2. Start Neo4j
docker compose up -d # Initialize schema cat neo4j/init-schema.cypher | \ docker exec -i health-dataspace-neo4j \ cypher-shell -u neo4j -p healthdataspace
3. Load Synthetic Data
# Insert synthetic FHIR + OMOP data cat neo4j/insert-synthetic-schema-data.cypher | \ docker exec -i health-dataspace-neo4j \ cypher-shell -u neo4j -p healthdataspace # Or load Synthea FHIR bundles (127 patients) pip install -r scripts/requirements.txt python scripts/load_fhir_neo4j.py
4. Start the UI
cd ui npm install npm run dev # → http://localhost:3000 npm run test # Run 1490 unit tests npm run lint # ESLint checks
Project Structure
├── .github/workflows/ # CI/CD (pages.yml for GitHub Pages) ├── connector/ # EDC-V connector (Gradle multi-module) │ ├── controlplane/ # DSP + Management API │ ├── dataplane/ # FHIR + OMOP data planes │ └── identityhub/ # DCP Identity Hub ├── docs/ # Documentation & ADRs │ ├── planning-health-dataspace-v2.md │ └── health-dataspace-graph-schema.md ├── jad/ # JAD infrastructure configs │ ├── edcv-assets/ # Contract definitions & policies │ └── openapi/ # OpenAPI specifications ├── neo4j/ # Cypher scripts & data │ ├── init-schema.cypher # Constraints & indexes │ ├── insert-synthetic-schema-data.cypher │ ├── fhir-to-omop-transform.cypher │ └── import/fhir/ # FHIR bundle imports ├── scripts/ # Automation scripts ├── services/neo4j-proxy/ # Node.js Neo4j proxy ├── ui/ # Next.js 14 application │ ├── src/app/ # App Router pages │ ├── src/components/ # Shared components │ ├── src/lib/ # Utilities & API client │ └── src/__tests__/ # Vitest unit tests └── docker-compose.yml # Local dev stack
Neo4j Graph Schema
The 5-layer knowledge graph uses these core node labels and relationships:
Key Conventions
- Node labels:
PascalCase(Patient, ConditionOccurrence) - Relationship types:
UPPER_SNAKE_CASE(HAS_ENCOUNTER, MAPS_TO) - Properties:
camelCase(birthDate, conceptId) - Schema defined in
neo4j/init-schema.cypher - Transformations in
neo4j/fhir-to-omop-transform.cypher
API Reference
The Next.js API routes (disabled in static export) proxy to Neo4j and EDC-V services:
| Route | Method | Description |
|---|---|---|
| /api/graph | GET | Fetch graph nodes & relationships for visualisation |
| /api/catalog | GET | HealthDCAT-AP dataset catalog search |
| /api/patients | GET | Patient list with FHIR demographics |
| /api/patients/[id] | GET | Patient journey timeline (FHIR + OMOP) |
| /api/analytics | GET | OMOP cohort analytics aggregates |
| /api/compliance | GET | EHDS compliance chain status |
| /api/eehrxf | GET | EEHRxF profile alignment data |
| /api/negotiate | POST | Initiate DSP contract negotiation |
| /api/query | POST | Natural language / Cypher query execution |
Note: API routes are only available when running locally (npm run dev). The GitHub Pages static export uses mock data from ui/public/mock/.
Testing
Unit Tests (Vitest)
- 1,490 tests across 78 files
- 94% statement coverage / 95% lines
- MSW for API mocking
- Testing Library for component tests
- View Test Report →(CI only)
npm run test # Run once npm run test:watch # Watch mode npm run test:coverage # With coverage
E2E Tests (Playwright)
- 166 tests across 18 spec files
- Screenshots captured for every test
- Traces & video on retries
- Playwright Report →
- EHDS Journey Report →
npm run test:e2e # Headless npm run test:e2e:ui # Interactive UI
EHDS User Journey
The full 8-step EHDS secondary-use journey is documented with sequence diagrams, persona mappings, and E2E test coverage:
View Full User Journey →CI/CD Pipeline
GitHub Pages Deployment
On push to main, the .github/workflows/pages.yml workflow:
- Checks out code and sets up Node 20
- Disables API routes (
mv src/app/api src/api_disabled) - Builds with
NEXT_PUBLIC_STATIC_EXPORT=trueandoutput: "export" - Uploads
./ui/outas Pages artifact - Deploys to GitHub Pages at
/MinimumViableHealthDataspacev2
Architecture Decision Records
EDC runtime metadata in PostgreSQL, health data in Neo4j knowledge graph.
Separate FHIR R4 and OMOP CDM data planes for type-safe access.
Graph nodes aligned with HealthDCAT-AP 3.0 profile for catalog interoperability.
Client-side SPA with API routes proxying to Neo4j and EDC-V backends.
Unit tests with Vitest, API mocking with MSW, coverage tracking.
Utility-first CSS with custom layer colour palette and Lucide icons.
Conditional next export with mock data for demo deployment.
Conventions
- Commit messages: Conventional Commits format (feat:, fix:, docs:, chore:)
- Branch strategy: Direct push to main (demo project)
- Pre-commit hooks: Prettier (md, yaml, json), ESLint, type-check
- Cypher: UPPER_SNAKE_CASE relationships, PascalCase labels, camelCase properties
- TypeScript: Strict mode, no any (where possible), interfaces over types
- Markdown: ~80 char line wrap, fenced code blocks, clean tables