- Updated the exercise form to include a tabbed navigation structure, improving user experience with sections for Stammdaten, Anleitung, Einordnung, Varianten, and Medien & Mehr. - Introduced the concept of **Freigabelevel** (visibility level) in the UI, replacing previous terminology for clarity and consistency across components. - Implemented new AI endpoints for exercise suggestions and regeneration, allowing for dynamic content generation without direct database writes. - Removed the legacy `is_primary` flag from exercise skills in the UI, ensuring that intensity levels (`niedrig`, `mittel`, `hoch`) are the primary focus for skill management. - Enhanced the variant management process with improved saving mechanisms and UI updates to reflect changes more intuitively.
17 KiB
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-graphsinkl. 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/exercisesmit Filtern u. a.: Fokus, Stilrichtung, Trainingsstil, Zielgruppe, Fähigkeiten, Skill-Stufe min/max,visibility_any,status_any,search,ai_search(Platzhalter, derzeit gleiche Volltextlogik wiesearch).- Optional:
include_variants=true— liefert pro Übung ein kompaktesvariants-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}/variantsPUT /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_order1…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; weiterhinexercise_variant_id(Migration 030) mit Validierung gegen die gewählteexercise_id; JOINs liefern u. a.exercise_variant_name.- Blueprint‑Zeilen (
framework_slot_idgesetzt):GET /api/training-unitslistet diese nicht;PUTmit eingeschränkten Regeln (keinplan_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_idsetzt 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, Freigabelevel, 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…“. <datalist>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 (ExerciseFormPageRoot.jsx)
Routing: /exercises/new, /exercises/:id/edit — keine separaten Varianten-Routen.
6.1 Tab-Navigation (Registerkarten)
Horizontale PageSectionNav über ExerciseFormTabBar / ExerciseFormPanel (ExerciseFormLayout.jsx); farbige linke Panel-Ränder (CSS .exercise-form-edit, .exercise-form-panel--*).
| Tab | Inhalt |
|---|---|
| Stammdaten | Titel, Kurztext, Dauer/Gruppe, Equipment, Freigabelevel (visibility), Status, Verein |
| Anleitung | Ziel, Durchführung, Vorbereitung, Trainerhinweise (Rich-Text inkl. Inline-Medien) |
| Einordnung | Fokusbereiche, Stilrichtungen, Trainingsstile, Zielgruppen, Altersgruppen, Fähigkeiten (kompakte Chip-Editoren) |
| Kombination | nur bei exercise_kind=combination: Slots, Archetyp, method_profile |
| Varianten | nur nach erstem Speichern; nicht bei Kombinationsübungen |
| Medien & Mehr | Medien, Progressionsgraph, KI-Hilfen, Löschen — nach erstem Speichern |
Neue Übungen: Tabs Varianten und Medien & Mehr deaktiviert bis zur ersten Speicherung.
6.2 Freigabelevel (UI-Begriff)
Feld exercises.visibility heißt in der UI durchgängig Freigabelevel (frontend/src/constants/exerciseGovernanceLabels.js) — Liste, Filter, Bulk, Picker, Formular. API/DB-Feldname visibility unverändert.
6.3 Fähigkeiten am Übungsobjekt
- Intensität je Fähigkeit:
niedrig|mittel|hoch, Standardmittel(exerciseSkillIntensity.js). - Kein „Primär“-Schalter mehr in der UI;
is_primarybeiexercise_skillsist Legacy — Backend speichert immerfalse, Scoring ignoriert das Feld. - Kompakte Chip-Editoren für Katalog-Zuordnungen und Fähigkeiten (
ExerciseCatalogAssocEditor,ExerciseSkillsEditor).
6.4 Varianten-Editor
- Tab Varianten: eine Variante zur Zeit (Dropdown oder „Erste Variante anlegen“); Felder über
ExerciseVariantFields; Reihenfolge Nach oben/unten; Löschen pro Variante. - Speichern über Aktionsleiste:
performSaveAttemptruft zuerstpersistPendingVariantChanges()auf (geänderte Varianten per PUT, danach optional EntwurfcreateVariantFromDraft()). - Button „Variante anlegen“ (
type="button", kein verschachteltes<form>): legt Entwurf sofort per API an; alternativ mitgesichert über Speichern in der Aktionsleiste. - Snapshot
variantsSavedSnapshotReffür Dirty-Erkennung; Hinweis im Panel: Änderungen werden mit Speichern in der Aktionsleiste mitgesichert.
6.5 Medien & Progressionsgraph
- 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.
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/insertOrderedListzuverlässiger bei Mehrzeilen-Markierung). styleWithCSSfalse vor Formatbefehlen.- Listen-Styling für
.rich-text-editor ul/ol/li(Einzüge sichtbar).
10. Admin – Matrix / Reifegrad (Kontext)
- Bereits dokumentiert in
CHANGELOG/ Modulematurity_models: Matrix-Stack-Bundle Export/Import, Kontext-Bindings — sieheversion.pyund Admin-UI-Pfade.
11. Trainingsrahmen: Bibliothek + Slot‑Blueprint (DB 036–037)
- 036:
training_framework_programsnur Bibliothek —focus_area_id,style_direction_id, M:Ntraining_framework_program_training_types/_target_groups; Entfallplan_mode,group_id; Slot‑Verknüpfungen zu Kalender‑Einheiten geleert. - 037: Pro Slot genau eine
training_units‑Zeile mitframework_slot_id; Ablauf übertraining_unit_sections/training_unit_section_items(wie Planung); Legacytraining_framework_slot_exercisesDatenmigration +DROPTABLE; geplante Kopien könnenorigin_framework_slot_idtragen. - Router
training_framework_programs.py: CRUD/api/training-framework-programs, Slots im Speichern mit neuen Blueprint‑training_units, Hydrationsections/exercises/blueprint_training_unit_id; sieheTRAINING_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 mitphase_id/parallel_stream_id; Default-Ganzgruppenphase für Bestand. - API:
GET /api/training-units/:idmitphases+sections;PUT/POSTmitphasesfü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(Dedupesha256+ Sichtbarkeit +club_idje nach Policy).- Router
media_assets.py: Listen, PATCH, Lifecycle, Dateiauslieferung, Bulk; Integration inexercises.py(Upload,from-asset, Promotion/Copyright-Regeln beiofficial/ 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. ÜbungCLUB_MEDIA_*). - Speicher: Pfadkonvention
library/{vereinssegment}/…mit Medienkind-Unterordnern; Umzug bei Sichtbarkeits-/Vereinsänderung; effektives WurzelverzeichnisMEDIA_ROOT+ Superadmin-local_relative_root. - Governance:
visibility=officialfü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 (siehetenant_context/AuthContext/activeClub.js).
12.3 Inline-Medien im Fließtext (geliefert in 0.8.60–0.8.64)
- Platzhalter-Syntax:
{{exerciseMedia:id}}(normalisiert aufdata-shinkan-exercise-media), Validierung gegenexercise_mediader aktuellen Übung. - Zentraler Anzeigepfad über
ExerciseRichTextBlockinkl. 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_levelvorhanden). - 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_percentcapped 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:
SkillDiscoveryPanelauf Fähigkeiten-Seite
15.3 Offen
- Corpus-Caching; pytest für Typ-Trennung; Filter-Persistenz; Skill-Filter Import-Dialog „Rahmen übernehmen“
16. Übungen – Governance & Berechtigungen (Ist, Stand 2026-05-20)
Owner: exercises.created_by (Ersteller). Varianten haben kein eigenes created_by — Rechte leiten sich von der Eltern-Übung ab.
| Aktion | private |
club |
official |
|---|---|---|---|
| Lesen | Ersteller; Plattform-Admin | Aktive Vereinsmitglieder des Objekt-club_id; Plattform-Admin ohne Mitgliedschaft (Audit) |
Plattform-weit |
| Bearbeiten (Übung inkl. Varianten/Medien) | Ersteller; Plattform-Admin | Ersteller; Plattform-Admin; can_plan_in_club im Objekt-Verein (trainer, content_editor, division_lead, club_admin) |
Plattform-Admin |
| Löschen | Ersteller; Vereins-Admin gemeinsamer Vereine mit Ersteller | Nur club_admin im Objekt-Verein |
Nur Plattform-Admin |
Code: backend/club_tenancy.py (exercise_visible_to_profile, can_plan_in_club), backend/routers/exercises.py (_assert_can_edit_exercise, _assert_can_delete_exercise).
17. 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 |