All checks were successful
Deploy Development / deploy (push) Successful in 48s
Test Suite / pytest-backend (push) Successful in 45s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 15s
Test Suite / k6 /health Baseline (push) Successful in 34s
Test Suite / playwright-tests (push) Successful in 1m35s
Document cross-app architecture patterns, Mitai alignment, and family entitlement standards. Documentation only; no runtime changes. Co-authored-by: Cursor <cursoragent@cursor.com>
120 lines
4.4 KiB
Markdown
120 lines
4.4 KiB
Markdown
# Media Assets & Archiv – Designprinzipien (Extraktion)
|
||
|
||
**Status:** Analyse / Arbeitspapier
|
||
**Stand:** 2026-07-04
|
||
**Geltungsbereich:** Modul „Media Assets & Archiv“ — physische Medien, Lifecycle, Inline
|
||
|
||
**Serie:** Designprinzipien für Produktfamilie · Shinkan Dokument 6 von 15
|
||
**Mitai-Vergleich:** — (Mitai hat kein vergleichbares Medien-Archiv)
|
||
|
||
**Kernkomponenten:**
|
||
|
||
| Bereich | Pfade |
|
||
|---------|-------|
|
||
| API | `backend/routers/media_assets.py`, `platform_media_storage.py` |
|
||
| Speicher | `backend/media_storage.py`, `MEDIA_ROOT` |
|
||
| Rechte/Audit | `backend/media_rights.py`, `media_legal_hold.py` |
|
||
| Inline Rich-Text | `backend/exercise_rich_text.py` |
|
||
| Retention-Job | `backend/scripts/media_retention_job.py` |
|
||
| Spec | `.claude/docs/technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md` |
|
||
|
||
---
|
||
|
||
## Modul
|
||
|
||
**Media Assets & Archiv**
|
||
|
||
Zentrale Verwaltung physischer Dateien (`media_assets`), Verknüpfung zu Übungen (`exercise_media`), mehrstufiger Lifecycle (Papierkorb, Legal Hold), Inline-Einbettung in Rich-Text.
|
||
|
||
---
|
||
|
||
## Designprinzipien
|
||
|
||
### 1. Physisches Asset einmal, mehrfach verknüpft
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Prinzip** | Datei in `media_assets`; Übungen referenzieren via `exercise_media.media_asset_id`. |
|
||
| **Begründung** | Keine Dubletten auf Platte; Wiederverwendung im Archiv. |
|
||
| **Quelle** | `MEDIA_ASSETS_AND_ARCHIVE_SPEC.md` §1 |
|
||
| **Tragfähigkeit** | **hoch** |
|
||
| **Einschränkung** | Legacy-Pfade ohne Asset-ID können noch existieren. |
|
||
|
||
### 2. Gleiche Visibility-Semantik wie Übungen
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Prinzip** | `private`/`club`/`official` + `club_id` — Access Layer für Download und Liste. |
|
||
| **Begründung** | Ein Freigabemodell für alle Bibliotheksartefakte. |
|
||
| **Quelle** | Spec §4; `media_rights.py` |
|
||
| **Tragfähigkeit** | **hoch** |
|
||
| **Einschränkung** | Promotion Übung→official muss Assets mithheben — UI-Dialog Pflicht. |
|
||
|
||
### 3. Lifecycle getrennt von Übungs-Verknüpfung
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Prinzip** | Verknüpfung in Übung lösen ≠ Asset physisch löschen; Papierkorb-Stufen separat. |
|
||
| **Begründung** | Trainer dürfen Link entfernen ohne Archiv-Löschrecht. |
|
||
| **Quelle** | Spec §5 |
|
||
| **Tragfähigkeit** | **hoch** |
|
||
| **Einschränkung** | Retention-Job muss in Betrieb überwacht werden. |
|
||
|
||
### 4. Legal Hold blockiert automatisierten Lifecycle
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Prinzip** | `legal_hold` schützt Asset vor Purge; Anbindung an Content Reports (Superadmin). |
|
||
| **Begründung** | Compliance bei Meldungen (P-11/P-13). |
|
||
| **Quelle** | `media_legal_hold.py`; `content_reports.py` |
|
||
| **Tragfähigkeit** | **hoch** |
|
||
| **Einschränkung** | — |
|
||
|
||
### 5. Inline-Medien: kanonisches Markup + Validierung
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Prinzip** | `{{exerciseMedia:id}}` → `<span data-shinkan-exercise-media="id">`; IDs müssen zur Übung gehören. |
|
||
| **Begründung** | Ein Render-Pfad; keine broken References nach Medien-Löschung. |
|
||
| **Quelle** | `exercise_rich_text.py`; Spec §11 |
|
||
| **Tragfähigkeit** | **hoch** |
|
||
| **Einschränkung** | Beim Erst-Anlegen der Übung keine Inline-Refs (Chicken-Egg). |
|
||
|
||
### 6. Speicher-Abstraktion (local + konfigurierbarer Root)
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Prinzip** | `get_effective_media_root()` + `library/…`-Pfadkonvention; kein hardcodierter `/app/media` in Routern. |
|
||
| **Begründung** | NAS/externer Speicher vorbereitet. |
|
||
| **Quelle** | `media_storage.py`; `platform_media_storage` |
|
||
| **Tragfähigkeit** | **mittel** |
|
||
| **Einschränkung** | S3-Backend noch nicht vollständig. |
|
||
|
||
### 7. Audit-Log für sensitive Aktionen
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Prinzip** | `media_asset_audit_log` bei Meldungen, Hold, kritischen Lifecycle-Events. |
|
||
| **Begründung** | Nachvollziehbarkeit für Admins und Compliance. |
|
||
| **Quelle** | `media_rights.write_audit_log_entry` |
|
||
| **Tragfähigkeit** | **mittel** |
|
||
| **Einschränkung** | Nicht jede Admin-Aktion geloggt. |
|
||
|
||
---
|
||
|
||
## Nicht übernehmen
|
||
|
||
1. **Download nur mit Übungs-ID ohne Asset-Governance** — Seitenkanal-Risiko.
|
||
2. **Copyright leer bei `official`** — Spec verbietet das fachlich.
|
||
3. **Physisches Löschen bei Referenzanzahl > 0** — Spec §5.3.
|
||
4. **Embed-URLs durch Lifecycle-Purge** — Embeds haben anderen Lebenszyklus.
|
||
|
||
---
|
||
|
||
## Verwandte Dokumentation
|
||
|
||
- [MEDIA_ASSETS_AND_ARCHIVE_SPEC.md](../../../.claude/docs/technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md)
|
||
- [ACCESS_LAYER_DESIGN_PRINCIPLES.md](./ACCESS_LAYER_DESIGN_PRINCIPLES.md)
|
||
- [CONTENT_REPORTS_DESIGN_PRINCIPLES.md](./CONTENT_REPORTS_DESIGN_PRINCIPLES.md)
|
||
- [DESIGN_PRINCIPLES_INDEX.md](./DESIGN_PRINCIPLES_INDEX.md)
|