- Introduced a centralized media archive (`/media`) with lifecycle management, including soft delete and recovery options. - Enhanced media upload functionality to support multiple files and automatic type inference. - Updated documentation to reflect the new media architecture and inline media linking specifications. - Version bump to 0.8.59 to accommodate changes in media handling and database schema. Co-authored-by: Cursor <cursoragent@cursor.com>
8.7 KiB
Shinkan Jinkendo – Entwicklungsstand & Handover
Stand: 2026-05-07
App-Version / DB-Schema: App 0.8.59, DB-Schema siehe backend/version.py (DB_SCHEMA_VERSION)
Diese Datei ist die Einstiegs-Doku für neue Chat-Sessions: Anforderungen im Detail stehen in .claude/docs/ (siehe unten); hier der implementierte Stand, Medien-Meilenstein und sinnvolle nächste Schritte.
Produktion: relation … does not exist (z. B. skill_main_categories)
Das Schema ist gegenüber dem Code zurück: Migration 022_skills_schema_complete (und ggf. Folgende) wurden auf dieser Datenbank noch nicht erfolgreich ausgeführt.
-
Automatisch: Die Dateien
migrations/*.sql(numerisch sortiert) bilden eine Warteschlange. Bereits erfolgreiche Läufe stehen inschema_migrations— diese Dateien werden übersprungen (idempotent). Pro Datei läuft eine Transaktion (im Container vorzugsweisepsql -1 -f, sonst Fallbacksqlparse+ psycopg2). -
Fix / manuell:
docker exec shinkan-api python /app/run_migrations.py— Exit-Code 0. -
Aktuelle Builds: Bei fehlgeschlagenem Migrate startet
main.pydie API nicht. Lokal ohne DB:SKIP_DB_MIGRATE=1.
1. Pflichtlektüre (Kontext & Anforderungen)
| Thema | Pfad |
|---|---|
| Projekt-Setup, Domain grob | .claude/docs/working/SHINKAN_PROJECT_SETUP.md |
| Projekt-Status (aktuell) | .claude/docs/PROJECT_STATUS.md |
| Medien-Archiv, Lifecycle, Inline-Plan (§11) | .claude/docs/technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md |
| Übungen: API, DB, Architektur, Routing | .claude/docs/technical/EXERCISES_API_SPEC.md, EXERCISES_DATABASE_FINAL.md, EXERCISES_ARCHITECTURE.md, EXERCISES_FRONTEND_ROUTING.md |
| Media / Upload-Limits / Embed | .claude/docs/technical/MEDIA_UPLOAD_SPEC.md |
| MediaWiki-Import | .claude/docs/technical/MEDIAWIKI_IMPORT_SPEC.md |
| Zugriffsschicht, Mandant, Governance | .claude/docs/technical/ACCESS_LAYER_AND_GOVERNANCE_PLAN.md |
| Tenant-Endpoints (Audit) | .claude/docs/working/ACCESS_LAYER_ENDPOINT_AUDIT.md |
| Rahmenprogramm · Planung | .claude/docs/technical/TRAINING_FRAMEWORK_SPEC.md |
| Überblick DB | .claude/docs/technical/DATABASE_SCHEMA.md |
| Domäne | .claude/docs/functional/DOMAIN_MODEL.md |
| Lieferliste inkl. Medien | .claude/docs/library/FEATURES_DELIVERED_2026-Q2.md §12 |
2. Implementierter Stand: Fähigkeiten & Reifegradmodelle
2.1 Datenbank
maturity_models,model_levels,model_skills,model_skill_levels: Matrix-Inhalt pro Modell.- Kontext am Modell (Legacy, M:N):
maturity_model_focus_areas,maturity_model_style_directions,maturity_model_target_groups(Migration 025). - Hierarchische Kontext-Zuordnung (Resolve):
maturity_model_context_bindingsmit optionalstyle_direction_id,training_type_id(Migration 026, 027). - 027: u. a.
Fokus + Trainingsstilohne Stilrichtung (partielle Unique-Indizes).
2.2 Resolve-Logik (Backend)
GET /api/maturity-models/resolve: Bindings zum Fokus, die zur Anfrage passen; Merge nach Spezifität (weniger spezifisch zuerst); spezifischere Zeilen überschreiben Zelltexte.- Matching: Gesetzte Spalten einer Binding-Zeile müssen mit der Anfrage übereinstimmen;
NULLin der Zeile = Wildcard. - Legacy-Fallback: Nur wenn für den Fokus keine einzige Zeile in
maturity_model_context_bindingsexistiert.
2.3 Export / Import (einzelnes Modell & aufgelöst)
GET /api/maturity-models/{id}/export:shinkan.maturity_model.v1inkl.context_bindings_for_model(IDs).GET /api/maturity-models/export-resolved:shinkan.maturity_matrix_resolved.v1(Query:focus_area_id, optionalstyle_direction_id,training_type_id).POST /api/maturity-models/import:create|replace, optionalimport_bindings.
2.4 Komplett-Stack Test → Prod
GET /api/admin/matrix-stack/export,POST /api/admin/matrix-stack/import— siehematrix_stack_bundle.py.
2.5 Frontend (Admin)
AdminMaturityModelsPage.jsx,MaturityModelBindingsAdmin.jsx,MaturityMatrixToolsAdmin.jsx; APIs inapi.js.
3. Trainingsrahmenprogramm & Planungs‑Blueprint (kurz)
- 036 / 037: Bibliotheks-Rahmen, Slot-Inhalt als
training_unitsmitframework_slot_id;POST /api/training-units/from-framework-slot. - Code:
training_framework_programs.py,training_planning.py; FrontendTrainingFrameworkProgramEditPage.jsx,createTrainingUnitFromFrameworkSlotinapi.js.
4. Stand: Medien-Management (Ist, 2026-05-07)
Datenmodell (Kurz):
media_assets: Physische oder logische Archiv-Datei (u. a.sha256,visibility,club_id,lifecycle_state,copyright_notice, Speicherpfad/storage_key,tagsab passender Migration).exercise_media: optionalmedia_asset_id; weiterhin Embeds ohne Asset; Kontext/Sortierung/Titel wie bisher.platform_media_storage: Superadmin — relativer Unterpfad unterMEDIA_ROOT.
API (Auszug):
GET /api/media-assets, Filter (Lifecycle,media_kind, Verein, Suche, Tags), Berechtigungen pro Zeile.PATCH /api/media-assets/{id}/ Bulk-PATCH, Lifecycle (POST …/lifecycle, Bulk).GET …/media-assets/{id}/file(inkl. Kontextssetokenwo vorgesehen).POST /api/exercises/{id}/media/from-asset: bestehendes Asset verknüpfen.- Übungs-Uploads erzeugen/verknüpfen
media_assets; Governance wielibrary_content_*/ TenantContext.
Frontend:
- Route
/media(Medienbibliothek): Kacheln/Liste, Filter, Copyright, Lifecycle-Actions (Rollen gemäß Spec;official: bearbeiten/Lifecycle im Wesentlichen Superadmin, andere Rollen Lesemodus im Bearbeiten-Dialog). - Übungsformular: Archiv-Picker, Vorschau, Reaktivierung bei Dedupe-Konflikt (Papierkorb).
Speicher & Pfade:
- Struktur unter
library/mit Vereinssegment (aus Vereinsname abgeleitet +c{id}), Unterordner nach Medienkind (image/video/pdf/other), Dateiname z. B. SHA-basiert — Details und Drift-Vermeidung inMEDIA_ASSETS_AND_ARCHIVE_SPEC.md.
Governance & Mandant:
visibility=officialfür Übungen: nur Superadmin; Medienofficial: Lifecycle/PATCH schwerpunktmäßig Superadmin (Plattform-Admin nicht gleich Superadmin).- Aktiver Verein:
profiles.active_club_id, HeaderX-Active-Club-Id, Responseeffective_club_id— nach 0.8.59 konsistent inkl. Plattform-Admin beim Reload (Backendtenant_context, FrontendgetResolvedActiveClubIdForUi+ Profil-Refresh nach Vereinswechsel).
5. Geplant: Inline-Medienverlinkung (nicht umgesetzt)
Ziel: Mediendarstellung innerhalb von Fließtext-Feldern (Ablauf, Ziele, Trainerhinweise), konsistent mit derselben exercise_media‑ bzw. Asset-Governance wie die Medienliste.
Norm: MEDIA_ASSETS_AND_ARCHIVE_SPEC.md §11 — u. a.:
- Verweis auf
exercise_media.id(oder kanonisch übersetzte Markup-Syntax), keine zweite Sichtbarkeitslogik. - Ein zentraler Render-/Sanitize-Pfad für Übungstexte; keine verstreuten „roh
dangerouslySetInnerHTML“-Pfade. - XSS/CSP: nur Allowlist-HTML und kontrollierte Player-Komponenten.
Reihenfolge: Archiv & aktuelle Governance gelten als Basis; Inline ist die nächste inhaltliche Ausbaustufe für Medien (siehe PROJECT_STATUS.md Nächste Schritte).
6. Nächste Session — sinnvolle Arbeitspakete
- Inline §11: Syntax festlegen (z. B.
{{exerciseMedia:id}}→ kanonisches HTML), Server normalisieren bei Speichern, einenrenderExerciseRichText()-Pfad im Frontend. - Tests: pytest für
media_assets-Router (Leserechte, Lifecycle,from-asset); ggf. Snapshot der Pfad-Umzug-Logik. - Retention: Job-Dokumentation + Betrieb (ENV, Intervall); Dry-Run beschreiben.
- S3/Adapter: Speicher-Abstraktion §7 — wenn Produkt es verlangt.
- Rahmen/UI: Kalender „aus Rahmen übernehmen“ weiter anbinden (parallel, unabhängig von Medien).
7. Technische Referenz (kurz)
| Bereich | Einstieg |
|---|---|
| Backend API | backend/main.py; u. a. media_assets.py, exercises.py, profiles.py, training_framework_programs.py, tenant_context.py |
| Migrationen | backend/migrations/ (040+ Mitgliedschaft/Governance; 045+ Medien-Stack) |
| Frontend API | frontend/src/utils/api.js |
| Aktiver Verein (UI) | frontend/src/utils/activeClub.js, AuthContext.jsx |
| Version / Changelog | backend/version.py |
8. Veraltete Hinweise
.claude/docs/working/HANDOVER_NEXT_SESSION.md verweist auf dieses Dokument (docs/HANDOVER.md) als aktuelle Basis.
Ende Handover-Dokument.