pediatric-ai-scribe-v3/monitoring/dashboards/pedscribe-audit.json
Daniel 47844ff29b Add Loki + Grafana monitoring stack, ntfy notifications, biometric auth
Monitoring:
- docker-compose.monitoring.yml — opt-in Loki + Grafana stack
- Loki config with 6-year retention (HIPAA compliant)
- Grafana auto-provisioned with Loki datasource + PedScribe dashboard
  (login activity, failed logins, clinical actions, API calls, log viewer)
- Logger ships to Loki in parallel with PostgreSQL (fire-and-forget)
- Labels: app=pedscribe, type=audit|api_call|access, category, action

Usage: docker compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d
Grafana at localhost:3003 (admin/pedscribe)

Notifications:
- ntfy push support (src/utils/notify.js)
- Notifications on: login, password change, registration
- Self-hosted, no Firebase dependency

Mobile:
- Biometric auth on app launch (Face ID/Touch ID/fingerprint)
- PIN/password fallback, auto-prompt, skip option
2026-04-11 03:00:52 +02:00

70 lines
2 KiB
JSON

{
"dashboard": {
"title": "PedScribe Audit & Usage",
"uid": "pedscribe-audit",
"timezone": "browser",
"refresh": "30s",
"time": { "from": "now-24h", "to": "now" },
"panels": [
{
"title": "Login Activity",
"type": "timeseries",
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
"targets": [{
"datasource": "Loki",
"expr": "count_over_time({app=\"pedscribe\", category=\"auth\"} |= \"login\" [5m])",
"legendFormat": "Logins"
}]
},
{
"title": "Failed Logins",
"type": "timeseries",
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 0 },
"targets": [{
"datasource": "Loki",
"expr": "count_over_time({app=\"pedscribe\", category=\"auth\"} |= \"login_failed\" [5m])",
"legendFormat": "Failed"
}]
},
{
"title": "Clinical Actions",
"type": "timeseries",
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
"targets": [{
"datasource": "Loki",
"expr": "count_over_time({app=\"pedscribe\", category=\"clinical\"} [5m])",
"legendFormat": "Clinical Actions"
}]
},
{
"title": "API Calls by Model",
"type": "timeseries",
"gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
"targets": [{
"datasource": "Loki",
"expr": "count_over_time({app=\"pedscribe\", type=\"api_call\"} [5m])",
"legendFormat": "API Calls"
}]
},
{
"title": "Recent Audit Events",
"type": "logs",
"gridPos": { "h": 10, "w": 24, "x": 0, "y": 16 },
"targets": [{
"datasource": "Loki",
"expr": "{app=\"pedscribe\"}",
"maxLines": 100
}],
"options": {
"showTime": true,
"showLabels": true,
"showCommonLabels": false,
"wrapLogMessage": true,
"prettifyLogMessage": false,
"enableLogDetails": true,
"sortOrder": "Descending"
}
}
]
}
}