# Gelieferte Features & technische Basis (Q2 2026) **Stand:** 2026-05-20 **Referenz:** `backend/version.py` — aktuelle **APP_VERSION** / **DB_SCHEMA_VERSION** (Stand Code u. a. **0.8.96**) Dieses Dokument bündelt die in der Entwicklungsphase erreichten **lieferbaren** Funktionen und die zugehörigen **technischen Artefakte**. Trainingsrahmen‑Bibliothek + Slot‑Blueprint: **`technical/TRAINING_FRAMEWORK_SPEC.md`** §2. **Progressionsgraph zwischen Übungen** (Zwischenstand, Grenzen): **§§3–4**. **Medien-Archiv & Bibliothek:** Abschnitt **12** unten + **`MEDIA_ASSETS_AND_ARCHIVE_SPEC.md`**. Detail-Spezifikationen bleiben in den verlinkten Pfaden unter `.claude/docs/technical/` und `.claude/docs/functional/`. --- ## 1. Datenbank-Migrationen (Auswahl) | Migration | Inhalt | |-----------|--------| | **032–034** | **Progressionsgraph Übung→Übung:** Container `exercise_progression_graphs`, Kanten `exercise_progression_edges`; **`notes`** (033); optionale Varianten-Endpunkte + Constraints (034) | | **028** | `exercise_media` erweitert (Embed/Metadaten), `exercise_skills` Level-Felder (VARCHAR); Medien-API | | **029** | Kanonische Fähigkeitsstufen (basis–optimierung), `model_levels`-Namen | | **030** | `training_unit_exercises.exercise_variant_id` → FK `exercise_variants(id)` ON DELETE SET NULL | | **035** | **`training_framework_programs`** + Ziele, Slots (+ frühere Slot‑Übungstabelle, heute entfallen nach **037**); **`training_plan_templates.visibility`** | | **036** | Rahmen nur Bibliothek: Kontext + M:N Trainingsarten/Zielgruppen; keine Modus-Spalten / keine Kopf‑`group_id` | | **045–046** | **`media_assets`**, `platform_media_storage`, `exercise_media.media_asset_id`, ggf. **Tags/GIN** — siehe `MEDIA_ASSETS_AND_ARCHIVE_SPEC.md` | --- ## 2. Backend – Progressionsgraphen (`routers/exercise_progression_graphs.py`) - REST unter **`/api/exercise-progression-graphs`** inkl. Kanten-CRUD, **`POST …/edges/sequence`** (Reihe auf einmal), **`POST …/edges/delete-batch`**. - AuthZ wie Trainingsvorlagen: Admin/Superadmin oder Graph‑Ersteller; Anlegen mit Trainings-/Planungsrolle (`_has_planning_role`). - Listenresponses mit Übungstiteln und Variantennamen (JOIN). --- ## 3. Backend – Übungen (`routers/exercises.py`) ### 3.1 Liste & Suche - `GET /api/exercises` mit Filtern u. a.: Fokus, Stilrichtung, Trainingsstil, Zielgruppe, Fähigkeiten, **Skill-Stufe min/max**, `visibility_any`, `status_any`, `search`, **`ai_search`** (Platzhalter, derzeit gleiche Volltextlogik wie `search`). - Optional: **`include_variants=true`** — liefert pro Übung ein kompaktes **`variants`**-JSON (id, variant_name, sequence_order) für Planung/UI. ### 3.2 Übungsvarianten (CRUD) Implementiert gemäß **`EXERCISES_API_SPEC.md`** (Varianten-Abschnitt): - `POST /api/exercises/{id}/variants` - `PUT /api/exercises/{id}/variants/{variant_id}` - `DELETE /api/exercises/{id}/variants/{variant_id}` (409, wenn andere Varianten diese als Voraussetzung nutzen) - `PUT /api/exercises/{id}/variants/reorder` — `sequence_order` 1…n Sortierung der Varianten im Detail: **`sequence_order`**, dann **`progression_level`**, dann **`id`**. ### 3.3 Medien-Upload – Größenlimits - Standard: **50 MB** pro Datei (`EXERCISE_MEDIA_MAX_UPLOAD_MB`, Default 50). - **`admin`** / **`superadmin`**: **1024 MB** Default (`EXERCISE_MEDIA_ADMIN_MAX_UPLOAD_MB`), nie unter dem Nutzer-Limit (in MB verglichen). Logik: `_upload_limit_bytes(session)` vor `read()`-Prüfung. --- ## 4. Backend – Trainingsplanung (`routers/training_planning.py`) - Strukturierte Einheiten: **`training_unit_sections`** + **`training_unit_section_items`** (Migration **031**) — Hauptpfad beim Lesen/Schreiben von Einheiten. - **`training_unit_exercises`:** Legacy-/Nebenpfad; weiterhin **`exercise_variant_id`** (Migration **030**) mit Validierung gegen die gewählte **`exercise_id`**; JOINs liefern u. a. **`exercise_variant_name`**. - **Blueprint‑Zeilen (`framework_slot_id` gesetzt):** **`GET /api/training-units`** listet diese **nicht**; **`PUT`** mit eingeschränkten Regeln (**kein** `plan_template_id` / kein Reset aus Vorlage über diesen Kopf wie bei Kalender‑Einheit). - Übernahme aus Rahmen: **`POST /api/training-units/from-framework-slot`** ({ `framework_slot_id`, `group_id`, `planned_date` }) — tiefe Kopie inkl. Sektionen/Items; **`origin_framework_slot_id`** setzt Lineage‑Light. --- ## 5. Frontend – Übungsliste (`ExercisesListPage.jsx`) - Tabs **Liste** · **Progressionsgraphen** (`ExerciseProgressionGraphPanel`): Graphen anlegen/bearbeiten, Kanten inkl. Sequenz-Bulk und Tabellenansicht. - **Filter-Modal** (Fokus, Stilrichtung, Trainingsstil, Zielgruppe, Fähigkeit + Stufen von/bis, Sichtbarkeit, Status). - **Filter-Chips** unter der Suchleiste; Klick entfernt einen Filter; Badge am Filter-Button = Anzahl Chips. - **Kein Vollbild-Spinner** bei jeder Suche: nur noch **`listFetching`** — Suchfelder bleiben im DOM (**Fokus/Cursor** bleiben erhalten); Liste zeigt optional „Aktualisiere Treffer…“. - **``** mit Titeln der aktuellen Treffer; **`autoComplete="on"`** für Browser-Vorschläge. - **`api.listExercises`**: Booleans (z. B. `include_variants`) werden als Query übergeben. --- ## 6. Frontend – Übung bearbeiten (`ExerciseFormPage.jsx`) - **Varianten-Editor**: eingeklappter Bereich (`
`), **eine Variante zur Zeit** über Dropdown oder „Neue Variante“; Felder über **`ExerciseVariantFields`**; Reihenfolge Nach oben/unten; Speichern/Löschen pro Variante. - **Medien:** Upload/Embed, **Archiv verknüpfen** (`from-asset`), Medienliste mit Vorschau, Reaktivierung bei Archiv-Konflikt — Details **§12**. - Block **Progressionsgraph** (Edit): Kanten mit Bezug zur aktuellen Übung. Hinweis: Es gibt **keine** separaten Routen `/exercises/:id/variants/...` — Bearbeitung erfolgt unter **`/exercises/:id/edit`** (Routing-Doku ggf. anpassen). --- ## 7. Frontend – Übung Detail (`ExerciseDetailPage.jsx`) - Varianten-Abschnitt mit **Meta** (Dauer, Schwierigkeit, Material, Progressionsstufe) wo vorhanden. --- ## 8. Frontend – Trainingsplanung (`TrainingPlanningPage.jsx`) - `listExercises({ include_variants: true })`. - Pro Zeile: Übung + **Variante** (optional), Dauer, Reihenfolge. --- ## 9. Rich-Text (`RichTextEditor.jsx` + CSS) - **Selection Save/Restore** vor Toolbar-Klicks (`insertUnorderedList` / `insertOrderedList` zuverlässiger bei Mehrzeilen-Markierung). - **`styleWithCSS` false** vor Formatbefehlen. - **Listen-Styling** für `.rich-text-editor ul/ol/li` (Einzüge sichtbar). --- ## 10. Admin – Matrix / Reifegrad (Kontext) - Bereits dokumentiert in **`CHANGELOG`** / Module **`maturity_models`**: Matrix-Stack-Bundle Export/Import, Kontext-Bindings — siehe `version.py` und Admin-UI-Pfade. --- ## 11. Trainingsrahmen: Bibliothek + Slot‑Blueprint (DB **036–037**) - **036:** `training_framework_programs` nur Bibliothek — `focus_area_id`, `style_direction_id`, M:N `training_framework_program_training_types` / `_target_groups`; Entfall `plan_mode`, `group_id`; Slot‑Verknüpfungen zu Kalender‑Einheiten geleert. - **037:** Pro Slot genau eine **`training_units`**‑Zeile mit **`framework_slot_id`**; Ablauf über **`training_unit_sections`** / **`training_unit_section_items`** (wie Planung); Legacy **`training_framework_slot_exercises`** Datenmigration + **`DROP` TABLE**; geplante Kopien können **`origin_framework_slot_id`** tragen. - **Router `training_framework_programs.py`:** CRUD **`/api/training-framework-programs`**, Slots im Speichern mit neuen Blueprint‑`training_units`, Hydration **`sections`/`exercises`/`blueprint_training_unit_id`**; siehe **`TRAINING_FRAMEWORK_SPEC.md`** §2.3. - **Frontend:** **`TrainingFrameworkProgramEditPage.jsx`**, **`createTrainingUnitFromFrameworkSlot`** (`api.js`). - **Doku:** **`technical/TRAINING_FRAMEWORK_SPEC.md`** §2; **`technical/DATABASE_SCHEMA.md`**; **`functional/DOMAIN_MODEL.md`** (Trainingsrahmen‑Abschnitt). --- ## 12. Trainingsplan: Phasen & parallele Streams (DB **063**, App **0.8.137–0.8.140**) - **063:** `training_unit_phases`, `training_unit_parallel_streams`; Sektionen mit `phase_id` / `parallel_stream_id`; Default-Ganzgruppenphase für Bestand. - **API:** `GET /api/training-units/:id` mit **`phases`** + **`sections`**; `PUT`/`POST` mit **`phases`** für Breakout-Einheiten (**0.8.138**); Rahmen-Slot-Materialisierung kopiert Phasen (**0.8.138**). - **Frontend:** Planung Breakout-Panel (**0.8.139–0.8.140**); **`trainingPlanUtils.js`** — `sectionsWithPlanLocForDisplay`, `flattenPlanTimeline`, `buildCoachSavePlanPayload`, Split-Rejoin (`coachShouldPromptSplitRejoinTransition`); **`TrainingCoachPage`**, **`TrainingUnitRunPage`**. - **Doku:** `.claude/docs/technical/PARALLEL_TRAINING_STREAMS_SPEC.md`, `docs/HANDOVER.md` §3, Arbeitspaket „offen“. --- ## 13. Medien-Archiv & Medienbibliothek (Migration **045** ff., App ca. **0.8.41–0.8.64**) Einzelnorm: **`technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md`**. Kurzüberblick geliefert: ### 12.1 Datenbank & Router - **`media_assets`**, **`platform_media_storage`**, **`exercise_media.media_asset_id`** (Dedupe `sha256` + Sichtbarkeit + `club_id` je nach Policy). - Router **`media_assets.py`**: Listen, PATCH, Lifecycle, Dateiauslieferung, Bulk; Integration in **`exercises.py`** (Upload, `from-asset`, Promotion/Copyright-Regeln bei `official` / Vereinsübungen). ### 12.2 Funktional (Ist) - Zentrale **Medienbibliothek** Frontend **`/media`**: Filter (Lifecycle, Medientyp, Verein für Admins), Suche, Tags, Copyright bearbeiten (rollengerecht), Kacheln/Liste, Nutzungs-Hinweise (Übungen/Planung wo implementiert). - **Papierkorb** mehrstufig (`trash_soft` / `trash_hidden`), Recovery, Superadmin-Purge; strukturierte Fehlercodes bei Governance (u. a. Übung **`CLUB_MEDIA_*`**). - **Speicher:** Pfadkonvention **`library/{vereinssegment}/…`** mit Medienkind-Unterordnern; Umzug bei Sichtbarkeits-/Vereinsänderung; effektives Wurzelverzeichnis `MEDIA_ROOT` + Superadmin-`local_relative_root`. - **Governance:** **`visibility=official`** für Übungen und schützenswerte Medien-Operationen im Wesentlichen **Superadmin**; Plattform-Admin entspricht nicht automatisch Superadmin. - **Mandant:** aktiver Verein über Profil + **`X-Active-Club-Id`**; Sync UI nach **0.8.59** (siehe `tenant_context` / `AuthContext` / `activeClub.js`). ### 12.3 Inline-Medien im Fließtext (geliefert in 0.8.60–0.8.64) - Platzhalter-Syntax: `{{exerciseMedia:id}}` (normalisiert auf `data-shinkan-exercise-media`), Validierung gegen `exercise_media` der aktuellen Übung. - Zentraler Anzeigepfad über `ExerciseRichTextBlock` inkl. Sanitize und Lifecycle-Hinweisen. - RTE-Workflow: Modal „Medien im Text“ (Mediathek + Upload), separates „Embed im Text“-Modal, Größenwahl (`small|medium|full`) und sprechende Platzhalter-Captions. - Bearbeiten: kompakte Medien-Kacheln + Drag&Drop in Textfelder; Auto-Scroll beim Drag aktiv. - UX-Schutz: Warnung bei Wechsel „Ansehen“ mit ungespeicherten Änderungen; Detailseite bietet Rückweg zur Bearbeitung. --- ## 14. Nächste sinnvolle Schritte (nicht Lieferstand) - Trainingsplanung: Kalender‑UI‑Anbindung **„aus Rahmen übernehmen“**; Visibility/Policies für geteilte Rahmen (**CURR‑004** später). - Progressions-Serien als **Blöcke** (angekündigt; Voraussetzung: `prerequisite_variant_id` / `progression_level` vorhanden). - Serverseitige **Suchvorschläge** (Autocomplete-Endpoint), falls datalist nicht reicht. - Optional: Streaming/chunked Upload für sehr große Videos (RAM-Thema). - **Medien:** Retention-Job-Betrieb; pytest-Abdeckung Archiv; S3-Adapter (Spec §7); ggf. strategischer Entscheid „exercise_media-Verknüpfung vs. reine Asset-Referenz“. --- ## 15. Gewichtetes Fähigkeiten-Scoring (Phase 3, Stand 2026-05-20) Norm: **`technical/SKILL_SCORING_SPEC.md`**. ### 15.1 Backend - **`skill_scoring.py`:** Gewichtung (Dauer × Vorkommen × Intensität × Stufen); `compute_planning_corpus_by_type()` mit getrennten Corpora; `universal_percent` capped auf 100 % - **`routers/skill_profiles.py`:** Profile-GET pro Artefakt; `POST /api/skill-profiles/batch-summaries`; `GET /api/skill-discovery/suggestions` - Sichtbarkeit: **`library_content_visibility_sql`** (Planungs-Bibliothek, nicht „nur Verein club“) ### 15.2 Frontend - **Listen:** Rahmenprogramme + Trainingsmodule — Filter-Modal (wie Übungen), Chips, `SkillTreeMultiSelect` (Portal-Dropdown) - **KPI:** `SkillProfileCompact` — Top je Unterkategorie, Score + Peer-% - **Editoren + Modal:** `SkillProfilePanel`, `SkillProfileFullModal` - **Discovery:** `SkillDiscoveryPanel` auf Fähigkeiten-Seite ### 15.3 Offen - Corpus-Caching; pytest für Typ-Trennung; Filter-Persistenz; Skill-Filter Import-Dialog „Rahmen übernehmen“ --- ## 16. Verweise | Thema | Dokument | |--------|----------| | Rahmenprogramm / Progressionsgraph | `technical/TRAINING_FRAMEWORK_SPEC.md` | | Fähigkeiten-Scoring Planung | `technical/SKILL_SCORING_SPEC.md` | | API Übungen | `technical/EXERCISES_API_SPEC.md` | | Domänenmodell | `functional/DOMAIN_MODEL.md` | | Datenbank Überblick | `technical/DATABASE_SCHEMA.md` | | Medien Upload (Limits, MIME) | `technical/MEDIA_UPLOAD_SPEC.md` | | Medien-Archiv & Lifecycle | `technical/MEDIA_ASSETS_AND_ARCHIVE_SPEC.md` | | Parallele Phasen/Streams | `functional/PARALLEL_TRAINING_STREAMS_CONCEPT.md`, `technical/PARALLEL_TRAINING_STREAMS_SPEC.md` | | Coaching/Breakout-Handover | `docs/HANDOVER.md` | | Fachlicher Nutzerüberblick | `docs/FACHLICHE_NUTZERFUNKTIONEN.md` (Repo-Root) | | Projektstatus-Kachel | `../PROJECT_STATUS.md` |