update
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# STEP 9 – Backup, Recovery & Löschkonzept
|
||||
|
||||
## Ziel
|
||||
Sicherstellung von Datenverlustminimierung, Wiederherstellbarkeit
|
||||
und Erfüllung der DSG-Löschpflichten.
|
||||
|
||||
---
|
||||
|
||||
## 1. Datenübersicht
|
||||
|
||||
### 1.1 Medizinische / Personenbezogene Daten
|
||||
|
||||
| Datei / Speicher | Format | Inhalt | Sensibilität |
|
||||
|---|---|---|---|
|
||||
| `kg_diktat_user_profile.json` | JSON | Arztname, Fachgebiet, Passwort-Hash, TOTP-Secret | HOCH |
|
||||
| `kg_diktat_ablage/KG/` | Dateien | Krankengeschichten | HOCH |
|
||||
| `kg_diktat_ablage/Briefe/` | Dateien | Arztbriefe | HOCH |
|
||||
| `kg_diktat_ablage/Rezepte/` | Dateien | Rezepte | HOCH |
|
||||
| `kg_diktat_ablage/Kostengutsprachen/` | Dateien | Kostengutsprachen | HOCH |
|
||||
| `kg_diktat_ablage/Diktat/` | Dateien | Diktattexte | HOCH |
|
||||
| `kg_diktat_notes.json` | JSON | Notizen (ev. Patientenbezug) | MITTEL |
|
||||
| `kg_diktat_todos.json` | JSON | Aufgaben (ev. Patientenbezug) | MITTEL |
|
||||
| `kg_diktat_todo_inbox.json` | JSON | Eingehende Aufgaben | MITTEL |
|
||||
| `kg_diktat_medwork_contacts.json` | JSON | Praxiskontakte | MITTEL |
|
||||
| `aza_email_contacts.json` | JSON | E-Mail-Kontakte | MITTEL |
|
||||
| `aza_medwork_messages.json` | JSON | Nachrichten | MITTEL |
|
||||
| `workforce_planner.db` | SQLite | Mitarbeiter, Abwesenheiten, Audit-Log | MITTEL |
|
||||
|
||||
### 1.2 Konfigurationsdaten (nicht personenbezogen)
|
||||
|
||||
| Datei | Inhalt |
|
||||
|---|---|
|
||||
| `kg_diktat_config.txt` | Grundeinstellungen |
|
||||
| `kg_diktat_signature.txt` | Arzt-Signatur |
|
||||
| `kg_diktat_korrekturen.json` | Auto-Korrekturen |
|
||||
| `kg_diktat_textbloecke.json` | Textbausteine |
|
||||
| `kg_diktat_autotext.json` | Autotext-Vorlagen |
|
||||
| `kg_diktat_soap_presets.json` | SOAP-Profile |
|
||||
| `kg_diktat_brief_presets.json` | Brief-Profile |
|
||||
| `aza_email_config.json` | E-Mail-Konfiguration (ohne Passwort) |
|
||||
| Diverse `*_window.txt` | Fensterpositionen / UI-State |
|
||||
|
||||
### 1.3 Cloud-Daten
|
||||
|
||||
| Dienst | Daten | Speicherort |
|
||||
|---|---|---|
|
||||
| Supabase | Synchronisierte Praxisdaten | AWS eu-central-1 |
|
||||
| OpenAI API | Keine persistente Speicherung (API-Modus, max. 30 Tage) | USA |
|
||||
|
||||
---
|
||||
|
||||
## 2. Backup-Konzept
|
||||
|
||||
### 2.1 Implementierung
|
||||
|
||||
Neues Skript: **`aza_backup.py`**
|
||||
|
||||
```
|
||||
python aza_backup.py backup # Backup erstellen
|
||||
python aza_backup.py list # Backups auflisten
|
||||
python aza_backup.py verify <f> # Integrität prüfen
|
||||
python aza_backup.py restore <f> # Wiederherstellen
|
||||
python aza_backup.py cleanup # Alte Backups entfernen
|
||||
```
|
||||
|
||||
### 2.2 Was wird gesichert
|
||||
|
||||
- Alle medizinischen JSON-Dateien (17 Dateien)
|
||||
- Alle Konfigurationsdateien (12 Dateien)
|
||||
- Alle UI-State-Dateien (11 Dateien)
|
||||
- Komplettes Ablage-Verzeichnis (KG, Briefe, Rezepte, etc.)
|
||||
- Lernmodus-Export
|
||||
- Workforce-Planner-Datenbank (SQLite)
|
||||
|
||||
### 2.3 Backup-Parameter
|
||||
|
||||
| Parameter | Wert | Konfiguration |
|
||||
|---|---|---|
|
||||
| Format | ZIP (Deflate, Level 9) | Fest |
|
||||
| Intervall | Täglich empfohlen | Manuell oder Cron/Task Scheduler |
|
||||
| Aufbewahrung | 90 Tage (Standard) | `AZA_BACKUP_KEEP_DAYS` |
|
||||
| Zielverzeichnis | `./backups/` | `AZA_BACKUP_DIR` |
|
||||
| Integrität | SHA-256 pro Datei + Manifest | Automatisch |
|
||||
| Benennung | `aza_backup_YYYY-MM-DD_HH-MM-SS.zip` | Automatisch |
|
||||
|
||||
### 2.4 Verschlüsselung
|
||||
|
||||
- **Transport:** ZIP-Dateien können auf verschlüsseltem Medium gespeichert werden
|
||||
- **Empfehlung:** Backup-Zielverzeichnis auf BitLocker-verschlüsseltem
|
||||
Laufwerk oder verschlüsseltem NAS ablegen
|
||||
- **ZIP-eigene Verschlüsselung:** Nicht implementiert (Python-zipfile
|
||||
unterstützt kein starkes AES; Laufwerksverschlüsselung wird empfohlen)
|
||||
|
||||
### 2.5 Offsite-Kopie
|
||||
|
||||
- Backup-Verzeichnis (`AZA_BACKUP_DIR`) kann auf externes Medium
|
||||
oder Netzlaufwerk zeigen
|
||||
- Empfohlen: Regelmässige Kopie auf externes verschlüsseltes Medium
|
||||
- Keine automatische Cloud-Sicherung implementiert
|
||||
|
||||
### 2.6 Automatisierung (Windows Task Scheduler)
|
||||
|
||||
```
|
||||
schtasks /create /tn "AZA_Backup" /tr "python C:\...\aza_backup.py backup" /sc daily /st 22:00
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Recovery-Konzept
|
||||
|
||||
### 3.1 Recovery Point Objective (RPO)
|
||||
|
||||
| Szenario | RPO |
|
||||
|---|---|
|
||||
| Tägliches Backup | Max. 24 Stunden Datenverlust |
|
||||
| Stündliches Backup (optional) | Max. 1 Stunde |
|
||||
|
||||
### 3.2 Recovery Time Objective (RTO)
|
||||
|
||||
| Szenario | RTO |
|
||||
|---|---|
|
||||
| Einzelne Datei | < 5 Minuten |
|
||||
| Komplettes System | < 30 Minuten |
|
||||
|
||||
### 3.3 Restore-Anleitung
|
||||
|
||||
#### Schritt 1: Verfügbare Backups anzeigen
|
||||
```
|
||||
python aza_backup.py list
|
||||
```
|
||||
|
||||
#### Schritt 2: Backup-Integrität prüfen
|
||||
```
|
||||
python aza_backup.py verify backups/aza_backup_YYYY-MM-DD_HH-MM-SS.zip
|
||||
```
|
||||
|
||||
#### Schritt 3: Dry-Run (was wird wiederhergestellt?)
|
||||
```
|
||||
python aza_backup.py restore backups/aza_backup_YYYY-MM-DD_HH-MM-SS.zip --dry-run
|
||||
```
|
||||
|
||||
#### Schritt 4: Tatsächliche Wiederherstellung
|
||||
```
|
||||
python aza_backup.py restore backups/aza_backup_YYYY-MM-DD_HH-MM-SS.zip
|
||||
```
|
||||
|
||||
**Sicherheitsmechanismus:** Vor dem Restore wird automatisch eine
|
||||
Pre-Restore-Sicherung der aktuellen Daten erstellt (in `backups/.pre_restore_*/`),
|
||||
sodass der Restore rückgängig gemacht werden kann.
|
||||
|
||||
### 3.4 Test-Ergebnisse (22.02.2026)
|
||||
|
||||
| Test | Ergebnis |
|
||||
|---|---|
|
||||
| Backup erstellen | PASS – 44 Dateien, 0.06 MB |
|
||||
| Backup verifizieren (SHA-256) | PASS – alle Checksummen korrekt |
|
||||
| Restore Dry-Run | PASS – 44 Dateien korrekt aufgelistet |
|
||||
| Backup auflisten | PASS – Datum, Grösse, Name korrekt |
|
||||
| Löschung Dry-Run | PASS – Warnung zu Backups korrekt |
|
||||
|
||||
---
|
||||
|
||||
## 4. Löschkonzept
|
||||
|
||||
### 4.1 Löschfristen
|
||||
|
||||
| Datenkategorie | Aufbewahrungsfrist | Rechtsgrundlage |
|
||||
|---|---|---|
|
||||
| Krankengeschichten | 10–20 Jahre (kantonal) | Kantonale Gesundheitsgesetze |
|
||||
| Arztbriefe | 10–20 Jahre | Kantonale Gesundheitsgesetze |
|
||||
| Rezepte | 10 Jahre | OR Art. 958f |
|
||||
| Mitarbeiterdaten | Anstellungsdauer + 5 Jahre | OR Art. 128 |
|
||||
| E-Mail-Kontakte | Bis Löschung durch Benutzer | DSG Art. 6 |
|
||||
| Backups | 90 Tage (konfigurierbar) | Intern |
|
||||
|
||||
### 4.2 Technische Umsetzung
|
||||
|
||||
#### Automatische Backup-Bereinigung
|
||||
```
|
||||
python aza_backup.py cleanup
|
||||
```
|
||||
Entfernt Backups älter als `AZA_BACKUP_KEEP_DAYS` (Standard: 90 Tage).
|
||||
|
||||
#### Patientendaten löschen (Recht auf Vergessenwerden)
|
||||
```
|
||||
# Dry-Run (nur prüfen, was gelöscht wird)
|
||||
python aza_backup.py delete-patient "Nachname Vorname"
|
||||
|
||||
# Tatsächliche Löschung
|
||||
python aza_backup.py delete-patient "Nachname Vorname" --execute
|
||||
```
|
||||
|
||||
### 4.3 Lösch-Workflow
|
||||
|
||||
1. **Antrag:** Patient stellt Löschanfrage (schriftlich empfohlen)
|
||||
2. **Prüfung:** Arzt prüft, ob gesetzliche Aufbewahrungspflicht besteht
|
||||
3. **Dry-Run:** `delete-patient --dry-run` zeigt betroffene Dateien
|
||||
4. **Dokumentation:** Löschanfrage und Ergebnis im Audit-Log festhalten
|
||||
5. **Ausführung:** `delete-patient --execute`
|
||||
6. **Backups:** Bestehende Backups enthalten noch Daten – nach Ablauf
|
||||
der Aufbewahrungsfrist (90 Tage) werden diese automatisch entfernt
|
||||
7. **Cloud:** Supabase-Daten manuell löschen (aktuell kein API-Endpunkt)
|
||||
|
||||
### 4.4 Einschränkungen
|
||||
|
||||
- Löschung in bestehenden Backups nur durch Warten auf Ablauf
|
||||
oder manuelles Löschen der betroffenen Backups
|
||||
- Supabase-Cloud-Daten müssen manuell gelöscht werden
|
||||
- OpenAI-API-Daten werden gemäss OpenAI nach max. 30 Tagen gelöscht
|
||||
- Namensbasierte Suche – funktioniert nur bei Dateinamen / JSON-Inhalt
|
||||
mit Patientenname
|
||||
|
||||
---
|
||||
|
||||
## 5. Geänderte / Neue Dateien
|
||||
|
||||
| Datei | Aktion |
|
||||
|---|---|
|
||||
| `aza_backup.py` | NEU – Backup, Verify, Restore, Cleanup, Löschung |
|
||||
| `backups/` | NEU – Backup-Verzeichnis (automatisch erstellt) |
|
||||
|
||||
---
|
||||
|
||||
## 6. Risiken
|
||||
|
||||
| Risiko | Bewertung | Massnahme |
|
||||
|---|---|---|
|
||||
| Kein automatischer Backup-Schedule | MITTEL | Task Scheduler einrichten |
|
||||
| ZIP nicht AES-verschlüsselt | MITTEL | Laufwerksverschlüsselung nutzen |
|
||||
| Keine Offsite-Kopie konfiguriert | HOCH | `AZA_BACKUP_DIR` auf NAS setzen |
|
||||
| Supabase-Löschung manuell | MITTEL | API-Endpunkt implementieren |
|
||||
| Namensbasierte Löschung unvollständig | NIEDRIG | Erweiterte Suche implementieren |
|
||||
| Kein inkrementelles Backup | NIEDRIG | Bei Datenwachstum nachrüsten |
|
||||
Reference in New Issue
Block a user