Releases: ma3u/MinimumViableHealthDataspacev2
v1.4.2 — MetricCard icon/label overlap fix
Patch fix: patient page metric cards were truncating labels like OBSERVATIONS/MEDICATIONS behind the top-right icon orb on narrow viewports. Absolute positioning with pr-16 could not reserve enough right-padding when the grid compressed; switched to a flex row layout where the orb column is a real flex sibling, so the label/value column reserves exactly its available width. Icon stays top-right, text no longer overlaps.
v1.4.1 — Patient timeline + Keycloak post-logout fixes
Patch release addressing three issues reported on https://ehds.mabu.red.
Fixes
Patient clinical timeline now shows dates
neo4j/insert-synthetic-schema-data.cypher now sets date/onsetDate/dateTime and display properties on Encounter, Condition, Observation, and MedicationRequest nodes for patients 1–8. The previous seed left these null, so the timeline coalesce in /api/patient returned undated rows.
ui/src/app/api/patient/route.ts now:
- Coalesces
fhir.idwithfhir.resourceId(the synthetic seed usesresourceId). - Accepts both
HAS_MEDICATIONandHAS_MEDICATION_REQUESTrelationships (Synthea vs. synthetic schema). - Broadens the date coalesce to include
onsetDate,dateTime, andperformedStart.
Both patient1 (Maria Schmidt, AlphaKlinik) and patient2 (Jan de Vries, Limburg MC) now return four dated clinical events each.
Keycloak "Invalid redirect uri" on patient switch
jad/keycloak-realm.json extends post.logout.redirect.uris (using the ## separator) to include https://ehds.mabu.red/* and the ACA ingress URL. Switching personas via /auth/switch no longer fails at Keycloak logout.
MetricCard icon drift
ui/src/app/patient/page.tsx pins metric card icons to the top of the card regardless of card height.
Upgrade / Deploy
Local JAD stack:
./jad/seed-all.sh --from 3 # re-seed FHIR with the new dated nodes
docker compose -f docker-compose.yml -f docker-compose.jad.yml up -d --build
Azure Container Apps deploy is tracked separately; image push requires AcrPush role on acrmvhdehds.
🤖 Generated with Claude Code
v1.4.0 — Patient timeline grouped by month, newest first
Highlights
Patient Journey timeline
- FHIR clinical events on
/patientare now grouped by year + month with section headers (e.g. September 1981). - Events are ordered newest first both between and within groups so reviewers scan top-down.
- Each month group shows its own event count and independent activity-timeline connector for clearer visual rhythm.
Build provenance in Docker image
ui/Dockerfilenow acceptsBUILD_SHA,BUILD_TIME, andBUILD_CHANNELbuild args and bakes them into the runtime env.UserMenu/ BuildInfo surfaces show which commit and channel produced the running image.
Test suite refresh
- Consolidated middleware unit tests onto the
getToken()+ CSP-nonce architecture (replaces oldwithAuthcallback flow). - Updated UserMenu tests to mock
/api/keycloak-configinstead of relying on removedNEXT_PUBLIC_KEYCLOAK_*env vars. - Added Neo4j fallback coverage for
admin-components+admin-tenantsroute tests. - New route tests:
graph-expand,graph-node,graph-validate,health,patient-insights,patient-profile,patient-research. - All 1648 unit tests pass.
Versions
ui/package.json: 1.3.0 → 1.4.0- Docker image:
acrmvhdehds.azurecr.io/health-dataspace-ui:1.4.0(sha256:2d0ee891099a)
Deployments
- Azure Container Apps:
mvhd-ui(revisionmvhd-ui--0000012) — live at https://ehds.mabu.red - Local JAD (Docker Compose):
health-dataspace-uicontainer —http://localhost:3003 - Local K8s (OrbStack):
health-dataspace-uideployment — in-cluster service healthy
Upgrade notes
No config changes required. Rebuild with --build-arg BUILD_SHA=$(git rev-parse --short HEAD) to populate the new build provenance env vars.
v1.3.0 — Neo4j temporal fix + UserMenu build info
Highlights
- Fix
/patient+/patient/profilecrash on ACA — Neo4j temporal types (DATE, DATETIME, Integer) now normalise to ISO strings / JS numbers before leavingrunQuery, so React no longer hits error #31 trying to render{year, month, day}objects. - Build info in UserMenu — the user dropdown shows the app version (linked to its GitHub release), short commit SHA (linked to the commit), and build timestamp. Local builds show a
+localmarker and link to the releases index. - 24×7 Azure deploy — production UI + graph are live at
ehds.mabu.red, backed by Azure Container Apps + Neo4j persistence. Off-hours scale-down keeps costs predictable. - EHDS Integration Hub rebranding — new landing page pitch, Scalar API reference, OpenAPI 3.1 + Bruno collection, and a "data planes" guide.
What's new
Features
- feat(ui): rewrite landing page as EHDS integration platform pitch (
a862cbe) - feat(docs): rename to EHDS Integration Hub + Scalar API reference + data planes guide (
32384a8) - feat(azure): 24/7 ACA deploy + Azure Monitor metrics + cost panel + UX fixes (
8887889) - feat(api): OpenAPI 3.1 + Swagger UI + Bruno collection + ACA persistence (
857a136) - feat(infra): ACA off-hours scale-down (ADR-016) replaces single-VM fallback (
bfc9f53) - feat(infra): single-VM dev path + fix /graph unauth UX + weekly reset (
3af57f5) - feat(admin): ODRL policy editor with edit/delete/duplicate + EHDS templates + favicon + login_hint (
1b4c471) - feat(auth): proper sign-out in static demo with persona picker on sign-in (
82223bd) - feat(settings): persona-aware profile — admin sees all, users see own org (
bf1a108) - feat(tasks): scope task list to user's organisation — admins see all (
f29d630) - feat(compliance): in-cluster ACA runner + Azure demo CI smoke (
3644335) - feat(quality): implement all medium+high future quality gates (
db1e20c) - feat(ci): skip nightly demo reset when databases are clean (#11,
25ae55e) - feat(ci): auto-sync mock fixtures from live Neo4j in pages workflow (
c241020) - feat: nightly demo reset workflow — 24h data retention policy (#11,
068fd0f)
Fixes
- fix(ui/lib/neo4j): normalise Neo4j temporal types in
runQueryso React can render patient dates (this release) - fix(admin): timeout ARM fetches so dead managed-identity doesn't hang UI (
d2b1f5b) - fix(ehds+azure): close seed-data gaps and point mvhd-ui at ACA internal ingress (
99ef769) - fix(edc): add fetch timeout so dead upstreams don't hang admin routes (
5496ea3) - fix(admin): make tenants/topology/cost panels Azure-aware (
744c725) - fix(compliance): use correct OMOP relationship names in EHDS runner (
c9538fa) - fix(csp): drop nonce from style-src so 'unsafe-inline' takes effect (
8810b2d) - fix(csp): opt layout into dynamic rendering so middleware nonce reaches HTML (
6e1d660) - fix(csp+auth): restore nonce propagation + runtime Keycloak config (
2867186) - fix(security): CSP nonces + HSTS/COOP/COEP + Bruno assertions + public /api/graph (
05b8193) - fix(azure): Neo4j seed job must use short-name Bolt host (
a85c04d) - fix(azure): Neo4j TCP ingress needs exposed-port + short-name DNS (
b732a83) - fix(a11y,azure): WCAG contrast + admin/components participants + Neo4j seed (
7bb0801) - fix(ui): show sign-in prompt on /patient and /eehrxf for anonymous users (
84adcaa) - fix(auth): sign-out in static demo now clears persona and redirects home (
d5b1145) - fix(graph): sync URL ?persona= param to sessionStorage for nav/menu (
c1dce63) - fix(e2e): resolve 15 test failures + add SBOM/license CI gates + docs improvements (
13b1f88) - multiple CI fixes (ACR naming, swagger self-host, demo-smoke paths, bash/sh)
Docs
- docs(planning): Phase 25 — GraphRAG accuracy via GDS + Azure AI Foundry (
cf77b57) - docs: add Graph DB + GraphRAG vs Relational DB + VectorRAG comparison (
1eaadda) - docs: add onboarding guide, SIMPL section in architecture, update developer page (
23a5991) - docs(quality-gates): add infrastructure note to compliance section (
5079ff7) - docs: link GitHub issues in planning doc + ADR workflow in CLAUDE.md (
27bba41)
Deployment
- Local JAD:
docker compose up -d && ./scripts/bootstrap-jad.sh(image tag1.3.0) - Azure ACA:
az containerapp update --image acrmvhdehds.azurecr.io/health-dataspace-ui:1.3.0 -n mvhd-ui -g rg-mvhd-dev
Known issues (out of scope for 1.3)
- ~70 pre-existing middleware unit-test failures remain and will be addressed in 1.3.1.
- Two UserMenu sign-out tests still assert the legacy
NEXT_PUBLIC_KEYCLOAK_*env-var path; the component now uses runtime/api/keycloak-configfetch — tests will be aligned in 1.3.1.
Full changelog: v1.2.0...v1.3.0
v1.2.0 — Azure Deployment & ADR Documentation
What's New in v1.2.0
Azure Container Apps Deployment
- Full stack deployed to Azure Container Apps (13 apps + 3 jobs)
- CI/CD pipeline with OIDC federation — no stored credentials
- Playwright E2E tests run against Azure after every deploy
- 11 deployment scripts in
scripts/azure/ - Azure Deployment Guide
Architecture Decision Records
- 13 standalone ADR documents in
docs/ADRs/ - ADR-001 to ADR-009: Extracted from planning document (PostgreSQL/Neo4j split, data planes, HealthDCAT-AP, Next.js frontend, source builds, GHCR publishing, DID:web, testing, credential issuance)
- ADR-010: WCAG 2.2 AA Accessibility Compliance
- ADR-011: Security Penetration Testing Strategy
- ADR-012: Azure Container Apps Deployment
- ADR-013: SIMPL-Open EU Programme Alignment
README Overhaul
- Replaced verbose 270-line phase descriptions with compact summary table
- Added Azure Deployment section with links to guide and scripts
- Updated documentation table with all current references
- Updated test stats badge (778 E2E tests)
E2E Test Fixes for Azure
- Fixed hardcoded
localhostURLs in test helpers - All tests now use
PLAYWRIGHT_BASE_URLandKEYCLOAK_PUBLIC_URLenv vars - Tests work against both local (localhost:3000) and Azure deployments
Planning Document Updates
- Added Cross-Cutting Concerns section (SIMPL, WCAG, Security, Azure)
- Added ADR index table linking all 13 architecture decisions
- Updated planning doc with links to standalone ADR files
Full Changelog
v1.1.0 — Hospital-Grade Design System, WCAG 2.2 AA & Simpl-Open Gap Analysis
What's New
Hospital-Grade Design System (Stitch Vitalis Blue)
- Phase 21–23: Complete design system overhaul with the Stitch Vitalis Blue theme — professional hospital-grade light/dark mode across all 16 pages
- Design tokens: CSS custom properties for consistent theming (
--accent,--surface-*,--text-*,--border, layer colours) - Page headers: Unified
page-headerpattern applied to admin, exchange, governance, and patient pages - Graph explorer: Redesigned entity inspector panel with improved usability and accessibility
WCAG 2.2 AA Compliance
- Zero contrast violations: All pages pass axe-core automated WCAG 2.2 AA checks in both light and dark mode
- 93 automated checks: 26 unauthenticated + 67 authenticated (7 Keycloak personas × dark/light × multiple pages)
- Light/dark safe patterns: Replaced all
text-gray-400,text-blue-400etc. with dual-mode tokens liketext-gray-700 dark:text-gray-400
Comprehensive E2E Test Suite
- 29 spec files / 778 tests: Up from 14 files / 102 tests (previous release)
- 581 passed, 197 skipped, 0 failed (JAD stack run)
- New journey specs: WCAG accessibility (J780–J799), security pentest (J800–J860), authenticated role menus (J870+), static GitHub Pages (J221–J260)
Documentation
- Simpl-Open vs EHDS gap analysis: 15-dimension architecture comparison matrix covering identity (DID/SSI vs X.509), policy (ODRL vs XACML), clinical data (FHIR R4, OMOP CDM), and EHDS article-by-article compliance mapping
- E2E test report: Full breakdown of all 29 spec files with JAD stack results
CI/CD Fixes
- Fixed gitleaks/Trivy binary install (checksum filename mismatch)
- Added
.gitleaksignorefor dev-only secrets (JAD stack in-memory credentials) - Stabilised E2E pipeline with
continue-on-error(no Neo4j available in CI)
Test Results
| Suite | Files | Tests | Passed | Failed |
|---|---|---|---|---|
| Unit (Vitest) | 86 | 1,613 | 1,613 | 0 |
| E2E (Playwright) | 29 | 778 | 581 | 0 |
| Protocol Compliance | 3 | — | ✅ | — |
Coverage (UI)
| Metric | Value |
|---|---|
| Statements | 93.78% |
| Branches | 81.65% |
| Functions | 89.57% |
| Lines | 94.73% |
Breaking Changes
None.
Full Changelog
v1.0.0 — EHDS Health Dataspace Reference Implementation
v1.0.0 — EHDS Health Dataspace Reference Implementation
The first official release of the Minimum Viable Health Dataspace v2 — a fully functional reference implementation of the European Health Data Space (EHDS) regulation, built on the Dataspace Protocol (DSP 2025-1) and Eclipse Dataspace Components (EDC-V).
Live Demo
No installation required — explore all 7 personas directly in your browser:
👉 https://ma3u.github.io/MinimumViableHealthDataspacev2/
Highlights
5-Layer Neo4j Knowledge Graph
- 113,686 nodes and 265,620 edges across 5 architectural layers
- L1 Marketplace: Participants, DataProducts, Contracts, HDAB Approvals, Trust Centers
- L2 HealthDCAT-AP: Dataset metadata, Distributions, EEHRxF Profiles
- L3 FHIR R4: 174 synthetic patients, Encounters, Conditions, Observations, Medications
- L4 OMOP CDM: Research analytics layer with pseudonymised subjects
- L5 Ontology: SNOMED CT, ICD-10, LOINC, RxNorm biomedical codes
Value-Centric Graph Explorer
Each persona sees their purpose at the center of the graph, with nodes arranged by relevance:
| Persona | Center Node | EHDS Articles |
|---|---|---|
| Patient / Citizen | My Health | Art. 3–12 |
| Researcher / Data User | My Researches | Art. 46–49 |
| Hospital / Data Holder | Our Data Offerings | Art. 33–37 |
| HDAB Authority | Govern the Dataspace | Art. 45–53 |
| EDC / Dataspace Admin | Manage Dataspace | Art. 33 |
| Trust Center Operator | Privacy Operations | Art. 50–51 |
Features: canvas hover tooltips, single-click expand, collapsible panels, persona-specific filter presets, friendly relationship labels, node property details.
EHDS Researcher Workflow (Art. 46–49)
The My Researches menu guides researchers through the complete EHDS secondary-use data access process:
- Research Overview → Knowledge graph with researcher focus
- Browse Catalogs → HealthDCAT-AP dataset catalog
- Discover Datasets → Federated search across participant catalogs
- Request Access → Submit access application with purpose and legal basis
- My Applications → Track HDAB approval status
- Retrieve Data → Transfer approved data to Secure Processing Environment
- Run Analytics → OMOP cohort analytics within the SPE
- Query & Export → NLQ/federated queries, export aggregate results only
Patient Data Isolation (EHDS Art. 3 / GDPR Art. 15)
- Patients see only their own health record — no access to other patients
- Patient selector hidden; restricted banner shown
- Server-side enforcement: API returns 403 for unauthorized patient IDs
- Works in both live stack (Keycloak session) and static demo (localStorage persona)
7 Pre-Configured Demo Personas
| Username | Role | Organisation |
|---|---|---|
edcadmin |
Dataspace Admin | Dataspace Operator |
clinicuser |
Data Holder | AlphaKlinik Berlin |
lmcuser |
Data Holder | Limburg Medical Centre |
researcher |
Researcher | PharmaCo Research AG |
regulator |
HDAB Authority | MedReg DE |
patient1 |
Patient / Citizen | AlphaKlinik Berlin |
patient2 |
Patient / Citizen | Limburg Medical Centre |
User switching passes login_hint to Keycloak for seamless persona transitions.
Protocol Compliance
| Protocol | Version | Status |
|---|---|---|
| DSP (Dataspace Protocol) | 2025-1 | ✅ TCK passing |
| DCP (Decentralised Claims Protocol) | v1.0 | ✅ VC attestation |
| FHIR R4 | R4 | ✅ 174 synthetic patients |
| OMOP CDM | v5.4 | ✅ Full ETL pipeline |
| HealthDCAT-AP | 2.1 | ✅ Dataset metadata |
| EHDS | Art. 3–53 | ✅ Primary + secondary use |
| GDPR | Art. 15–22 | ✅ Patient rights |
| ODRL | 2.2 | ✅ Policy expressions |
| EEHRxF | 2025 | ✅ FHIR profile alignment |
Architecture
┌─────────────────────────────────────────────────────────┐
│ Next.js 14 UI │
│ 35 pages · 37 API routes · 7 persona views │
├─────────────┬───────────────┬───────────────────────────┤
│ Keycloak │ EDC-V Stack │ Neo4j 5 Knowledge Graph │
│ OIDC SSO │ (19 services)│ 113K nodes · 265K edges │
│ 7 users │ DSP + DCP │ 5 layers · FHIR + OMOP │
├─────────────┴───────────────┴───────────────────────────┤
│ Docker Compose (22 containers) · OrbStack / K8s │
└─────────────────────────────────────────────────────────┘
Test Coverage
| Suite | Framework | Count | Status |
|---|---|---|---|
| Unit + Component | Vitest 4 | 1,564 | ✅ All pass |
| E2E (live stack) | Playwright | 93 | ✅ All pass |
| E2E (GitHub Pages) | Playwright | 115 | ✅ 115/116 pass |
| Protocol TCK | DSP 2025-1 | — | ✅ Passing |
Quick Start
# Minimal stack (Neo4j + UI)
docker compose up -d
# → http://localhost:3000
# Full JAD stack (22 services — needs 8 GB Docker RAM)
docker compose -f docker-compose.yml -f docker-compose.jad.yml up -d
./scripts/bootstrap-jad.sh
# → http://localhost:3003 (Keycloak SSO)What's New Since Initial Development
- Value-centric graph explorer with persona-specific center nodes
- Color palette split: cool/muted structural layers vs warm/vivid actor accents
- Canvas hover tooltips and single-click node expansion
- Persona-specific filter presets (patient, researcher, hospital, HDAB)
- Human-readable node names (display names before numeric codes)
- Node properties API with user-friendly labels per type
- Enriched TransferEvent data with consumer/provider/contract/dataset
- EHDS researcher workflow menu (Art. 46–49)
- Patient data isolation (EHDS Art. 3 / GDPR Art. 15)
- Keycloak user switching with
login_hint - Hospital-specific and HDAB-specific filter presets
- Collapsible left sidebar and right detail panel
- TransferEvent schema constraints and seed data
- 37 persona-specific mock JSON files for static export
- 219 commits across 24 implementation phases
Built with Next.js 14, Neo4j 5, Eclipse EDC-V, Keycloak, and the European Health Data Space regulation.