docs(compliance): P-06 fachlich-technische Spezifikation erstellt
Some checks failed
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 33s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 11s
Test Suite / playwright-tests (push) Failing after 53s
Some checks failed
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 33s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 11s
Test Suite / playwright-tests (push) Failing after 53s
- docs/p06-upload-rights-spec.md (neu): vollständige Spezifikation für Upload-Einwilligungsdialog (§22 KUG, §8 DSGVO, Minderjährigenschutz) — IST-Analyse, Entscheidungsmatrix, Zielmodell (media_asset_rights_declarations + 3 neue Felder in media_assets), 10 Ziel-Flows, Legacy-Konzept, 12 juristische Klärungspunkte, Umsetzungsplan P-06a–P-06e - compliance-roadmap.md: Blocker 2 (P-06) mit Spec-Hinweis und juristischer Klärungsliste; §6 Freigabe-Empfehlung aktualisiert - compliance-package-register.md: P-06 Letzter Stand mit Spec-Verweis und Zielmodell-Zusammenfassung ergänzt - compliance-implementation.md: P-06 in Tabelle mit Spec-Hinweis Keine Code-Umsetzung; Umsetzung erst nach juristischer Klärung. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
aff3020b13
commit
8cda5c27ec
|
|
@ -383,7 +383,7 @@ Anmerkung jsPDF (0.8.74):
|
|||
|-------|------------------|--------|------------|
|
||||
| P-01 | Rechtstexte | offen | Scope ausgeschlossen (juristischer Inhalt) |
|
||||
| P-02 | Self-Service-Kontolöschung + Datenexport | offen | Scope ausgeschlossen |
|
||||
| P-06 | Upload-Einwilligungsdialog (Recht am eigenen Bild) | offen | Scope ausgeschlossen |
|
||||
| P-06 | Upload-Einwilligungsdialog (Recht am eigenen Bild) | offen | Scope ausgeschlossen — Spezifikation erstellt (2026-05-10): `docs/p06-upload-rights-spec.md`; keine Code-Umsetzung |
|
||||
| P-08 | HSTS / externe Proxy-Sicherheit dokumentieren | offen | Scope ausgeschlossen (außerhalb Repo — Reverse-Proxy) |
|
||||
| P-09 | Admin-Audit-Log | offen | Scope ausgeschlossen |
|
||||
| P-10 | Mindestalter-Abfrage | offen | Scope ausgeschlossen |
|
||||
|
|
|
|||
|
|
@ -124,8 +124,8 @@
|
|||
| **Findings** | KRIT-04 |
|
||||
| **Etappe** | 1 |
|
||||
| **Status** | ❌ open |
|
||||
| **Letzter Stand** | Nicht umgesetzt. Keine Pflicht-Einwilligung beim Medienupload. Juristisch zu prüfen (§22 KUG, §8 DSGVO). |
|
||||
| **Verweise** | `docs/compliance-audit.md` §8.2, §8.3, §11.4, §17 |
|
||||
| **Letzter Stand** | Nicht umgesetzt. Keine Pflicht-Einwilligung beim Medienupload. Juristisch zu prüfen (§22 KUG, §8 DSGVO). **Fachlich-technische Spezifikation erstellt (2026-05-10):** `docs/p06-upload-rights-spec.md` — Zielmodell: neue Tabelle `media_asset_rights_declarations` (append-only Einwilligungslog) + 3 neue Felder in `media_assets` (`rights_status`, `rights_declared_for_visibility`, `rights_declared_at`); abgestufte Einwilligungslogik nach Sichtbarkeit (upload/club/official); Legacy-Konzept für bestehende Medien (`rights_status = 'legacy_unreviewed'`); Umsetzungsplan P-06a–P-06e. Umsetzung erst nach Entscheidung über 12 juristische Klärungspunkte (§22 KUG, §8 DSGVO, Minderjährigenschutz, Widerrufsrecht) — vollständige Liste in `docs/p06-upload-rights-spec.md` §7. |
|
||||
| **Verweise** | `docs/compliance-audit.md` §8.2, §8.3, §11.4, §17; `docs/p06-upload-rights-spec.md` |
|
||||
| **Hinweise** | **Drift-Hinweis:** In `docs/compliance-implementation.md` (vor Korrektur 2026-05-10) wurde P-06 fälschlich als „HSTS-Header" beschrieben. Der korrekte Titel ist „Upload-Einwilligungsdialog". HSTS gehört zu P-08. Korrigiert in `docs/compliance-implementation.md`. |
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -99,7 +99,9 @@ Die folgenden Pakete sind vor der Freigabe für allgemeine öffentliche Registri
|
|||
|
||||
**Finding:** KRIT-04 (§22 KUG, §8 DSGVO)
|
||||
**Warum zwingend:** Jeder hochgeladene Bildinhalt mit erkennbaren Personen ist ohne dokumentierte Einwilligung rechtlich problematisch. Das Risiko besteht nicht erst bei öffentlichen Inhalten — es beginnt beim Upload.
|
||||
**Abhängigkeit:** Keine; kann als Frontend-Dialog mit Backend-Flag implementiert werden.
|
||||
**Abhängigkeit:** Keine; kann als Frontend-Dialog mit Backend-Flag implementiert werden.
|
||||
**Spezifikation:** Fachlich-technische Spezifikation erstellt (2026-05-10): `docs/p06-upload-rights-spec.md`. Enthält IST-Analyse, Entscheidungsmatrix, Zielmodell (neue Tabelle `media_asset_rights_declarations` + 3 neue Felder in `media_assets`), 10 Ziel-Flows, Legacy-Konzept für bestehende Medien, Umsetzungsplan P-06a–P-06e.
|
||||
**Vor Umsetzung zu klären (12 Punkte):** §22-KUG-Anforderungen im Vereinskontext, Minderjährigenschutz, Einwilligungs-Widerrufsrecht, Speicherfristen — vollständige Klärungsliste in `docs/p06-upload-rights-spec.md` §7.
|
||||
|
||||
### Blocker 3 — P-11: Legal-Hold Lifecycle-Status
|
||||
|
||||
|
|
@ -225,11 +227,13 @@ Erst wenn diese Fragen beantwortet und als Spec dokumentiert sind, wird P-02 in
|
|||
|
||||
**P-01 + P-01b + P-01c technisch vollständig umgesetzt (Version 0.8.74).** Rechtstexte über Login, Desktop-Sidebar und Einstellungen → Rechtliches (Mobile/PWA) erreichbar. Superadmin kann über `/admin/legal-documents` versionierte Rechtstexte anlegen, bearbeiten (inkl. Abschnitts-Sortierung und Einfügen an beliebiger Stelle), als Entwurf kopieren, veröffentlichen und als PDF herunterladen — sobald Inhalte eingepflegt sind, verschwindet der Platzhalter-Banner automatisch. Juristische Inhalte bleiben offen (Betreiber + Rechtsanwalt).
|
||||
|
||||
Die nächste technische Freigabe sollte **Etappe B** umfassen — beginnend mit dem kleinsten Paket:
|
||||
Die nächste technische Freigabe sollte **Etappe B** umfassen — beginnend mit P-06:
|
||||
|
||||
**P-06 Spezifikation vorhanden** (`docs/p06-upload-rights-spec.md`, 2026-05-10). Die Umsetzung setzt die Entscheidung über 12 juristische Klärungspunkte voraus (§22 KUG im Vereinskontext, §8 DSGVO Minderjährigenschutz, Widerrufsrecht, Speicherfristen für Einwilligungen). Erst nach dieser Klärung:
|
||||
|
||||
> „Freigabe zur Umsetzung P-06: Upload-Einwilligungsdialog"
|
||||
|
||||
oder als Paket:
|
||||
oder als Paket (nach Klärung P-06):
|
||||
|
||||
> „Freigabe zur Umsetzung Etappe B: P-06, P-11, P-13"
|
||||
|
||||
|
|
@ -353,7 +357,7 @@ Diese Punkte liegen außerhalb des Code-Scopes und erfordern organisatorische Ma
|
|||
| ~~P-01 technisch~~ | ~~„Freigabe zur Umsetzung P-01: Rechtstexte technisch anlegen"~~ | ✅ historisch abgeschlossen (Version 0.8.69) |
|
||||
| ~~P-01b~~ | ~~„Freigabe zur Umsetzung P-01b: Mobile/PWA-Zugriff auf Rechtliches"~~ | ✅ historisch abgeschlossen (Version 0.8.70) |
|
||||
| ~~P-01c~~ | ~~„Freigabe zur Umsetzung P-01c: Admin-konfigurierbare Rechtstexte"~~ | ✅ historisch abgeschlossen (Version 0.8.71); Erweiterungen copy-as-draft (0.8.72) + jsPDF/Sortierung (0.8.74) |
|
||||
| **P-06 (empfohlen)** | **„Freigabe zur Umsetzung P-06: Upload-Einwilligungsdialog"** | ⬅ nächste empfohlene Freigabe |
|
||||
| **P-06 (empfohlen)** | **„Freigabe zur Umsetzung P-06: Upload-Einwilligungsdialog"** | ⬅ nächste empfohlene Freigabe — Spec vorhanden (`docs/p06-upload-rights-spec.md`); Umsetzung erst nach juristischer Klärung (§7 der Spec) |
|
||||
| Etappe B komplett | „Freigabe zur Umsetzung Etappe B: P-06, P-11, P-13" | offen |
|
||||
| P-02 Spezifikation | „Freigabe zur Spezifikation P-02: DSGVO-Self-Service-Prozess" | offen |
|
||||
|
||||
|
|
|
|||
720
docs/p06-upload-rights-spec.md
Normal file
720
docs/p06-upload-rights-spec.md
Normal file
|
|
@ -0,0 +1,720 @@
|
|||
# P-06 – Fachlich-technische Spezifikation: Upload-Einwilligungsdialog
|
||||
|
||||
**Paket-ID:** P-06 (kanonisch, unveränderlich)
|
||||
**Kanonischer Titel:** Upload-Einwilligungsdialog (Recht am eigenen Bild, Personen, Minderjährige)
|
||||
**Dokument-Typ:** Spezifikation — keine Umsetzungsfreigabe
|
||||
**Erstellt:** 2026-05-10
|
||||
**App-Version bei Erstellung:** 0.8.74
|
||||
**Status P-06:** ❌ offen — Umsetzung erst nach Entscheidung zu offenen juristischen Punkten
|
||||
**Rechtlicher Hinweis:** Alle als „juristisch zu prüfen" markierten Einschätzungen sind keine Rechtsberatung. Keine konkrete Textfassung von Erklärungen in diesem Dokument — Formulierungen obliegen dem Rechtsanwalt.
|
||||
|
||||
---
|
||||
|
||||
## 1. Kontext und Ziel
|
||||
|
||||
### 1.1 Ausgangslage (Initial-Audit-Befund)
|
||||
|
||||
Das Initial-Audit (`docs/compliance-audit.md`, §8.2–8.3) identifiziert folgende Lücken:
|
||||
|
||||
- Keine verbindliche Rechteerklärung beim Medienupload
|
||||
- Keine Abfrage, ob erkennbare Personen enthalten sind
|
||||
- Keine Abfrage, ob Minderjährige abgebildet sind
|
||||
- Keine Abfrage, ob erforderliche Einwilligungen abgebildeter Personen vorliegen
|
||||
- Keine Dokumentation, wer wann welche Erklärung abgegeben hat
|
||||
|
||||
### 1.2 Regulatorische Prüfanker (technische Modellierung)
|
||||
|
||||
| Norm | Relevanz für Datenmodell | Juristisch zu prüfen |
|
||||
|------|--------------------------|----------------------|
|
||||
| § 22 KUG | Bildnisse erkennbarer Personen erfordern Einwilligung vor Verbreitung/Zurschaustellung | Gilt auch für vereinsinterne Sichtbarkeit? |
|
||||
| Art. 8 DSGVO | Bei Minderjährigen ggf. Einwilligung Erziehungsberechtigter | Ab welchem Alter? Welche Mechanismen? |
|
||||
| § 19a UrhG | Öffentliche Zugänglichmachung = eigener Nutzungstatbestand | Ab wann gilt `official` als „öffentlich zugänglich"? |
|
||||
| DSGVO Art. 5(1)(e) | Datenminimierung — welche Nachweisdaten dürfen gespeichert werden? | Was ist verhältnismäßig? |
|
||||
|
||||
### 1.3 Ziel dieser Spezifikation
|
||||
|
||||
P-06 soll sicherstellen, dass:
|
||||
|
||||
1. Jeder Medien-Upload mit einer strukturierten, gespeicherten Rechteerklärung verknüpft ist
|
||||
2. Die Erklärung nach Sichtbarkeitsstufe gestuft wird (private minimal, official vollständig)
|
||||
3. Bestehende Prüfungen aus P-04 (copyright_notice) komplementär erhalten bleiben
|
||||
4. Juristische Textanpassungen ohne Codeänderungen möglich sind (Versionierung)
|
||||
5. Altmedien ohne rückwirkenden Zwang behandelt werden können
|
||||
6. Backend-Erzwingung (keine reine Frontend-Kosmetik) besteht
|
||||
|
||||
---
|
||||
|
||||
## 2. IST-Analyse
|
||||
|
||||
### 2.1 Upload-Pfade (vollständige Bestandsaufnahme)
|
||||
|
||||
| # | Endpoint | Datei | Upload-Typ | Sichtbarkeit wählbar | Copyright bei Upload |
|
||||
|---|----------|-------|-----------|---------------------|----------------------|
|
||||
| U1 | `POST /api/exercises/{id}/media` | `routers/exercises.py:2518` | Einzeldatei oder Embed-URL | Folgt Übungssichtbarkeit (implizit) | Nicht abgefragt |
|
||||
| U2 | `POST /api/media-assets/bulk-upload` | `routers/media_assets.py:787` | 1–n Dateien | `visibility` + `club_id` als Form-Parameter | Optional (`copyright_notice` fehlt im POST-Body, nur via PATCH nachträglich) |
|
||||
|
||||
**Kein weiterer Upload-Endpoint vorhanden** (geprüft über Codebase-Suche nach `UploadFile`).
|
||||
|
||||
**Weitere indirekte Upload-Pfade:**
|
||||
- `POST /api/exercises/{id}/media/from-asset` (`exercises.py`) — verknüpft ein bestehendes Archiv-Asset mit einer Übung; kein Upload, kein neues Medium
|
||||
- Embed-URL (`embed_url`, `embed_platform`) — keine Datei, keine Rechteerklärung für Dateiinhalte; externe Plattform verantwortlich
|
||||
|
||||
### 2.2 Promotionspfade (Sichtbarkeitsänderung)
|
||||
|
||||
| # | Endpoint | Datei | Mögliche Promotion |
|
||||
|---|----------|-------|--------------------|
|
||||
| PR1 | `PATCH /api/media-assets/{id}` | `routers/media_assets.py:1223` | private→club, private→official, club→official, auch Rückstufung |
|
||||
| PR2 | `POST /api/media-assets/bulk-patch` | `routers/media_assets.py:1094` | Massenpromotion, gleiche Richtungen |
|
||||
| PR3 | Implizit bei `PUT /api/exercises/{id}` | `routers/exercises.py` | Übungssichtbarkeit→club/official löst `apply_official_exercise_media_rules()` oder `apply_club_exercise_media_copyright_rules()` aus |
|
||||
|
||||
**Rückstufungen** (official→club, club→private) werden nicht gesperrt — juristisch zu prüfen, ob Rückstufung Rechte-Konsequenzen hat.
|
||||
|
||||
### 2.3 Datenmodell `media_assets` (Migration 045 + 046)
|
||||
|
||||
```
|
||||
media_assets
|
||||
├── id SERIAL PK
|
||||
├── mime_type VARCHAR(100)
|
||||
├── byte_size INT
|
||||
├── sha256 CHAR(64) NOT NULL
|
||||
├── original_filename VARCHAR(300)
|
||||
├── visibility VARCHAR(32) NOT NULL DEFAULT 'private' ← Sichtbarkeitsstufe
|
||||
├── club_id INT REFERENCES clubs(id) ← Vereinszuordnung
|
||||
├── uploaded_by_profile_id INT REFERENCES profiles(id) ← Uploader
|
||||
├── copyright_notice TEXT ← Urheberrechtshinweis (P-04)
|
||||
├── storage_backend VARCHAR(32)
|
||||
├── storage_key TEXT NOT NULL UNIQUE
|
||||
├── lifecycle_state VARCHAR(32) DEFAULT 'active'
|
||||
├── trash_soft_at, trash_hidden_at, purge_after_at TIMESTAMP
|
||||
├── created_at, updated_at TIMESTAMP
|
||||
└── tags TEXT[] DEFAULT '{}'
|
||||
```
|
||||
|
||||
**Fehlende P-06-Felder:** Keine Einwilligungsfelder vorhanden. Keine Personenabbildungsmarkierung. Keine Deklarations-Versionierung.
|
||||
|
||||
### 2.4 Rollen und Berechtigungen (Zusammenfassung `_item_permissions()`)
|
||||
|
||||
| Aktion | private | club | official |
|
||||
|--------|---------|------|----------|
|
||||
| Upload (neu) | Jeder authentifizierte Nutzer | Vereinsmitglied + club_id | Nur Superadmin |
|
||||
| `edit_metadata` | Superadmin, Plattform-Admin, Uploader | Superadmin, Plattform-Admin, Club-Admin | Nur Superadmin |
|
||||
| Promotion zu club | Eigener Upload: Uploader; Club-Asset: Club-Admin | — | — |
|
||||
| Promotion zu official | Nur Superadmin | Nur Superadmin | — |
|
||||
| Lifecycle (trash) | Uploader, Plattform-Admin, Superadmin | Club-Admin, Plattform-Admin, Superadmin | Nur Superadmin |
|
||||
|
||||
### 2.5 Bestehende Frontend-Dialoge
|
||||
|
||||
| Stelle | Datei | Aktuelles Verhalten |
|
||||
|--------|-------|---------------------|
|
||||
| Übungsformular Medienupload | `ExerciseFormPage.jsx` | Datei-Picker, kein Einwilligungsdialog |
|
||||
| Archiv Bulk-Upload | `MediaLibraryPage.jsx` | Datei-Picker + optional `copyright_notice` im Editmodal, kein Pflichtdialog |
|
||||
| Übung → official (API-Error) | `ExerciseFormPage.jsx:624` | `window.prompt()` für copyright_notice nach 422-Fehler — reaktiv, kein proaktiver Dialog |
|
||||
| Archiv PATCH Sichtbarkeit | `MediaLibraryPage.jsx` | Backend wirft 400 wenn copyright fehlt; Frontend-Feedback unklar |
|
||||
|
||||
**Ergebnis:** Kein proaktiver strukturierter Einwilligungsdialog vorhanden. Alle Copyright-Abfragen sind reaktiv (nach API-Fehler) oder optional.
|
||||
|
||||
### 2.6 Bestehende Copyright-Prüfungen P-04 (Referenz)
|
||||
|
||||
P-04 erzwingt `copyright_notice` bei Promotion zu `club` oder `official`:
|
||||
- `patch_media_asset()`: HTTP 400 wenn `copyright_notice` leer bei Ziel club/official
|
||||
- `bulk_media_patch()`: Asset in `failed`-Liste wenn copyright fehlt
|
||||
- `apply_official_exercise_media_rules()`: HTTP 422 `OFFICIAL_MEDIA_CONFIRM_REQUIRED` wenn Assets kein copyright
|
||||
- Mindestlänge: 3 Zeichen (`_MIN_OFFICIAL_MEDIA_COPYRIGHT_LEN = 3`)
|
||||
|
||||
**Verhältnis zu P-06:** P-04 (copyright_notice) = Attribution für Dritte (wer besitzt das Recht). P-06 = Selbsterklärung des Uploaders (habe ich das Recht, dieses Medium hochzuladen). Ergänzend, nicht konkurrierend.
|
||||
|
||||
### 2.7 IST-Lücken (P-06-spezifisch)
|
||||
|
||||
| Lücke | Schwere |
|
||||
|-------|---------|
|
||||
| Kein Pflichtfeld „Ich bin Rechteinhaber" beim Upload | Kritisch (Grundlage aller Uploads) |
|
||||
| Keine Abfrage „erkennbare Personen enthalten?" | Hoch (§ 22 KUG-Risiko bei club/official) |
|
||||
| Keine Abfrage „Minderjährige enthalten?" | Hoch (Art. 8 DSGVO, besonderer Schutz) |
|
||||
| Keine Speicherung von Einwilligungszeitpunkt und -version | Hoch (Nachweisbarkeit) |
|
||||
| Keine Erzwingung im Backend (nur Frontend-Checkbox wäre zu wenig) | Kritisch |
|
||||
| Kein Einwilligungslog (wer hat wann welche Version bestätigt?) | Hoch |
|
||||
| copyright_notice beim Erstupload nicht abgefragt | Mittel (P-04 fragt erst bei Promotion) |
|
||||
|
||||
### 2.8 Altbestandsrisiken
|
||||
|
||||
- Alle bestehenden `media_assets`-Zeilen haben keine Einwilligungsmetadaten
|
||||
- Unbekannt, ob bei bestehenden Medien erkennbare Personen/Minderjährige abgebildet sind
|
||||
- Medien mit `visibility=club` oder `visibility=official` existieren ohne dokumentierte Einwilligung
|
||||
- Superadmin kann bestehende official-Medien weiter sehen/nutzen ohne Nachdeklaration
|
||||
- Bei Neuzuweisung zu einer anderen Übung werden bestehende Medien ohne Prüfung verknüpft
|
||||
|
||||
---
|
||||
|
||||
## 3. Entscheidungsmatrix
|
||||
|
||||
Anforderungen nach **Sichtbarkeitsstufe** (Zeilen) × **Aktion** (Spalten). „Pflicht" = Backend-Sperre wenn fehlend. „Optional" = abfragen aber nicht erzwingen.
|
||||
|
||||
| Aktion → | Erstupload | Promotion club | Promotion official | Metadaten-Edit | Reuse in neuer Übung |
|
||||
|-----------|-----------|---------------|-------------------|---------------|---------------------|
|
||||
| **private** | `rights_holder`: Pflicht; Personen-Fragen: optional | — | — | Keine P-06-Pflicht | Keine P-06-Pflicht |
|
||||
| **club** | `rights_holder`: Pflicht; `contains_persons`: Pflicht; `person_consent`: Pflicht wenn Personen | `contains_persons` + `person_consent`: Pflicht; `contains_minors`: Pflicht | — | Keine P-06-Pflicht | Keine P-06-Pflicht |
|
||||
| **official** | Alles Pflicht | Alles Pflicht | Alle Felder Pflicht + copyright_notice (P-04) | Keine P-06-Pflicht | Keine P-06-Pflicht |
|
||||
|
||||
**B: Medieninhalt — Konsequenzen:**
|
||||
|
||||
| Inhalt | private | club | official |
|
||||
|--------|---------|------|----------|
|
||||
| Keine erkennbaren Personen | `person_consent` entfällt | `person_consent` entfällt | `person_consent` entfällt |
|
||||
| Erkennbare Erwachsene | Optional zu deklarieren | Einwilligung Pflicht (juristisch zu prüfen) | Einwilligung Pflicht |
|
||||
| Erkennbare Minderjährige | Optional zu deklarieren | Einwilligung Erziehungsberechtigter Pflicht (juristisch zu prüfen) | Einwilligung Pflicht |
|
||||
| Unklar / nicht beantwortet | Zulässig bei private | Blockiert bei club/official | Blockiert |
|
||||
|
||||
**C: Rechteinhalt — Konsequenzen:**
|
||||
|
||||
| Inhalt | Konsequenz |
|
||||
|--------|-----------|
|
||||
| Nutzer ist selbst Urheber | `rights_holder_confirmed = true` genügt |
|
||||
| Nutzer hat Nutzungsrechte | `rights_holder_confirmed = true` genügt; copyright_notice sollte Rechteinhaber nennen |
|
||||
| Drittmaterial enthalten | `rights_holder_confirmed = true` nur wenn Lizenz vorhanden; copyright_notice Pflicht bei club/official |
|
||||
| Musik enthalten | `contains_music = true`; `music_rights_confirmed` Pflicht (juristisch zu prüfen) |
|
||||
| Logos/Marken/sonstige Fremdinhalte | Fällt unter `rights_holder_confirmed`; juristisch zu prüfen |
|
||||
|
||||
**D: Aktion — Blockierungslogik:**
|
||||
|
||||
| Aktion | Fehlendes Pflichtfeld | Verhalten Backend |
|
||||
|--------|----------------------|-------------------|
|
||||
| Upload | rights_holder_confirmed fehlt | HTTP 400 `RIGHTS_DECLARATION_REQUIRED` |
|
||||
| Promotion club | contains_persons / person_consent fehlt | HTTP 400 `CONSENT_REQUIRED_FOR_CLUB` |
|
||||
| Promotion official | Beliebiges Pflichtfeld fehlt | HTTP 400 `CONSENT_REQUIRED_FOR_OFFICIAL` |
|
||||
| Promotion mit Altmedium (legacy) | rights_status = legacy_unreviewed | HTTP 400 `LEGACY_REDECLARATION_REQUIRED` |
|
||||
|
||||
---
|
||||
|
||||
## 4. Empfohlenes Zielmodell
|
||||
|
||||
### 4.1 Neue Tabelle: `media_asset_rights_declarations`
|
||||
|
||||
Append-only Audit-Log. Jede Erklärung (Upload, Promotion, Nachdeklaration) erzeugt einen neuen Eintrag. Bestehende Einträge werden nie geändert.
|
||||
|
||||
```sql
|
||||
CREATE TABLE media_asset_rights_declarations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
media_asset_id INT NOT NULL REFERENCES media_assets(id) ON DELETE CASCADE,
|
||||
declared_by_profile_id INT REFERENCES profiles(id) ON DELETE SET NULL,
|
||||
declared_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
||||
|
||||
-- Kontext
|
||||
action_type VARCHAR(50) NOT NULL
|
||||
CHECK (action_type IN (
|
||||
'upload', -- Erstupload
|
||||
'promote_club', -- Promotion zu club
|
||||
'promote_official', -- Promotion zu official
|
||||
're_declaration', -- Nachdeklaration (auf Aufforderung)
|
||||
'legacy_re_declaration' -- Altmedium: erste Deklaration nachgereicht
|
||||
)),
|
||||
target_visibility VARCHAR(32) NOT NULL, -- Sichtbarkeit für die erklärt wird
|
||||
declaration_version VARCHAR(20) NOT NULL DEFAULT 'p06-v1.0', -- Textversion der Erklärung
|
||||
|
||||
-- Pflichtfeld (alle Sichtbarkeiten)
|
||||
rights_holder_confirmed BOOLEAN NOT NULL,
|
||||
|
||||
-- Personenrechte (Pflicht ab club)
|
||||
contains_identifiable_persons BOOLEAN,
|
||||
person_consent_confirmed BOOLEAN, -- Pflicht wenn contains_identifiable_persons = true
|
||||
contains_minors BOOLEAN,
|
||||
parental_consent_confirmed BOOLEAN, -- Pflicht wenn contains_minors = true (juristisch zu prüfen)
|
||||
|
||||
-- Drittmaterial (optional MVP, Pflicht später)
|
||||
contains_music BOOLEAN,
|
||||
music_rights_confirmed BOOLEAN,
|
||||
third_party_content_confirmed BOOLEAN,
|
||||
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_mar_declarations_asset ON media_asset_rights_declarations (media_asset_id);
|
||||
CREATE INDEX idx_mar_declarations_profile ON media_asset_rights_declarations (declared_by_profile_id);
|
||||
```
|
||||
|
||||
### 4.2 Neue Felder in `media_assets`
|
||||
|
||||
Drei neue Schnellzugriffs-Felder (kein Ersatz für den Log, nur für performante Abfragen):
|
||||
|
||||
```sql
|
||||
ALTER TABLE media_assets
|
||||
ADD COLUMN rights_status VARCHAR(32)
|
||||
NOT NULL DEFAULT 'legacy_unreviewed'
|
||||
CHECK (rights_status IN ('pending', 'declared', 'legacy_unreviewed', 'blocked')),
|
||||
ADD COLUMN rights_declared_for_visibility VARCHAR(32), -- Höchste Stufe, für die erklärt wurde
|
||||
ADD COLUMN rights_declared_at TIMESTAMP WITH TIME ZONE; -- Zeitpunkt der aktuellsten Erklärung
|
||||
```
|
||||
|
||||
**Status-Semantik:**
|
||||
|
||||
| rights_status | Bedeutung |
|
||||
|---------------|-----------|
|
||||
| `legacy_unreviewed` | Bestehendes Medium ohne P-06-Daten — Altbestand |
|
||||
| `pending` | Neues Medium, Upload noch ohne Deklaration (Zwischenzustand, darf nie persistent sein) |
|
||||
| `declared` | Gültige Deklaration vorhanden für `rights_declared_for_visibility` |
|
||||
| `blocked` | Deklaration widerrufen oder durch Admin gesperrt (→ P-11/P-13 Schnittstelle) |
|
||||
|
||||
**Visibility-Hierarchie für Prüfung:**
|
||||
```
|
||||
private (1) < club (2) < official (3)
|
||||
```
|
||||
|
||||
Promotion ist erlaubt wenn: `rights_declared_for_visibility` ≥ Ziel-Visibility. Sonst ist neue Deklaration erforderlich.
|
||||
|
||||
### 4.3 Feld-Bewertung: MVP vs. später
|
||||
|
||||
| Feld | MVP-Pflicht | Sinnvoll später | Unnötig / zu früh | Juristisch abhängig |
|
||||
|------|-------------|-----------------|-------------------|---------------------|
|
||||
| `rights_holder_confirmed` | ✅ | — | — | Nein |
|
||||
| `contains_identifiable_persons` | ✅ ab club | — | — | Nein |
|
||||
| `person_consent_confirmed` | ✅ wenn Personen + ≥ club | — | — | Teilweise |
|
||||
| `contains_minors` | ✅ ab official | ✅ auch club | — | Ja (Schwelle) |
|
||||
| `parental_consent_confirmed` | — | ✅ | — | Ja (juristisch zu klären) |
|
||||
| `contains_music` | — | ✅ | — | Ja |
|
||||
| `music_rights_confirmed` | — | ✅ | — | Ja |
|
||||
| `third_party_content_confirmed` | — | ✅ | — | Teilweise |
|
||||
| `declaration_version` | ✅ | — | — | Nein |
|
||||
| `action_type` | ✅ | — | — | Nein |
|
||||
| `rights_status` in media_assets | ✅ | — | — | Nein |
|
||||
| `rights_declared_for_visibility` | ✅ | — | — | Nein |
|
||||
| Separates Upload von Einwilligungsdokumenten | — | — | Zu früh | Ja |
|
||||
| `may_be_embedded_in_exercises` | — | — | Unnötig (exercise_media-Tabelle reicht) | — |
|
||||
| `declaration_scope_*` als einzelne Booleans | — | — | Unnötig (visibility-String reicht) | — |
|
||||
|
||||
### 4.4 Designentscheidungen (mit Begründung)
|
||||
|
||||
**Entscheidung 1: Gestufte Erklärungen je Sichtbarkeitsstufe**
|
||||
|
||||
Nicht eine universale Erklärung für alle Stufen, sondern Promotion auf höhere Stufe erfordert neue Erklärung.
|
||||
|
||||
*Begründung:* Rechtliche Anforderungen steigen mit Sichtbarkeit. Private Medien: nur Eigentümer sieht sie. Official-Medien: plattformweit sichtbar (ggf. öffentlich). Stufenmodell ist rechtsanschlussfähig — spätere juristische Textanpassungen pro Stufe ohne Systemwechsel möglich.
|
||||
|
||||
**Entscheidung 2: Minimalset beim Erstupload**
|
||||
|
||||
Pflicht beim privaten Upload: nur `rights_holder_confirmed`. Personen-Fragen: optional beim Upload, Pflicht erst bei Promotion zu club/official.
|
||||
|
||||
*Begründung:* Die meisten Uploads bleiben privat und werden nie promoted. Volle Fragebogenbelastung beim Upload würde Nutzung hemmen ohne rechtlichen Mehrwert. Personen-Fragen werden erzwungen sobald der Upload für andere sichtbar wird.
|
||||
|
||||
**Entscheidung 3: Keine globale Nutzer-Einwilligung (pro Upload)**
|
||||
|
||||
Erklärung wird pro Upload abgegeben, nicht einmalig pro Nutzer.
|
||||
|
||||
*Begründung:* Jedes Medium ist inhaltlich unterschiedlich. Eine pauschale Einwilligung beim Registrieren oder einmalig je Nutzer deckt nicht ab, ob bei diesem konkreten Video Minderjährige abgebildet sind.
|
||||
|
||||
**Entscheidung 4: Append-only Audit-Log**
|
||||
|
||||
Einmal abgegebene Erklärungen werden nie geändert oder gelöscht. Neue Erklärung = neuer Eintrag.
|
||||
|
||||
*Begründung:* Nachweisbarkeit. Bei späterem Streit muss belegbar sein, was wann erklärt wurde.
|
||||
|
||||
**Entscheidung 5: Versionierung via `declaration_version`-String**
|
||||
|
||||
Wenn Rechtsanwalt Erklärungstexte ändert, wird die neue Version als "p06-v1.1" deklariert. Keine Datenbank-FK auf eine Textversion-Tabelle (zu komplex für MVP).
|
||||
|
||||
*Begründung:* Einfach nachvollziehbar. Ob bei Versionswechsel alle Altdeklarationen erneuert werden müssen, ist juristisch zu entscheiden — technisch ermöglicht das System beides.
|
||||
|
||||
**Entscheidung 6: copyright_notice bleibt separat (P-04 unberührt)**
|
||||
|
||||
P-06 führt keine copyright_notice-Redundanz ein. copyright_notice (P-04) = Attribution. rights_holder_confirmed (P-06) = Berechtigung. Beide sind Pflicht bei official.
|
||||
|
||||
---
|
||||
|
||||
## 5. Ziel-Flows
|
||||
|
||||
### Flow 1: Erstupload eines privaten Mediums (Übung oder Archiv)
|
||||
|
||||
**Frontend:**
|
||||
1. Nutzer öffnet Upload-Dialog (Exercise oder Archiv)
|
||||
2. Dateiauswahl
|
||||
3. **P-06-Dialog erscheint vor Upload-Button-Aktivierung:**
|
||||
- ☑ „Ich bin der Rechteinhaber oder besitze die erforderlichen Nutzungsrechte an diesem Medium." [Pflicht]
|
||||
- ☐ „Das Medium enthält erkennbare Personen." [optional]
|
||||
- → wenn ja: ☑ „Alle abgebildeten Personen haben der Nutzung zugestimmt." [optional bei private, Pflicht bei Promotion]
|
||||
- ☐ „Das Medium enthält Minderjährige." [optional]
|
||||
4. Upload-Button aktiv erst wenn Pflicht-Checkbox gesetzt
|
||||
|
||||
**Backend:**
|
||||
- Empfängt neue Felder: `rights_holder_confirmed`, optional `contains_identifiable_persons`, `person_consent_confirmed`, `contains_minors`
|
||||
- Prüft: `rights_holder_confirmed == true` — sonst HTTP 400 `RIGHTS_DECLARATION_REQUIRED`
|
||||
- INSERT in `media_assets` mit `rights_status = 'declared'`, `rights_declared_for_visibility = 'private'`, `rights_declared_at = NOW()`
|
||||
- INSERT in `media_asset_rights_declarations` mit `action_type = 'upload'`, `declaration_version = 'p06-v1.0'`, alle Felder
|
||||
|
||||
**Fehlermeldungen:**
|
||||
- `RIGHTS_DECLARATION_REQUIRED`: "Bitte bestätige, dass du die erforderlichen Rechte an diesem Medium besitzt."
|
||||
|
||||
**Tests:**
|
||||
- Upload ohne `rights_holder_confirmed` → 400
|
||||
- Upload mit `rights_holder_confirmed=true` → 201, `rights_status='declared'` in DB
|
||||
- Declaration-Log-Eintrag vorhanden mit korrektem `action_type='upload'`
|
||||
|
||||
**Offene juristische Fragen:** Reicht Selbsterklärung oder muss der Betreiber den Upload ansonsten ablehnen? (→ §7.1)
|
||||
|
||||
---
|
||||
|
||||
### Flow 2: Erstupload direkt als club-Medium (Archiv-Bulk-Upload)
|
||||
|
||||
**Frontend:**
|
||||
- Nutzer wählt `visibility = club` im Bulk-Upload-Dialog
|
||||
- P-06-Dialog erweitert (zusätzlich zur privaten Pflicht-Checkbox):
|
||||
- ☑ „Das Medium enthält erkennbare Personen." [Antwort Pflicht bei club]
|
||||
- → wenn ja: ☑ „Alle abgebildeten Personen haben der vereinsinternen Nutzung zugestimmt." [Pflicht]
|
||||
- ☑ „Das Medium enthält Minderjährige." [Antwort Pflicht]
|
||||
- → wenn ja: ☑ „Einwilligung der Erziehungsberechtigten liegt vor." [Pflicht, juristisch zu prüfen]
|
||||
|
||||
**Backend:**
|
||||
- Prüft alle Pflichtfelder für club: `rights_holder_confirmed`, `contains_identifiable_persons` (must be answered), `person_consent_confirmed` (wenn contains_persons=true)
|
||||
- `rights_declared_for_visibility = 'club'`
|
||||
- Eintrag in `media_asset_rights_declarations` mit `action_type = 'upload'`, `target_visibility = 'club'`
|
||||
|
||||
---
|
||||
|
||||
### Flow 3: Bulk-Upload durch Admin (Plattform-Admin / Superadmin)
|
||||
|
||||
**Besonderheit:** Admin lädt oft viele Dateien auf einmal. Dialog-Design muss batch-fähig sein.
|
||||
|
||||
**Empfehlung:** Eine Einwilligungserklärung für den gesamten Batch (nicht je Datei). Alle Dateien des Batches erhalten den gleichen Declarations-Record, jedoch referenziert je `media_asset_id`.
|
||||
|
||||
**Frontend:**
|
||||
- Vor Upload: Batch-Deklaration (gilt für alle Dateien des Batches)
|
||||
- Alternativ: Je Datei separate Deklaration (aufwändiger aber präziser) — juristisch zu prüfen welche Variante ausreichend ist
|
||||
|
||||
**Backend:**
|
||||
- `action_type = 'upload'` für alle Dateien des Batches
|
||||
- Wenn Batch-Deklaration: eine Deklarations-Transaktion, n Einträge in Log (je asset_id)
|
||||
|
||||
**Offene juristische Fragen:** Genügt eine Sammelbestätigung für Batches? (→ §7.6)
|
||||
|
||||
---
|
||||
|
||||
### Flow 4: Promotion private → club
|
||||
|
||||
**Frontend:**
|
||||
1. Nutzer ändert Sichtbarkeit eines Mediums zu `club` (im Archiv oder via Übungssichtbarkeit)
|
||||
2. Frontend erkennt Sichtbarkeitserhöhung
|
||||
3. **P-06-Promotions-Dialog:**
|
||||
- ☑ „Das Medium enthält erkennbare Personen." [Pflicht — Antwort erforderlich]
|
||||
- → wenn ja: ☑ „Alle abgebildeten Personen haben der vereinsinternen Nutzung zugestimmt." [Pflicht]
|
||||
- ☑ „Das Medium enthält Minderjährige." [Pflicht — Antwort erforderlich]
|
||||
- → wenn ja: ☑ „Einwilligung der Erziehungsberechtigten liegt vor." [Pflicht, juristisch zu prüfen]
|
||||
4. Bestehende copyright_notice-Abfrage (P-04) bleibt erhalten — läuft parallel oder im gleichen Dialog
|
||||
|
||||
**Backend:**
|
||||
- PATCH `/api/media-assets/{id}` empfängt: `visibility='club'`, P-06-Felder, `copyright_notice`
|
||||
- Prüft: rights_status='declared' AND rights_declared_for_visibility ≥ 'club' — wenn ja, keine neue Deklaration nötig (z. B. bereits als club hochgeladen)
|
||||
- Wenn nicht: neue Pflichtfelder prüfen, INSERT in Declarations-Log mit `action_type='promote_club'`
|
||||
- Bestehende P-04-Prüfung: copyright_notice weiterhin Pflicht
|
||||
- `rights_declared_for_visibility` in media_assets auf 'club' setzen
|
||||
|
||||
**Backend-Fehler:**
|
||||
- `CONSENT_REQUIRED_FOR_CLUB`: Personenfragen nicht beantwortet
|
||||
- `LEGACY_REDECLARATION_REQUIRED`: Altmedium, muss Nachdeklaration abgeben
|
||||
- `RIGHTS_DECLARATION_REQUIRED` (P-04): copyright_notice fehlt (bestehend)
|
||||
|
||||
---
|
||||
|
||||
### Flow 5: Promotion private/club → official
|
||||
|
||||
**Frontend:**
|
||||
1. Nur Superadmin kann zu official promoten
|
||||
2. Dialog zeigt vollständige Erklärung:
|
||||
- Alle Felder aus Flow 4 (Pflicht)
|
||||
- ☑ zusätzlich: „Das Medium enthält Musik oder sonstige Fremdinhalte." [Pflicht — Antwort erforderlich]
|
||||
- → wenn ja: ☑ „Ich besitze die erforderlichen Lizenzen für die öffentliche Nutzung." [Pflicht]
|
||||
3. copyright_notice (P-04) weiterhin Pflicht (bestehende Logik)
|
||||
|
||||
**Backend:**
|
||||
- Prüft alle Felder + copyright_notice
|
||||
- `action_type = 'promote_official'`, `target_visibility = 'official'`
|
||||
- `rights_declared_for_visibility = 'official'`
|
||||
|
||||
**Offene juristische Fragen:** Reicht Selbstdeklaration oder muss Superadmin bei official höhere Sorgfalt nachweisen? (→ §7.3)
|
||||
|
||||
---
|
||||
|
||||
### Flow 6: Nachbearbeitung von Metadaten (ohne Sichtbarkeitsänderung)
|
||||
|
||||
**Szenario:** Nutzer ändert nur `copyright_notice`, `original_filename`, `tags` — keine Sichtbarkeitsänderung.
|
||||
|
||||
**P-06-Anforderung:** Keine neue Deklaration erforderlich (Metadaten-Edit ist kein Promotions-Schritt).
|
||||
|
||||
**Ausnahme:** Wenn `rights_status = 'blocked'` (durch P-11/P-13 gesetzt) → Metadaten-Edit erlaubt, aber Sichtbarkeitsänderungen bleiben gesperrt.
|
||||
|
||||
---
|
||||
|
||||
### Flow 7: Verwendung bestehender Medien in neuer Übung (`from-asset`)
|
||||
|
||||
**Szenario:** Trainer verknüpft ein bereits im Archiv liegendes Medium mit einer neuen Übung über `POST /api/exercises/{id}/media/from-asset`.
|
||||
|
||||
**P-06-Anforderung:** Keine neue Deklaration erforderlich. Die Deklaration gilt für das Medium selbst, nicht für die Verknüpfung. Voraussetzung: `rights_status` des Assets ist 'declared' für die Sichtbarkeit der Übung.
|
||||
|
||||
**Backend-Prüfung (neu):**
|
||||
- Asset-Sichtbarkeit ≥ Übungs-Sichtbarkeit? Bestehende Prüfung.
|
||||
- `rights_declared_for_visibility` ≥ Übungs-Sichtbarkeit? → Neue Prüfung durch P-06
|
||||
- Wenn nicht: HTTP 400 `RIGHTS_DECLARATION_REQUIRED_FOR_TARGET_VISIBILITY`
|
||||
|
||||
---
|
||||
|
||||
### Flow 8: Behandlung von Altmedien ohne P-06-Metadaten
|
||||
|
||||
**Strategie: Soft-Block bei Promotion, kein Rückwirkungs-Zwang für private Altmedien**
|
||||
|
||||
| Situation | Verhalten |
|
||||
|-----------|-----------|
|
||||
| Altmedium private → weiterhin privat | Unverändert zugänglich; keine Zwangs-Nachdeklaration |
|
||||
| Altmedium privat → Anzeige in Übung (private) | Unverändert; keine neue Deklaration |
|
||||
| Altmedium privat → Promotion zu club | Blocked: `LEGACY_REDECLARATION_REQUIRED`; Nutzer muss Nachdeklaration abgeben |
|
||||
| Altmedium club → Promotion zu official | Blocked; Superadmin muss Nachdeklaration abgeben |
|
||||
| Altmedium mit `rights_status = 'legacy_unreviewed'` | Einsehbar, nicht promotable |
|
||||
|
||||
**Nachdeklarations-Flow:**
|
||||
1. Nutzer versucht Promotion eines Altmediums
|
||||
2. Backend gibt HTTP 400 `LEGACY_REDECLARATION_REQUIRED` zurück
|
||||
3. Frontend zeigt Hinweis und Deklarations-Dialog (analog zu neuem Upload-Dialog)
|
||||
4. Nutzer füllt Deklaration aus
|
||||
5. PATCH mit `legacy_re_declaration=true` + alle Pflichtfelder + `visibility`
|
||||
6. Backend: INSERT in Declarations-Log mit `action_type='legacy_re_declaration'`, aktualisiert `rights_status`, `rights_declared_for_visibility`
|
||||
|
||||
**Migrationsstrategie für bestehende Daten:**
|
||||
- Alle bestehenden `media_assets`-Zeilen bleiben mit `rights_status = 'legacy_unreviewed'` (Default in Migration)
|
||||
- Keine rückwirkende Sperrung
|
||||
- Bestehende club/official-Medien: `rights_status = 'legacy_unreviewed'` — die historische Sichtbarkeit bleibt erhalten, spätere Änderungen erfordern aber Nachdeklaration
|
||||
|
||||
**Juristisch zu prüfen:** Muss der Betreiber aktiv alle Altmedien auf club/official sperren bis zur Nachdeklaration? (→ §7.8)
|
||||
|
||||
---
|
||||
|
||||
### Flow 9: Widerruf / nachträglich fehlende Rechte erkannt
|
||||
|
||||
**Szenario:** Abgebildete Person widerruft Einwilligung oder Uploader erkennt, dass er keine Rechte hatte.
|
||||
|
||||
**P-06 implementiert keinen Widerrufsmechanismus direkt.** Anschluss an spätere Pakete:
|
||||
|
||||
- **P-11 (Legal-Hold):** Superadmin kann `rights_status = 'blocked'` setzen → Medium sofort aus allen öffentlichen Abfragen entfernt
|
||||
- **P-13 (Content-Melde-Backend):** Dritte können Rechtsverletzung melden → Moderationsqueue → Superadmin entscheidet über Sperrung
|
||||
|
||||
**P-06-Schnittstelle:** Das Feld `rights_status = 'blocked'` in `media_assets` ist die technische Brücke zu P-11 und P-13.
|
||||
|
||||
**Empfehlung:** Declaration-Log-Tabelle hat `ON DELETE CASCADE` auf `media_assets.id` — wenn ein Medium purged wird, werden auch alle Deklarationseinträge entfernt. Juristisch zu prüfen, ob Deklarationslog nach Löschung aufbewahrt werden muss (Rechenschaftspflicht Art. 5 Abs. 2 DSGVO).
|
||||
|
||||
---
|
||||
|
||||
### Flow 10: Zusammenspiel mit späterem P-11 und P-13
|
||||
|
||||
| P-06-Element | P-11-Anschluss | P-13-Anschluss |
|
||||
|-------------|---------------|---------------|
|
||||
| `rights_status = 'blocked'` | P-11 setzt diesen Status (Legal-Hold) | P-13-Moderator triggert P-11-Sperre |
|
||||
| Declaration-Log | Zeigt, welche Version bei Sperrung galt | Kontext für Moderationsentscheidung |
|
||||
| `contains_identifiable_persons` | Relevant für Löschbegründung (KUG) | Relevanzmerkmal für Meldekategorie |
|
||||
| `contains_minors` | Höchste Priorität bei P-11-Sofortsperrung | CSAM-Eskalationspfad in P-13 |
|
||||
|
||||
P-06 darf nicht im Widerspruch zu den späteren Paketen implementiert werden. Der `rights_status`-Enum muss `'blocked'` bereits in P-06a (Migration) enthalten.
|
||||
|
||||
---
|
||||
|
||||
## 6. Legacy- und Migrationskonzept
|
||||
|
||||
### 6.1 Fragen und Antworten
|
||||
|
||||
| Frage | Empfehlung | Juristisch zu prüfen |
|
||||
|-------|-----------|----------------------|
|
||||
| Dürfen Altmedien sichtbar bleiben? | Ja — keine rückwirkende Sperrung | Ja — insb. club/official ohne Einwilligung |
|
||||
| Dürfen Altmedien in neuen Übungen verwendet werden? | Ja, wenn Sichtbarkeit kompatibel | Ja — falls keine Rechte vorhanden |
|
||||
| Dürfen Altmedien zu club promoted werden? | Nein — Nachdeklaration erforderlich | Ja — ob Selbstdeklaration genügt |
|
||||
| Dürfen Altmedien zu official promoted werden? | Nein — vollständige Nachdeklaration | Ja — höhere Anforderungen |
|
||||
| Muss bei erster Bearbeitung Nachdeklaration erzwungen werden? | Nein (nur bei Promotion) | Ja — Betreiber-Ermessen |
|
||||
|
||||
### 6.2 Migration-Schritte
|
||||
|
||||
1. **Migration (P-06a):** Neue Spalten in `media_assets` mit `DEFAULT 'legacy_unreviewed'` → alle bestehenden Zeilen erhalten automatisch Status `legacy_unreviewed`
|
||||
2. **Neue Uploads nach P-06:** Code setzt `rights_status = 'declared'` nach erfolgreicher Deklaration
|
||||
3. **Altmedien-Promotion:** Backend blockiert mit `LEGACY_REDECLARATION_REQUIRED`; Nutzer muss Nachdeklaration abgeben
|
||||
4. **Keine automatische Batch-Re-Deklaration** durch Betreiber (wäre fachlich falsch — Betreiber kann nicht für Uploader erklären)
|
||||
|
||||
### 6.3 Empfohlene Übergangsstrategie (Minimales Risiko)
|
||||
|
||||
```
|
||||
private Altmedien: weiter sichtbar und nutzbar | Promotion blockiert
|
||||
club Altmedien: weiter sichtbar | Sichtbarkeitsänderung blockiert
|
||||
official Altmedien: weiter sichtbar | Sichtbarkeitsänderung blockiert
|
||||
```
|
||||
|
||||
*Begründung:* Vollständige Sperrung aller Altmedien würde Betrieb lahmlegen. Die Blockierung bei Promotion schützt vor Eskalation ohne existierende Nutzung zu zerstören. Juristisch bleibt das Risiko bei bereits exponierten Medien — das ist ein organisatorisches Problem, kein technisches.
|
||||
|
||||
---
|
||||
|
||||
## 7. Juristische Klärungsliste
|
||||
|
||||
Alle folgenden Punkte müssen durch einen Rechtsanwalt oder Datenschutzbeauftragten bewertet werden. Keine der folgenden Einschätzungen ist rechtlich bindend.
|
||||
|
||||
| # | Frage | Technische Relevanz | Dringlichkeit |
|
||||
|---|-------|---------------------|---------------|
|
||||
| 7.1 | Welche Erklärung ist für **private** Medien (nur Uploader sieht sie) erforderlich? Reicht `rights_holder_confirmed` oder ist auch ohne Sichtbarkeit Dritter eine Personeneinwilligung nötig? | Ob Personen-Fragen bei private Pflicht werden | Vor MVP |
|
||||
| 7.2 | Welche Erklärung ist für **club**-interne Sichtbarkeit (Vereinsmitglieder) erforderlich? Gilt § 22 KUG für vereinsintern? Reicht Selbsterklärung des Uploaders? | Pflichtfelder bei Promotion zu club | Vor MVP |
|
||||
| 7.3 | Welche Erklärung ist für **official** (plattformweit, ggf. öffentlich) erforderlich? Reicht Selbsterklärung oder muss Einwilligung nachgewiesen werden? | Pflichtfelder bei Promotion zu official | Vor MVP |
|
||||
| 7.4 | Wie ist mit erkennbaren **Minderjährigen** zu verfahren? Ab welchem Alter benötigen Minderjährige elterliche Einwilligung? Welche Einwilligungsform ist rechtssicher? | `contains_minors` + `parental_consent_confirmed` — Pflicht ab welcher Stufe? | Vor MVP |
|
||||
| 7.5 | Reicht eine **Selbsterklärung** des Uploaders oder müssen Einwilligungs-Dokumente (Scan, Upload) archiviert werden? | Dateiupload für Einwilligungs-Scan nötig? (MVP oder später?) | Vor MVP |
|
||||
| 7.6 | Ist eine **Batch-Deklaration** (eine Erklärung für mehrere Dateien des Uploads) rechtlich ausreichend? | Flow 3: Bulk-Upload-Design | Vor MVP |
|
||||
| 7.7 | Muss die **Textfassung** der Erklärungen (Checkbox-Labels) durch Rechtsanwalt freigegeben werden? Welche konkreten Formulierungen sind erforderlich? | `declaration_version` Textbasis | Vor MVP |
|
||||
| 7.8 | Wie sind **Altmedien** zu behandeln, die bereits mit club/official-Sichtbarkeit in der DB stehen? Muss der Betreiber diese sperren bis zur Nachdeklaration? | Migrationsstrategie §6.3 | Zeitnah |
|
||||
| 7.9 | Wie ist bei **Widerruf** einer Einwilligung vorzugehen? Welche Fristen gelten? Muss das Medium sofort gelöscht oder nur gesperrt werden? | rights_status='blocked', Schnittstelle P-11 | Vor P-11 |
|
||||
| 7.10 | Welche **Nachweisdaten** dürfen/sollen gespeichert werden (Datensparsamkeit vs. Rechenschaftspflicht)? Wie lange muss der Declaration-Log aufbewahrt werden? | Retention-Policy für `media_asset_rights_declarations` | Vor MVP |
|
||||
| 7.11 | Welche Anforderungen gelten für **Trainingsvideos mit mehreren Personen**? Muss jede Person einzeln einwilligen oder reicht eine kollektive Erklärung? | `person_consent_confirmed` als Boolean vs. Mehrfach-Einwilligung | Vor MVP |
|
||||
| 7.12 | Welche Anforderungen gelten für **Musik, Logos, Marken, Grafiken** von Dritten im Video/Bild? Ab wann ist eine separate Lizenz nötig? Reicht `music_rights_confirmed` als Selbsterklärung? | `contains_music`, `music_rights_confirmed` — MVP oder Pflicht? | Mittel |
|
||||
|
||||
---
|
||||
|
||||
## 8. Umsetzungsplan (für spätere Codephase — keine Umsetzungsfreigabe)
|
||||
|
||||
### P-06a – Datenmodell / Migration
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| **Ziel** | Neue Tabelle `media_asset_rights_declarations` anlegen; drei neue Spalten in `media_assets` |
|
||||
| **Betroffene Dateien** | `backend/migrations/048_media_rights_declarations.sql` (neu) |
|
||||
| **Migrationsbedarf** | Neue Migration; `DEFAULT 'legacy_unreviewed'` automatisch für bestehende Zeilen |
|
||||
| **Abhängigkeiten** | Keine (neue Tabelle) |
|
||||
| **Testbedarf** | Migration idempotent; bestehende `media_assets`-Zeilen haben `rights_status='legacy_unreviewed'` nach Migration; neue Zeilen haben `rights_status='declared'` nach P-06b |
|
||||
| **Akzeptanzkriterien** | Tabelle angelegt, alle Spalten korrekt typisiert, Indizes vorhanden, ALTER-Migration ohne Downtime anwendbar |
|
||||
| **Risiko** | Niedrig (neue Tabelle + ALTER mit DEFAULT ohne Table-Lock in PostgreSQL 16) |
|
||||
| **Rollback** | DROP TABLE media_asset_rights_declarations; ALTER TABLE media_assets DROP COLUMN rights_status, rights_declared_for_visibility, rights_declared_at |
|
||||
|
||||
---
|
||||
|
||||
### P-06b – Backend-Erzwingung
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| **Ziel** | Backend blockiert Upload und Promotion wenn Pflichtfelder fehlen; schreibt Declarations-Log |
|
||||
| **Betroffene Dateien** | `backend/routers/media_assets.py` (bulk-upload + patch + bulk-patch), `backend/routers/exercises.py` (upload_exercise_media, from-asset), neues Modul `backend/media_rights.py` (Hilfslogik) |
|
||||
| **Neue Pydantic-Models** | `RightsDeclaration` (Pflichtfelder + optionale Felder); Integration in `MediaAssetPatch` + Upload-Endpoints |
|
||||
| **Neue Fehlercodes** | `RIGHTS_DECLARATION_REQUIRED`, `CONSENT_REQUIRED_FOR_CLUB`, `CONSENT_REQUIRED_FOR_OFFICIAL`, `LEGACY_REDECLARATION_REQUIRED`, `RIGHTS_DECLARATION_REQUIRED_FOR_TARGET_VISIBILITY` |
|
||||
| **Abhängigkeiten** | P-06a (Migration) muss abgeschlossen sein |
|
||||
| **Testbedarf** | Unit-Tests für jeden neuen Fehlercode; Integrationstests Upload → Deklarationslog; Promotion ohne/mit Deklaration; Legacy-Block |
|
||||
| **Akzeptanzkriterien** | Upload ohne `rights_holder_confirmed` → 400; promotion ohne Personen-Deklaration → 400; gültige Deklaration → Eintrag in DB vorhanden; bestehender P-04-Test weiterhin grün |
|
||||
| **Risiko** | Mittel (Breaking Change für alle Upload-Clients); Feature-Flag zum schrittweisen Rollout empfohlen |
|
||||
| **Rollback** | Feature-Flag deaktivieren; kein DB-Rollback nötig |
|
||||
|
||||
---
|
||||
|
||||
### P-06c – Frontend-Dialoge
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| **Ziel** | Einwilligungsdialog in allen Upload-Pfaden; Promotions-Dialog bei Sichtbarkeitsänderung |
|
||||
| **Betroffene Dateien** | `frontend/src/components/RightsDeclarationDialog.jsx` (neu, wiederverwendbar), `frontend/src/pages/ExerciseFormPage.jsx`, `frontend/src/pages/MediaLibraryPage.jsx`, `frontend/src/utils/api.js` |
|
||||
| **Dialog-Typen** | Upload-Dialog (privat/club/official je nach Kontext), Promotions-Dialog (erkennt Sichtbarkeitserhöhung), Nachdeklarations-Dialog (für Legacy) |
|
||||
| **Abhängigkeiten** | P-06b (Backend-Codes müssen definiert sein); juristische Textfreigabe für Checkbox-Labels |
|
||||
| **Testbedarf** | Playwright E2E: Dialog erscheint; Upload ohne Checkbox → deaktivierter Button; Dialog mit allem ausgefüllt → erfolgreicher Upload; Backend-Fehler → korrekte Fehlermeldung |
|
||||
| **Akzeptanzkriterien** | Dialog erscheint bei allen Upload-Pfaden; Checkbox-State korrekt; Labels entsprechen juristisch geprüften Formulierungen; Promotions-Dialog erkennt Sichtbarkeitserhöhung |
|
||||
| **Risiko** | Mittel (UX-Änderung an häufig genutzten Pfaden) |
|
||||
| **Rollback** | Feature-Flag; Dialoge können ohne Backend-Änderung deaktiviert werden |
|
||||
|
||||
---
|
||||
|
||||
### P-06d – Tests / Dokumentation
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| **Ziel** | Vollständige Testabdeckung für P-06 + Doku-Update |
|
||||
| **Betroffene Dateien** | `backend/tests/test_media_rights_declaration.py` (neu), `tests/dev-smoke-test.spec.js` (neue P-06-Tests), `docs/compliance-implementation.md`, `docs/compliance-package-register.md`, Access-Layer-Audit aktualisieren |
|
||||
| **Backend-Tests** | Upload-Flows, Promotions-Flows, Legacy-Block, Declaration-Log, alle Fehlercodes |
|
||||
| **Playwright-Tests** | Dialog erscheint, Checkbox-Validierung, vollständiger Upload-Flow, Promotions-Dialog |
|
||||
| **Abhängigkeiten** | P-06a, P-06b, P-06c abgeschlossen |
|
||||
| **Akzeptanzkriterien** | Alle neuen Tests grün; bestehende Tests unverändert grün; ACCESS_LAYER_STRICT=1 grün |
|
||||
| **Risiko** | Niedrig |
|
||||
|
||||
---
|
||||
|
||||
### P-06e – Legacy-Nacharbeit (optional, nach juristischer Klärung)
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| **Ziel** | Massenprüfung und ggf. Sperrung bestehender club/official-Medien ohne Deklaration, falls juristisch notwendig |
|
||||
| **Betroffene Dateien** | `backend/scripts/media_rights_audit.py` (neu), evtl. Admin-UI |
|
||||
| **Inhalt** | Script listet alle `visibility IN ('club', 'official')` mit `rights_status='legacy_unreviewed'`; Superadmin kann Massenmarkierung oder individuelle Überprüfung anstoßen |
|
||||
| **Abhängigkeiten** | P-06a–d; juristische Klärung §7.8 |
|
||||
| **Akzeptanzkriterien** | Script läuft ohne Fehler; erzeugt CSV-Report mit betroffenen Assets |
|
||||
| **Risiko** | Mittel (wenn Sperrung aktiv: Betriebsunterbrechung für Vereinsmedien) |
|
||||
| **Hinweis** | Erst nach juristischer Entscheidung über Altbestand-Behandlung umsetzen |
|
||||
|
||||
---
|
||||
|
||||
## 9. Abschlussbewertung
|
||||
|
||||
### 9.1 Neue / geänderte Dokumente
|
||||
|
||||
| Dokument | Änderung |
|
||||
|----------|---------|
|
||||
| `docs/p06-upload-rights-spec.md` | Neu erstellt (dieses Dokument) |
|
||||
| `docs/compliance-roadmap.md` | P-06: Spezifikation erstellt vermerkt; nächste Freigabe angepasst |
|
||||
| `docs/compliance-implementation.md` | Kurzer P-06-Eintrag: Spezifikation erstellt, keine Umsetzung |
|
||||
| `docs/compliance-package-register.md` | P-06 Letzter Stand: Spezifikation vorhanden |
|
||||
|
||||
### 9.2 Empfohlene P-06-Zielarchitektur (Kurzfassung)
|
||||
|
||||
- **Append-only Log-Tabelle** `media_asset_rights_declarations` (Wer, Wann, Was, Welche Version)
|
||||
- **Drei Status-Felder** in `media_assets`: `rights_status` / `rights_declared_for_visibility` / `rights_declared_at`
|
||||
- **Gestufte Erklärungen**: Upload = Minimalset; Promotion club = Personen-Pflicht; Promotion official = vollständig
|
||||
- **Backend-Erzwingung** über neue Fehlercodes; keine reine Frontend-Checkbox
|
||||
- **Versionierung** über `declaration_version`-String; kein FK auf Texttabelle
|
||||
- **Legacy**: `rights_status = 'legacy_unreviewed'`; Promotion blockiert; Nachdeklarations-Flow
|
||||
|
||||
### 9.3 Kritische Designentscheidungen
|
||||
|
||||
| Entscheidung | Begründung |
|
||||
|-------------|-----------|
|
||||
| Gestufte Erklärungen je Sichtbarkeitsstufe | Rechtsrisiko steigt mit Sichtbarkeit; Rechtsanschlussfähigkeit |
|
||||
| Minimalset beim Erstupload | Nutzbarkeit vs. Compliance; Pflicht-Erweiterung bei Promotion |
|
||||
| Append-only Log (nie löschen/ändern) | Nachweisbarkeit; Audit-Integrität |
|
||||
| rights_status = 'legacy_unreviewed' per Default | Keine rückwirkende Sperrung; kontrollierbarer Übergang |
|
||||
| Kein Einwilligungs-Datei-Upload (MVP) | Aufwand vs. Mehrwert; spätere Nachrüstung möglich |
|
||||
| `rights_status = 'blocked'` als P-11-Schnittstelle | Zukunftssicherheit; P-11/P-13 können sofort anschließen |
|
||||
|
||||
### 9.4 Offene juristische Fragen (Priorisiert)
|
||||
|
||||
| Priorität | Frage | Paket-Impact |
|
||||
|-----------|-------|-------------|
|
||||
| Vor MVP | §7.7 Textfassung der Erklärungen | P-06c (Dialog-Labels) |
|
||||
| Vor MVP | §7.1 Private: Reicht rights_holder allein? | Pflichtfeld-Definition |
|
||||
| Vor MVP | §7.2 Club: § 22 KUG vereinsintern? | contains_persons bei club Pflicht? |
|
||||
| Vor MVP | §7.4 Minderjährige: Schwelle und Form | parental_consent MVP oder später |
|
||||
| Vor MVP | §7.5 Selbsterklärung oder Dokumenten-Upload? | Scope P-06c |
|
||||
| Zeitnah | §7.8 Altmedien club/official: Sperrpflicht? | P-06e Scope |
|
||||
| Vor P-11 | §7.9 Widerruf: Fristen und Mechanismus | P-11-Design |
|
||||
| Mittel | §7.10 Aufbewahrung Declaration-Log | Retention-Policy |
|
||||
|
||||
### 9.5 Empfohlene spätere Umsetzungsschritte
|
||||
|
||||
1. Rechtsanwalt beauftragt für §7.7 (Texte) und §7.1–7.3 (Anforderungen je Stufe)
|
||||
2. Nach Klärung §7.7: Freigabe P-06a + P-06b parallel (kein Frontend-Merge nötig)
|
||||
3. Nach §7.7 Textfreigabe: Freigabe P-06c (Frontend-Dialoge)
|
||||
4. P-06d: Tests + Doku beim gleichen Merge wie P-06b/P-06c
|
||||
5. Nach §7.8-Klärung: ggf. P-06e (Legacy-Massenprüfung)
|
||||
|
||||
### 9.6 Implementierungsbereitschaft
|
||||
|
||||
| Kriterium | Einschätzung |
|
||||
|-----------|-------------|
|
||||
| P-06 implementierungsreif | Teilweise — Datenmodell und Backend-Logik spezifizierbar; Dialog-Labels nicht ohne juristische Textfreigabe |
|
||||
| Juristische Vorabklärung erforderlich | Ja — §7.7 (Textfassung) blockiert P-06c; §7.1–7.3 bestimmen Pflichtfelder |
|
||||
| P-06a (Migration) vorab umsetzbar | Ja — unabhängig von juristischen Texten |
|
||||
| P-06b (Backend) vorab umsetzbar | Ja — mit Platzhalter-Fehlercodes, Texte nachrüstbar |
|
||||
| P-06c (Frontend-Dialog) vorab umsetzbar | Nein — Dialog-Labels müssen juristisch freigegeben sein |
|
||||
|
||||
### 9.7 Scope-Drift-Prüfung
|
||||
|
||||
| Prüfung | Ergebnis |
|
||||
|---------|---------|
|
||||
| Codeänderungen vorgenommen? | Nein |
|
||||
| Neue Migrationen erstellt? | Nein |
|
||||
| Neue Endpoints erstellt? | Nein |
|
||||
| Paket-ID geändert? | Nein |
|
||||
| Andere Paket-IDs berührt? | Nein (P-11, P-13 nur als Referenz) |
|
||||
| P-06 bleibt nach dieser Arbeit offen? | Ja |
|
||||
|
||||
---
|
||||
|
||||
**P-06 fachlich-technisch spezifiziert. Keine Codeänderungen vorgenommen.**
|
||||
|
||||
---
|
||||
|
||||
*Erstellt: 2026-05-10 | Autor: Claude Code | Kein Rechtsanwalt; alle rechtlichen Einschätzungen sind juristisch zu prüfen.*
|
||||
Loading…
Reference in New Issue
Block a user