mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 20:43:41 +00:00
docs: add DAK-Datenschutz design for role-based data masking
Design for hiding personal data (name, birthdate) from dak_mitarbeiter users with backend-enforced filtering and a time-limited disclosure request mechanism for KVNR error resolution. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
480f851836
commit
030fab72e4
1 changed files with 106 additions and 0 deletions
106
docs/plans/2026-02-26-dak-datenschutz-design.md
Normal file
106
docs/plans/2026-02-26-dak-datenschutz-design.md
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
# DAK-Datenschutz: Rollenbasierte Datenmaskierung
|
||||||
|
|
||||||
|
## Ziel
|
||||||
|
|
||||||
|
DAK-Mitarbeiter (`dak_mitarbeiter`) duerfen personenbezogene Daten (Nachname, Vorname, Geburtsdatum) nicht einsehen. Die Maskierung erfolgt auf Backend-Ebene (DSGVO-konform). Bei Bedarf (z.B. KVNR-Fehler) kann ein DAK-Mitarbeiter eine zeitlich begrenzte Freigabe beim Admin anfordern.
|
||||||
|
|
||||||
|
## Architektur
|
||||||
|
|
||||||
|
**Ansatz: Backend-Filterung** — Das Backend entfernt sensible Felder aus der API-Antwort fuer `dak_mitarbeiter`. Zwei Serialisierungspfade je nach Rolle. Kein Frontend-only-Masking, da technisch versierte Nutzer sonst per DevTools an die Daten kaemen.
|
||||||
|
|
||||||
|
## 1. Backend-Serialisierung
|
||||||
|
|
||||||
|
### Zwei Response-Pfade
|
||||||
|
|
||||||
|
- **Admin:** Voller `CaseResponse` wie bisher (alle Felder).
|
||||||
|
- **dak_mitarbeiter:** Felder `nachname`, `vorname`, `geburtsdatum` werden auf `null` gesetzt, es sei denn eine aktive Freigabe existiert. Zusaetzliches Feld `disclosure_granted: bool` in der Response.
|
||||||
|
|
||||||
|
### Suchfunktion
|
||||||
|
|
||||||
|
Der `search`-Query-Parameter durchsucht aktuell: nachname, vorname, fall_id, kvnr. Fuer `dak_mitarbeiter` wird die Suche auf **fall_id und kvnr** beschraenkt.
|
||||||
|
|
||||||
|
## 2. Freigabe-Mechanismus (Disclosure Requests)
|
||||||
|
|
||||||
|
### Neues Modell: `DisclosureRequest`
|
||||||
|
|
||||||
|
Tabelle `disclosure_requests`:
|
||||||
|
|
||||||
|
| Feld | Typ | Beschreibung |
|
||||||
|
|------|-----|-------------|
|
||||||
|
| id | int (PK) | Auto-increment |
|
||||||
|
| case_id | int (FK -> cases) | Betroffener Fall |
|
||||||
|
| requester_id | int (FK -> users) | DAK-Mitarbeiter |
|
||||||
|
| reason | str | Begruendung |
|
||||||
|
| status | str | pending / approved / rejected |
|
||||||
|
| reviewed_by | int (FK -> users, nullable) | Admin der entscheidet |
|
||||||
|
| reviewed_at | datetime (nullable) | Zeitpunkt der Entscheidung |
|
||||||
|
| expires_at | datetime (nullable) | 24h nach Genehmigung |
|
||||||
|
| created_at | datetime | Anfragezeitpunkt |
|
||||||
|
|
||||||
|
### Ablauf
|
||||||
|
|
||||||
|
1. DAK-Mitarbeiter sieht Fall -> klickt "Personendaten anfordern"
|
||||||
|
2. Gibt Begruendung ein -> `POST /cases/{case_id}/disclosure-request`
|
||||||
|
3. Admin erhaelt Notification (Typ `disclosure_request`)
|
||||||
|
4. Admin sieht offene Anfragen unter `/admin/disclosures`
|
||||||
|
5. Admin genehmigt/lehnt ab -> `PUT /admin/disclosure-requests/{id}`
|
||||||
|
6. Bei Genehmigung: `expires_at` = now() + 24h
|
||||||
|
7. DAK-Mitarbeiter erhaelt Notification ueber Ergebnis
|
||||||
|
8. Backend prueft bei jedem Case-Abruf: aktive Freigabe vorhanden? -> Personendaten werden mitgeliefert
|
||||||
|
|
||||||
|
### Zeitliche Begrenzung
|
||||||
|
|
||||||
|
Freigaben laufen nach 24 Stunden automatisch ab. Pruefung bei jedem API-Aufruf: `status == 'approved' AND expires_at > now()`. Kein Cronjob noetig.
|
||||||
|
|
||||||
|
## 3. Neue API-Endpoints
|
||||||
|
|
||||||
|
| Methode | Route | Rolle | Beschreibung |
|
||||||
|
|---------|-------|-------|-------------|
|
||||||
|
| POST | `/cases/{case_id}/disclosure-request` | dak_mitarbeiter | Freigabe anfordern |
|
||||||
|
| GET | `/admin/disclosure-requests` | admin | Offene Anfragen auflisten |
|
||||||
|
| GET | `/admin/disclosure-requests/count` | admin | Anzahl offener Anfragen (Badge) |
|
||||||
|
| PUT | `/admin/disclosure-requests/{id}` | admin | Genehmigen/Ablehnen |
|
||||||
|
|
||||||
|
### Bestehende Endpoints — Anpassungen
|
||||||
|
|
||||||
|
- `GET /cases/`, `GET /cases/{id}`, `GET /cases/pending-icd` — Rollenpruefung, Feldern maskieren
|
||||||
|
- Search-Parameter: nachname/vorname aus OR-Suche entfernen fuer dak_mitarbeiter
|
||||||
|
|
||||||
|
### Validierung
|
||||||
|
|
||||||
|
- Doppelte pending-Anfrage fuer gleichen Fall/User -> 409 Conflict
|
||||||
|
- Aktive (nicht abgelaufene) Freigabe existiert bereits -> 409 Conflict
|
||||||
|
- Fall nicht gefunden -> 404
|
||||||
|
|
||||||
|
## 4. Frontend-Anpassungen
|
||||||
|
|
||||||
|
### Fallliste (CasesPage)
|
||||||
|
|
||||||
|
**dak_mitarbeiter:**
|
||||||
|
- Spalten Nachname/Vorname komplett ausgeblendet (nicht gerendert)
|
||||||
|
- Suchfeld-Placeholder: "Fall-ID, KVNR..."
|
||||||
|
- Sichtbare Spalten: Datum, KVNR, Fallgruppe, ICD, Gutachten, Status
|
||||||
|
|
||||||
|
**admin:** Keine Aenderung.
|
||||||
|
|
||||||
|
### Falldetail (CaseDetail Sheet)
|
||||||
|
|
||||||
|
**dak_mitarbeiter:**
|
||||||
|
- Felder nachname, vorname, geburtsdatum ausgeblendet
|
||||||
|
- Ausnahme: Bei `disclosure_granted === true` -> Felder anzeigen mit Badge "Freigabe aktiv (laeuft ab um XX:XX)"
|
||||||
|
- Button "Personendaten anfordern" -> Dialog mit Textfeld fuer Begruendung
|
||||||
|
- Bei pending-Anfrage -> Button disabled mit "Anfrage ausstehend"
|
||||||
|
|
||||||
|
**admin:** Keine Aenderung.
|
||||||
|
|
||||||
|
### Admin-Bereich
|
||||||
|
|
||||||
|
- Neuer Sidebar-Eintrag: "Freigabe-Anfragen" (`/admin/disclosures`) mit Badge-Counter
|
||||||
|
- Listenseite mit offenen Requests: Fall-ID, Anfragender User, Begruendung, Datum
|
||||||
|
- Approve/Reject-Buttons pro Anfrage
|
||||||
|
|
||||||
|
### Notifications
|
||||||
|
|
||||||
|
Bestehendes Notification-System wird erweitert:
|
||||||
|
- DAK-Mitarbeiter: "Ihre Freigabe fuer Fall XYZ wurde genehmigt/abgelehnt"
|
||||||
|
- Admin: "Neue Freigabe-Anfrage von [Username] fuer Fall XYZ"
|
||||||
Loading…
Reference in a new issue