Some checks failed
Deploy Development / deploy (push) Successful in 39s
Test Suite / pytest-backend (push) Successful in 34s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 11s
Test Suite / playwright-tests (push) Failing after 1m23s
Implementiert server-seitige Rechteerklärungspflicht für alle Medien-Uploads
und Sichtbarkeits-Promotions (konservative Erstannahme: alle Uploads).
Backend:
- backend/media_rights.py (NEU): Kernmodul — validate_rights_declaration,
check_rights_coverage, assert_rights_for_promotion, assert_rights_for_exercise_link,
write_rights_declaration, update_rights_quick_fields
- backend/migrations/048_media_rights_declarations.sql (NEU): Tabelle
media_asset_rights_declarations (Append-only Audit-Log), Felder
rights_status/rights_visibility_level in media_assets
- backend/routers/media_assets.py: P-06-Pflichtprüfung in PATCH (single + bulk),
POST /api/media-assets/{id}/rights-declarations (Re-Deklaration),
GET /api/admin/media-rights/legacy-summary|legacy-assets (Admin-Endpoints)
- backend/routers/exercises.py: P-06-Felder in upload_exercise_media,
assert_rights_for_exercise_link in attach_exercise_media_from_asset
- backend/main.py: admin_rights_router registriert
Frontend:
- frontend/src/components/RightsDeclarationDialog.jsx (NEU): 9-Felder-Dialog
(konservativ: immer alle Fragen), Client-Validierung, VORLÄUFIG-Hinweis
- frontend/src/pages/MediaLibraryPage.jsx: Dialog-Intercept vor Upload,
Altbestand-Indikator (legacy_unreviewed)
- frontend/src/utils/api.js: P-06-Felder in bulkUploadMediaAssets weitergeleitet
Tests:
- backend/tests/test_media_rights_declaration.py (NEU): 28 Unit-/Integrationstests
- backend/tests/test_media_assets_archive.py: P-06 fetchone-Slots + Mock ergänzt
- backend/tests/test_media_assets_copyright_promotion.py: check_rights_coverage gemockt
- tests/dev-smoke-test.spec.js: 5 P-06 E2E-Tests ergänzt
Dokumentation:
- docs/compliance-implementation.md: P-06-Abschnitt
- docs/compliance-package-register.md: Status ⚠️ teilweise umgesetzt (KRIT-04 offen)
- docs/compliance-roadmap.md: P-06 im Freigaben-Log
Offen: KRIT-04 (rechtliche Finalisierung Einwilligungsformulierung) — technisch
vollständig, Rechtstext VORLÄUFIG.
version: 0.8.75
module: media_rights 1.0.0, media_assets 1.13.0, exercises 2.20.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
76 lines
3.7 KiB
SQL
76 lines
3.7 KiB
SQL
-- Migration 048: P-06 Upload-Einwilligungsdialog
|
|
-- Append-only Deklarations-Log + Schnellfelder in media_assets
|
|
-- Alle bestehenden Medien erhalten rights_status = 'legacy_unreviewed'
|
|
|
|
-- Deklarations-Log (append-only, wird nie geaendert oder geloescht)
|
|
CREATE TABLE IF NOT EXISTS 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 TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
|
|
-- Kontext der Erklaerung
|
|
action_type VARCHAR(50) NOT NULL
|
|
CHECK (action_type IN (
|
|
'upload', -- Erstupload
|
|
'promote_club', -- Promotion zu club
|
|
'promote_official', -- Promotion zu official
|
|
're_declaration', -- Freiwillige Nacherklaerung
|
|
'legacy_re_declaration' -- Altmedium: erste Erklaerung nachgereicht
|
|
)),
|
|
target_visibility VARCHAR(32) NOT NULL
|
|
CHECK (target_visibility IN ('private', 'club', 'official')),
|
|
-- Textversion der Erklaerung; 'p06-v1-conservative' = konservative Erstannahmen
|
|
-- VORLAEUTIG: Texte noch nicht juristisch geprueft
|
|
declaration_version VARCHAR(40) NOT NULL DEFAULT 'p06-v1-conservative',
|
|
|
|
-- Pflichtfeld (alle Sichtbarkeiten, alle Aktionen)
|
|
rights_holder_confirmed BOOLEAN NOT NULL,
|
|
|
|
-- Personen (konservative Annahme: immer abgefragt, auch bei 'private')
|
|
contains_identifiable_persons BOOLEAN,
|
|
person_consent_confirmed BOOLEAN, -- Pflicht wenn contains_identifiable_persons = true
|
|
|
|
-- Minderjaehrige
|
|
contains_minors BOOLEAN,
|
|
parental_consent_confirmed BOOLEAN, -- Pflicht wenn contains_minors = true
|
|
|
|
-- Drittmaterial
|
|
contains_music BOOLEAN,
|
|
music_rights_confirmed BOOLEAN, -- Pflicht wenn contains_music = true
|
|
contains_third_party_content BOOLEAN,
|
|
third_party_rights_confirmed BOOLEAN, -- Pflicht wenn contains_third_party_content = true
|
|
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_mard_asset
|
|
ON media_asset_rights_declarations (media_asset_id);
|
|
CREATE INDEX IF NOT EXISTS idx_mard_profile
|
|
ON media_asset_rights_declarations (declared_by_profile_id);
|
|
CREATE INDEX IF NOT EXISTS idx_mard_action_type
|
|
ON media_asset_rights_declarations (action_type);
|
|
|
|
-- Schnellfelder in media_assets (kein Ersatz fuer den Log, nur fuer effiziente Abfragen)
|
|
ALTER TABLE media_assets
|
|
ADD COLUMN IF NOT EXISTS rights_status VARCHAR(32)
|
|
NOT NULL DEFAULT 'legacy_unreviewed'
|
|
CHECK (rights_status IN ('legacy_unreviewed', 'declared', 'blocked')),
|
|
ADD COLUMN IF NOT EXISTS rights_declared_for_visibility VARCHAR(32)
|
|
CHECK (rights_declared_for_visibility IN ('private', 'club', 'official')),
|
|
ADD COLUMN IF NOT EXISTS rights_declared_at TIMESTAMPTZ;
|
|
|
|
-- Bestehende Medien: explicit legacy_unreviewed setzen (redundant zum DEFAULT, zur Klarheit)
|
|
UPDATE media_assets
|
|
SET rights_status = 'legacy_unreviewed'
|
|
WHERE rights_status = 'legacy_unreviewed'; -- no-op, setzt Default explizit
|
|
|
|
COMMENT ON TABLE media_asset_rights_declarations IS
|
|
'P-06: Append-only Erklaerungslog fuer Upload-Einwilligungen. '
|
|
'Eintraege werden nie geaendert. Juristische Validierung der Felder und Texte steht aus.';
|
|
|
|
COMMENT ON COLUMN media_assets.rights_status IS
|
|
'P-06: legacy_unreviewed = Altbestand ohne P-06-Erklaerung; '
|
|
'declared = gueltige Erklaerung fuer rights_declared_for_visibility; '
|
|
'blocked = durch Admin gesperrt (P-11-Schnittstelle).';
|