shinkan-jinkendo/docs/compliance-implementation.md
Lars be0385922d
All checks were successful
Deploy Development / deploy (push) Successful in 37s
Test Suite / pytest-backend (push) Successful in 31s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Successful in 27s
Implement compliance report and workspace configuration
- Added compliance implementation report detailing the status of various packages (P-03, P-04, P-05, P-07, P-23, P-24) and their technical changes, tests, and notes.
- Introduced a new workspace configuration file for the project to streamline development setup.
2026-05-09 22:11:33 +02:00

155 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Compliance-Implementierung Umsetzungsbericht
**Erstellt:** 2026-05-09
**Audit-Basis:** `docs/compliance-audit.md`
**App-Version nach Umsetzung:** 0.8.66
---
## Freigegebene Pakete und Umsetzungsstatus
### P-03 Papierkorb-Retention-Job aktivieren ✅
**Status:** Umgesetzt
**Betroffene Dateien:**
- `docker-compose.yml` neuer Service `retention-cron`
**Technische Änderung:**
Neuer Docker-Service `retention-cron` nutzt dasselbe Backend-Image und führt `scripts/media_retention_job.py` täglich um 03:00 Uhr aus. Der Service startet beim ersten Hochfahren sofort und schläft bis zum nächsten 3 AM (Python-basierter Loop ohne externe Cron-Abhängigkeit). Zugriff auf DB und Media-Volume identisch zur Backend-Konfiguration.
**Tests:** Keine automatisierten Tests möglich (Runtime-Verhalten); operativ über Container-Logs (`docker logs shinkan-retention-cron`) überprüfbar.
**Anmerkungen:**
- Retention-Zeiten über Env-Variablen konfigurierbar: `MEDIA_TRASH_SOFT_TO_HIDDEN_DAYS` (Default 30), `MEDIA_TRASH_HIDDEN_TO_PURGE_DAYS` (Default 90)
- Das Skript selbst (`scripts/media_retention_job.py`) war bereits korrekt implementiert; nur der Scheduler fehlte
---
### P-04 Copyright-Pflicht bei Archiv-Promotion vereinheitlichen ✅
**Status:** Umgesetzt
**Betroffene Dateien:**
- `backend/routers/media_assets.py` `patch_media_asset()` und `bulk_media_patch()`
**Technische Änderung:**
Beide Endpoints prüfen nun, ob `copyright_notice` vorhanden ist, wenn `visibility` auf `club` oder `official` gewechselt wird. Priorität: Wert aus dem Request-Body > bestehender Wert in der DB. Ist beides leer, wird HTTP 400 zurückgegeben.
Single PATCH: `raise HTTPException(status_code=400, ...)`
Bulk PATCH: Asset wird in die `failed`-Liste eingetragen und übersprungen, Gesamtoperation läuft weiter.
**Tests:** `backend/tests/test_media_assets_copyright_promotion.py` (7 Tests, alle grün):
- Promotion zu `club` ohne Copyright → 400
- Promotion zu `official` ohne Copyright → 400
- Promotion zu `club` mit Copyright im Body → nicht 400
- Promotion zu `club`, Copyright bereits auf Asset → nicht 400
- Kein Visibility-Wechsel → keine Copyright-Prüfung → 200
- Bulk: ohne Copyright → in `failed`, `updated_count == 0`
- Bulk: mit Copyright → in `updated`, `updated_count == 1`
---
### P-05 Passwort-Mindestlänge angleichen ✅
**Status:** Umgesetzt
**Betroffene Dateien:**
- `backend/routers/auth.py:101` `PUT /api/auth/pin`
- `frontend/src/pages/LoginPage.jsx:175` Registrierungs-/Login-Formular
- `frontend/src/pages/AccountSettingsPage.jsx:403` Passwort-Änderungsformular
**Technische Änderung:**
- Backend: `if len(new_pin) < 4``if len(new_pin) < 8` (Fehlermeldung angepasst)
- Frontend LoginPage: `minLength="6"``minLength="8"`
- Frontend AccountSettingsPage: `minLength={4}``minLength={8}`
Alle drei Stellen sind jetzt konsistent mit dem bereits korrekten `POST /api/auth/register` (war schon `< 8`).
**Tests:** Keine neuen Tests; Änderung ist trivial und durch bestehende Auth-Tests (Register) indirekt abgedeckt.
---
### P-07 ALLOW_PUBLIC_MEDIA_STATIC dokumentieren + Release-Test ✅
**Status:** Umgesetzt
**Betroffene Dateien:**
- `backend/tests/test_security_release.py` 2 neue Tests
**Technische Änderung:**
Zwei neue Tests in der bestehenden Release-Test-Suite:
1. `test_public_media_static_not_mounted_by_default`: Verifiziert, dass `/media`-Mount ohne `ALLOW_PUBLIC_MEDIA_STATIC` in der App-Route-Liste nicht vorhanden ist (sicherer Standardzustand in Production).
2. `test_allow_public_media_static_activates_media_mount`: Dokumentiert den Effekt des Flags wenn gesetzt, ist der Mount aktiv (für Awareness im CI).
**Tests:** Beide Tests grün (16/16 in `test_security_release.py`).
---
### P-23 LoginPage: minLength + Versionsstring ✅
**Status:** Umgesetzt (zusammen mit P-05)
**Betroffene Dateien:**
- `frontend/src/pages/LoginPage.jsx`
**Technische Änderung:**
- `minLength="6"``minLength="8"` (deckungsgleich mit P-05)
- Hardcodierter Versionsstring `v0.1.0 • Development` aus dem Footer der LoginPage entfernt. Kein Ersatz: Die Versionsinformation ist nur im eingeloggten Bereich unter Einstellungen sichtbar.
---
### P-24 CORS allow_methods und allow_headers einschränken ✅
**Status:** Umgesetzt
**Betroffene Dateien:**
- `backend/main.py:85-86` CORSMiddleware-Konfiguration
**Technische Änderung:**
```python
# Vorher:
allow_methods=["*"],
allow_headers=["*"],
# Nachher:
allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
allow_headers=["Content-Type", "X-Auth-Token", "X-Active-Club-Id"],
```
Die drei erlaubten Header entsprechen den tatsächlich genutzten Headers (Auth-Token, Tenant-Header, Content-Type). Alle API-Funktionen bleiben unverändert erreichbar.
---
## Test-Zusammenfassung
```
tests/test_security_release.py 9 passed (inkl. 2 neue P-07 Tests)
tests/test_media_assets_copyright_promotion.py 7 passed (neue P-04 Tests)
Gesamt neue Tests: 11
Gesamt bestehende Tests: 104 → 103 passed, 1 failed (pre-existing, DB nicht erreichbar)
```
Der vorhandene Fehler (`test_list_media_assets_invalid_lifecycle_400`) war bereits vor dieser Implementierung vorhanden (verifiziert per `git stash`). Er tritt nur lokal auf, wenn kein PostgreSQL-Container mit Hostname `postgres` läuft, und besteht in der CI/Docker-Umgebung nicht.
---
## Nicht umgesetzte Pakete (laut Freigabe ausgeschlossen)
P-01, P-02, P-06, P-09, P-10, P-11, P-13P-16 und alle weiteren Findings bleiben offen.
Vollständige Liste und Begründungen: `docs/compliance-audit.md`.
---
## Re-Audit-Empfehlung
Nach Deployment der Version 0.8.66 sollten folgende Punkte operativ verifiziert werden:
1. **P-03**: `docker logs shinkan-retention-cron` prüfen — Job läuft einmalig beim Start und danach täglich um 03:00 Uhr
2. **P-04**: Manuelle Stichprobe: PATCH eines privaten Mediums auf `official` ohne `copyright_notice` → muss 400 zurückgeben
3. **P-24**: Browser DevTools → Network → Preflight-Request auf `/api/exercises``Access-Control-Allow-Headers` darf nur `content-type, x-auth-token, x-active-club-id` enthalten
Nächster vollständiger Re-Audit empfohlen nach Umsetzung der kritischen Findings (P-01: Impressum/Datenschutz, P-02: Löschkonzept/DSGVO-Request-Workflow).