shinkan-jinkendo/docs/HANDOVER.md
Lars b6de1f15ea
All checks were successful
Deploy Development / deploy (push) Successful in 34s
Test Suite / pytest-backend (push) Successful in 25s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Successful in 23s
feat(media): implement centralized media archive and inline media linking
- 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>
2026-05-08 10:56:43 +02:00

8.7 KiB
Raw Permalink Blame History

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 in schema_migrations — diese Dateien werden übersprungen (idempotent). Pro Datei läuft eine Transaktion (im Container vorzugsweise psql -1 -f, sonst Fallback sqlparse + psycopg2).

  • Fix / manuell: docker exec shinkan-api python /app/run_migrations.py — Exit-Code 0.

  • Aktuelle Builds: Bei fehlgeschlagenem Migrate startet main.py die 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_bindings mit optional style_direction_id, training_type_id (Migration 026, 027).
  • 027: u.a. Fokus + Trainingsstil ohne 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; NULL in der Zeile = Wildcard.
  • Legacy-Fallback: Nur wenn für den Fokus keine einzige Zeile in maturity_model_context_bindings existiert.

2.3 Export / Import (einzelnes Modell & aufgelöst)

  • GET /api/maturity-models/{id}/export: shinkan.maturity_model.v1 inkl. context_bindings_for_model (IDs).
  • GET /api/maturity-models/export-resolved: shinkan.maturity_matrix_resolved.v1 (Query: focus_area_id, optional style_direction_id, training_type_id).
  • POST /api/maturity-models/import: create | replace, optional import_bindings.

2.4 Komplett-Stack Test → Prod

  • GET /api/admin/matrix-stack/export, POST /api/admin/matrix-stack/import — siehe matrix_stack_bundle.py.

2.5 Frontend (Admin)

  • AdminMaturityModelsPage.jsx, MaturityModelBindingsAdmin.jsx, MaturityMatrixToolsAdmin.jsx; APIs in api.js.

3. Trainingsrahmenprogramm & PlanungsBlueprint (kurz)

  • 036 / 037: Bibliotheks-Rahmen, Slot-Inhalt als training_units mit framework_slot_id; POST /api/training-units/from-framework-slot.
  • Code: training_framework_programs.py, training_planning.py; Frontend TrainingFrameworkProgramEditPage.jsx, createTrainingUnitFromFrameworkSlot in api.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, tags ab passender Migration).
  • exercise_media: optional media_asset_id; weiterhin Embeds ohne Asset; Kontext/Sortierung/Titel wie bisher.
  • platform_media_storage: Superadmin — relativer Unterpfad unter MEDIA_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. Kontext ssetoken wo vorgesehen).
  • POST /api/exercises/{id}/media/from-asset: bestehendes Asset verknüpfen.
  • Übungs-Uploads erzeugen/verknüpfen media_assets; Governance wie library_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 in MEDIA_ASSETS_AND_ARCHIVE_SPEC.md.

Governance & Mandant:

  • visibility=official für Übungen: nur Superadmin; Medien official: Lifecycle/PATCH schwerpunktmäßig Superadmin (Plattform-Admin nicht gleich Superadmin).
  • Aktiver Verein: profiles.active_club_id, Header X-Active-Club-Id, Response effective_club_id — nach 0.8.59 konsistent inkl. Plattform-Admin beim Reload (Backend tenant_context, Frontend getResolvedActiveClubIdForUi + 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

  1. Inline §11: Syntax festlegen (z.B. {{exerciseMedia:id}} → kanonisches HTML), Server normalisieren bei Speichern, einen renderExerciseRichText()-Pfad im Frontend.
  2. Tests: pytest für media_assets-Router (Leserechte, Lifecycle, from-asset); ggf. Snapshot der Pfad-Umzug-Logik.
  3. Retention: Job-Dokumentation + Betrieb (ENV, Intervall); Dry-Run beschreiben.
  4. S3/Adapter: Speicher-Abstraktion §7 — wenn Produkt es verlangt.
  5. 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.