Clinical wearable data platform: ingestion, mapping, storage, extraction, and web/mobile experience.
This repository is part of a research project at Charité – Universitätsmedizin Berlin. It contains the software platform developed to support a clinical study on wearable-derived digital biomarkers, covering data ingestion from wearable devices (e.g., smartwatches), mapping to standardized clinical formats (FHIR), storage, researcher-facing data extraction, and a web/mobile application layer for study participants and clinical staff.
The platform is designed to support clinical research workflows in which wearable sensor data (e.g., heart rate variability and related metrics) is collected, processed, and made available for analysis alongside clinical outcome measures, in compliance with applicable data protection requirements.
Preprint: Coming soon — .
Contact: Dr.-Ing. Elias Grünewald — elias.gruenewald@charite.de
This repository contains the Wearables platform end-to-end:
- mobile data collection
- backend APIs and stream processing
- schema and API contract generation
- frontend and dashboard embedding
- Kubernetes/GitOps deployment assets
- benchmarking and architecture artifacts
flowchart LR
A[Mobile App] --> B[Import Service]
B --> C[Kafka wearables-raw]
C --> D[FHIR Mapper + Validator]
D --> E[Kafka wearables-lp]
E --> F[Telegraf Kafka Consumer]
F --> G[InfluxDB]
G --> H[db_lord]
H --> I[Wearables BFF]
H --> J[Extraction Service]
K[Web Frontend] --> I
K --> L[Grafana Proxy]
L --> M[Grafana]
Notes:
wearables-bffintegrates withdb_lordthroughDATABASE_API_URL(services/backend/wearables-bff/src/clients/databaseApi.ts).extraction-serviceis researcher-facing and queriesdb_lord; it is not part of the web frontend request path.- Web monitoring embeds dashboards through
grafana-proxy(services/web/src/pages/case/CasePage.tsx). importservicevalidates case-verification JWTs viaJWT_SECRET+JWT_ISSUER(services/backend/importservice/app/security.py), so the issuer and secret must match your token issuer.
| Path | Purpose |
|---|---|
services/web |
React + Vite frontend for auth, case management, and monitoring UI |
services/mobile/mobile_app |
Flutter mobile app (wearables_app_tub) |
services/backend/wearables-bff |
Main BFF/API layer for web clients |
services/backend/grafana-proxy |
Grafana reverse proxy with JWT/session validation |
services/backend/importservice |
FastAPI ingestion endpoint to Kafka |
services/backend/fhir-mapper-validator |
Kafka Streams mapper/validator to FHIR + line protocol |
services/backend/db_lord |
Data management service for storage/query workflows |
services/backend/extraction-service |
Researcher-facing extraction API (JSON + CSV export) |
services/backend/wplug |
Go load generator for workload testing scenarios |
services/backend/clinical-analytics |
Legacy/minikube-oriented platform deployment assets |
services/packages/api-schema |
Zod-based API schema source, generates openapi.json |
gitops |
Helm charts and Kubernetes deployment manifests |
infra |
Terraform + Ansible infrastructure automation |
ci-cd |
GitHub Actions workflow definitions and CI/CD helper assets |
observability |
Dashboard JSON and monitoring artifacts |
benchmarks |
Benchmark runner, jobs, measurements, and evaluation |
docs |
Architecture docs, migration notes, and presentations |
- Install dependencies:
npm --prefix services/backend/wearables-bff install
npm --prefix services/web install- Create local env files:
cp services/backend/wearables-bff/.env.example services/backend/wearables-bff/.env
cp services/web/.env.example services/web/.env- For local browser access, set these in
services/backend/wearables-bff/.env:
FRONTEND_ORIGINS=http://localhost:5173
FRONTEND_REDIRECT_URL=http://localhost:5173
BACKEND_URL=http://localhost:3001- Start local development (runs BFF and web frontend):
npm --prefix services/web run dev- Open
http://localhost:5173.
npm --prefix services/backend/grafana-proxy install
cp services/backend/grafana-proxy/.env.example services/backend/grafana-proxy/.env
npm --prefix services/backend/grafana-proxy run devKeep JWT settings aligned across services:
services/backend/wearables-bff/.env->JWT_SECRET,TOKEN_ISSUERservices/backend/grafana-proxy/.env->APP_JWT_SECRET,APP_JWT_ISSUER
For QR/app ingestion to work end-to-end, align case-token settings between the issuer and the validator:
- Token issuer service (
wearables-bff) usesTOKEN_ISSUER+JWT_SECRET. - Token validator (
importservice) checksJWT_ISSUER+JWT_SECRET. - If those differ,
/ingestrejects tokens with401 Invalid issuer.
services/packages/api-schema is the contract source of truth.
Regenerate schema and clients:
npm --prefix services/packages/api-schema install
npm --prefix services/packages/api-schema run generate:api-schema
npm --prefix services/backend/wearables-bff run generate:api
npm --prefix services/web run generate:api- Unified runtime deploy flow:
docs/deploy-runtime-config.md - Frontend chart:
gitops/apps/web-frontend/README.md - BFF chart:
gitops/apps/services/wearables-bff/README.md - Grafana proxy chart:
gitops/apps/monitoring/grafana-proxy/README.md - Extraction service chart:
gitops/apps/services/extraction-service/README.md - DB Lord chart:
gitops/apps/services/db-lord/README.md
- Benchmark suite:
benchmarks/README.md - Example plots/data:
benchmarks/evaluation/ - Runner implementation:
benchmarks/runner/
This monorepo was assembled from multiple project repositories with preserved history during development.
- Migration summary:
docs/migration/MIGRATION_SUMMARY.md - Recorded migration date: 2025-12-06
- TBA
