All checks were successful
Deploy Development / deploy (push) Successful in 41s
Test Suite / pytest-backend (push) Successful in 43s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Successful in 34s
Test Suite / playwright-tests (push) Successful in 1m21s
- Updated `PROJECT_STATUS.md` to reflect the implementation of F15 features, including the unified slot review and handling of `findings_stale`. - Enhanced `PROGRESSION_GRAPH_SLOT_EDITOR_SPEC.md` with detailed descriptions of new functionalities related to the match dialog and path quality assessments. - Introduced new functions in `exercise_progression_graphs.py` to validate exercise visibility against progression graph settings, ensuring proper governance. - Improved frontend components to support new governance parameters (visibility and club_id) in exercise creation workflows. - Updated documentation in `HANDOVER.md` and `PLANNING_KI_ROADMAP.md` to outline the latest developments and validation results for the F15 features. - Enhanced utility functions for exercise creation to incorporate governance settings, improving the overall user experience in the path builder and editor.
333 lines
30 KiB
Markdown
333 lines
30 KiB
Markdown
# Shinkan Jinkendo – Entwicklungsstand & Handover
|
||
|
||
**Stand:** 2026-05-22 (F15 Graph-Match & getrennte Pfad-QS, lokal nach **0.8.233**)
|
||
**App-Version / DB-Schema:** App **`0.8.233`** (Planungs-KI F11–F14, Katalog-Kontext); **F15** siehe §2.8 — DB unverändert (`DB_SCHEMA_VERSION`, Migration **088**).
|
||
|
||
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 |
|
||
|--------|------|
|
||
| **Architektur-Zielbild, Refaktor, Roadmap, Regeln** | **`docs/architecture/README.md`** |
|
||
| **Performance-Baseline (Phase 0)** | **`docs/architecture/BASELINE_SNAPSHOT.md`**, **`scripts/load/README.md`** |
|
||
| 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` |
|
||
| KI-Prompt-System — Zielarchitektur (Roadmap) | `.claude/docs/technical/AI_PROMPT_TARGET_ARCHITECTURE.md` |
|
||
| Tenant-Endpoints (Audit) | `.claude/docs/working/ACCESS_LAYER_ENDPOINT_AUDIT.md` |
|
||
| Rahmenprogramm · Planung | `.claude/docs/technical/TRAINING_FRAMEWORK_SPEC.md` |
|
||
| **Trainingsmodule & Kombinationsübungen (Fachspez, Drift-Schutz)** | `.claude/docs/functional/Shinkan Trainingsmodule Kombinationsuebungen Spezifikation V2.md` (§ 10.2.1 Archetyp-IDs, § 10.4 Coaching-Stufen, **Anhang A** Code-Abgleich) |
|
||
| **Umsetzungsplan** (Module/Kombination/Coach) | `.claude/docs/working/TRAINING_MODULES_IMPLEMENTATION_PLAN.md` |
|
||
| Überblick DB | `.claude/docs/technical/DATABASE_SCHEMA.md` |
|
||
| Domäne | `.claude/docs/functional/DOMAIN_MODEL.md` |
|
||
| **Gewichtetes Fähigkeiten-Scoring (Phase 3)** | `.claude/docs/technical/SKILL_SCORING_SPEC.md` |
|
||
| **Planungs-KI — Katalog-Prompt-Snippets (H1)** | **`docs/architecture/PLANNING_CATALOG_PROMPT_SNIPPETS.md`** |
|
||
| **Lieferliste inkl. Medien & Formular-UX** | `.claude/docs/library/FEATURES_DELIVERED_2026-Q2.md` §6, §16 |
|
||
| **Fachlicher Nutzerüberblick (Design/Product)** | **`docs/FACHLICHE_NUTZERFUNKTIONEN.md`** |
|
||
|
||
---
|
||
|
||
## 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`.
|
||
|
||
### 2.6 Gewichtetes Fähigkeiten-Scoring (Phase 3, Stand 2026-05-20)
|
||
|
||
- **Spec:** `.claude/docs/technical/SKILL_SCORING_SPEC.md`
|
||
- **Backend:** `skill_scoring.py`, `routers/skill_profiles.py` — Profile on-the-fly aus Übungsvorkommen + `exercise_skills`; **Peer-Kontext getrennt** (`framework_program` | `training_module` | `progression_graph`) über `library_content_visibility_sql`
|
||
- **Metriken:** Trainingsgewicht (`weight`); **Peer-%** (`universal_percent`, max. 100 %) nur unter sichtbaren Bausteinen **desselben Typs**; ★ = stärkster Peer je Fähigkeit
|
||
- **API:** Skill-Profile pro Artefakt; `POST /api/skill-profiles/batch-summaries` für Listen; `GET /api/skill-discovery/suggestions`
|
||
- **Frontend:** KPI-Kacheln + Filter-Modal (UX wie Übungsliste) auf **`/planning/framework-programs`** und **`/planning/training-modules`**; Panels in Editoren; Discovery auf Fähigkeiten-Seite; `SkillTreeMultiSelect` mit Portal-Dropdown in Modals
|
||
- **Offen (Backlog):** Corpus-Caching bei großen Bibliotheken; Tests für Typ-Trennung; Filter-Persistenz; Skill-Filter im Dialog „Rahmen übernehmen“; API-Umbenennung `club_*` → Peer-Namen
|
||
|
||
### 2.7 Übungsformular UX, Freigabelevel & Varianten-Speichern (Stand 2026-05-20)
|
||
|
||
- **Code:** `frontend/src/components/exercises/ExerciseFormPageRoot.jsx`, `ExerciseFormLayout.jsx`, `ExerciseCatalogAssocEditor.jsx`, `ExerciseSkillsEditor.jsx`, `frontend/src/constants/exerciseGovernanceLabels.js`, `exerciseSkillIntensity.js`
|
||
- **Tab-Navigation:** Stammdaten | Anleitung | Einordnung | (Kombination) | Varianten | Medien & Mehr — `PageSectionNav` mit farbigen Panels (`.exercise-form-edit` in `app.css`); Varianten/Medien erst nach erstem Speichern aktiv; Kombi-Übungen ohne Varianten-Tab
|
||
- **Freigabelevel:** UI-Label für `exercises.visibility` in Formular, Liste, Filter, Bulk, Picker — API-Feldname unverändert
|
||
- **Fähigkeiten:** Intensität `niedrig`/`mittel`/`hoch` (Default `mittel`); kein Primär-Flag in UI; Backend setzt `exercise_skills.is_primary` immer `false`
|
||
- **Varianten:** Speichern in der **Aktionsleiste** persistiert zuerst geänderte Varianten (`persistPendingVariantChanges`), dann Übungs-Stammdaten; „Variante anlegen“ als `type="button"` ohne verschachteltes Formular (`createVariantFromDraft`)
|
||
- **Governance (Übungen):** Owner = `created_by`; Bearbeiten = Ersteller, Plattform-Admin oder `can_plan_in_club` bei `visibility=club`; Löschen `club` = nur `club_admin`; Details **`FEATURES_DELIVERED_2026-Q2.md`** §16, **`EXERCISES_API_SPEC.md`** Permissions
|
||
|
||
### 2.8 KI Assistenz Übungen & Planungs-KI (Stand **0.8.233**)
|
||
|
||
**Zentrale Ist-Doku (Progressionsgraph-KI):** **`docs/architecture/PLANNING_PROGRESSION_GRAPH_KI.md`** — bei Drift zuerst dort pflegen.
|
||
|
||
**Retrieval / Scoring:** `.claude/docs/working/PLANNING_EXERCISE_SUGGEST_CONTEXT.md`
|
||
**Zielarchitektur Roadmap:** `.claude/docs/working/PLANNING_PROGRESSION_ROADMAP_SPEC.md`
|
||
**Produkt-Roadmap Phase G+:** `docs/architecture/PLANNING_KI_ROADMAP.md`
|
||
|
||
| Phase | Inhalt | Status |
|
||
|-------|--------|--------|
|
||
| **P0–P2, A–C2** | Übungssuche, Voll-Library, Graph-Bias, Varianten | ✅ bis **0.8.184** |
|
||
| **C3, E–E3** | Pfad-Builder, Semantik, QA, Gap-Offers | ✅ bis **0.8.203** |
|
||
| **D** | `planning_context` an `suggestExerciseAi` | ✅ **0.8.208** |
|
||
| **F0–F4** | Roadmap-Pipeline, LLM 078/079, `roadmap_first`, UI-Review | ✅ **0.8.205–209** |
|
||
| **F5** | Start/Ziel strukturiert, LLM **087**, Zwei-Schritt-UI | ✅ **0.8.210–214** |
|
||
| **F6** | Gap-Prep-Modal, reicher KI-Kontext (`planning_exercise_form_context`) | ✅ **0.8.212–214** |
|
||
| **F7** | `planning_skill_expectations` — Retrieval + UI + Gap | ✅ **0.8.215–216** |
|
||
| **F8** | Editierbare `stage_specs` (Belastung, Erfolgskriterien) | ✅ **0.8.216** |
|
||
| **F9** | `planning_roadmap` JSONB am Graph (Migration **088**) | ✅ **0.8.217** |
|
||
| **F10** | Stufen-Lernziel-Gate, kein blindes Rank-Fallback | ✅ **0.8.218** |
|
||
| **F11** | Auto-Rematch + Stufen-Spec-Refine + mehrstufige QS | ✅ **0.8.225–0.8.230** |
|
||
| **F12** | Post-Match-Gate, LLM-QA nach Rematch, Gap-Timing, `roadmap_unfilled`-Sync | ✅ **0.8.231–0.8.232** |
|
||
| **F13** | **`planning_catalog_context`** (Fokus/Stil/TT/ZG) im Match + Graph-Artefakt | ✅ **0.8.233** |
|
||
| **F14** | **`ProgressionGraphEditor`** — Slot-UI + Planungskontext-Dropdowns | ✅ **0.8.233** |
|
||
| **F15** | Unified Slot-Review (Match-Dialog), getrennte Pfad-QS, `findings_stale` | ✅ lokal (nach 0.8.233) |
|
||
| **H1** | Katalog-Prompt-Snippets (modulare LLM-Anweisungen) | 🔲 Spec **`docs/architecture/PLANNING_CATALOG_PROMPT_SNIPPETS.md`** |
|
||
|
||
**Architektur (verbindlich):** Drei Schichten — (1) **Katalog-Dimensionen** (DB, jetzt im Match verdrahtet; **H1:** zusätzlich Prompt-Snippets), (2) **Technik-Disambiguierung** (Code, nur bei `topic_type=technique`), (3) **Didaktik** (Roadmap + LLM-QS, nicht im Vokabular). Progressionsgraph = **Roadmap-first**, **keine Gruppenanalyse**. Bestehender Graph = **leichter Nachfolger-Bias** ab Schritt 2. Trainingsplanung = **eigene Pipeline** (Phase G) — Wiederverwendung der Bausteine, siehe Ist-Doku §16.
|
||
|
||
**Validierung (Mae Geri, Härtetest):** Roadmap-QS nach Trainer-Roadmap oft **~85–88 %** — gilt **Stufenlogik**, nicht leere Slots. **Gesamt-Pfad-QS** = Minimum aus **`roadmap_qa`** + **`assignment_qa`** (leere Slots → Besetzung ~8–15 %). Workbench universell; Mae Geri Referenzfall.
|
||
|
||
#### F15 — Match-Dialog, Bewertung, Pfad-QS (Stand 2026-05-22)
|
||
|
||
| Thema | Ist |
|
||
|--------|-----|
|
||
| **„Übungen matchen“** | Schritt 1: `evaluate_only` (wie „Graph bewerten“) · Schritt 2: `unified_slot_review: true` → Dialog **pro Slot** (Bewertung, Bibliotheks-Alternative, optional KI) |
|
||
| **Vorauswahl Dialog** | Bibliothek nur bei Stufen-Fit **≥ 50 %** und besser als aktuell; bei leerem Slot + schwacher Bibliothek → **KI-Vorschlag** vorausgewählt |
|
||
| **Übernahme** | Nur gewählte Slots speichern — **keine** automatische teure Nach-Bewertung |
|
||
| **Bewertung veraltet** | Nach Graph-Änderungen Hinweis im Findings-Panel; persistiert als **`findings_stale`** im `planning_roadmap`-Artefakt (mit Speichern) |
|
||
| **Getrennte QS** | `path_qa.roadmap_qa` (Stufen/Roadmap/LLM) + `path_qa.assignment_qa` (Slot-Befüllung); **`quality_score`** = Minimum beider |
|
||
| **UX-Fix** | Slot-Karten: stabiler React-Key (`slot-{index}`) — Lernziel editierbar ohne Fokusverlust |
|
||
|
||
**Code:** `ProgressionOptimizeCompareModal.jsx`, `planning_exercise_path_builder.py` (`_build_unified_slot_review_entry`, `_slot_auto_select_*`), `planning_exercise_path_qa.py` (`build_*_qa_snapshot`), `progression_graph_planning_artifact.py` (`findings_stale`), `progressionGraphDraft.js`
|
||
|
||
**Backend-Kern:** `planning_progression_roadmap.py`, `planning_exercise_path_builder.py`, `planning_catalog_context.py`, `planning_path_rematch.py`, `planning_path_refine_stage.py`, `planning_path_qa_pipeline.py`, `planning_skill_expectations.py`, `planning_exercise_form_context.py`, `planning_exercise_path_ai_fill.py`, `progression_graph_planning_artifact.py`
|
||
|
||
**API:** `POST /api/planning/progression-path-suggest` · `PUT /api/exercise-progression-graphs/:id` (`planning_roadmap`, `planning_catalog_context`) · `POST …/edges/sequence`
|
||
|
||
**Frontend:** **`ProgressionGraphEditor`** (primäre Workbench), `ExerciseProgressionPathBuilder`, `ExerciseGapFillPrepModal`, `progressionGraphDraft.js`, `planningContextForExerciseAi.js`
|
||
|
||
**Offen (priorisiert):**
|
||
1. Dev-Regression: Gewaltschutz / Breitensport / Kinder (nicht nur Mae Geri)
|
||
2. **PathBuilder-Parität** — gleiche Katalog-Dropdowns wie GraphEditor
|
||
3. UI-Wizard (4 Schritte: Ziel → Roadmap → Match → Lücken)
|
||
4. Graph-Erweiterungsmodus (Start ab Knoten)
|
||
5. Phase D′ — Auto KI-Gap-Fill bei persistent leeren Slots
|
||
6. **Trainingsplanung Phase G** — Gruppenkontext-Pack, Scopes `training_section` / `framework_slot` (Ist-Doku §16)
|
||
7. Technik-Katalog konfigurierbar (Backlog)
|
||
8. **H1** — Katalog-Prompt-Snippets (modulare LLM-Anweisungen)
|
||
|
||
#### Übungs-KI Formular / Schnellanlage (Stand **0.8.171**)
|
||
|
||
- **Planungs-Übungssuche:** siehe Tabelle oben — getrennt von Formular-KI.
|
||
- **Doku:** Umsetzung `.claude/docs/working/AI_EXERCISE_IMPLEMENTATION_PLAN.md`; Profil-/JSON-Konzept `.claude/docs/working/AI_SKILL_RETRIEVAL_PROFILES_SPEC.md`; Ist-Prompt/UI **`AI_PROMPT_SYSTEM_SPEC.md`**; API-Felder **`KI_FEATURES_SPEC.md`** §5.2
|
||
- **Kontext / Job:** **`ai_prompt_context`** (Titel, Ziel, Durchführung, Vorbereitung, Trainer-Hinweise, Fokus); **`ai_prompt_job`** — **`run_exercise_form_ai_suggestion`**; **`ai_prompt_runtime`**; **`exercise_ai`** — OpenRouter
|
||
- **DB:** **`067`** ai_prompts · **`069`** default_template · **`068`** ai_skill_retrieval_profiles · **`070`** openrouter_model · **`071`** **`exercise_instruction_rewrite`**
|
||
- **Prompt-Slugs:** `exercise_summary`, `exercise_skill_suggestions`, **`exercise_instruction_rewrite`** (Anleitung JSON, prägnant, HTML p/ul/ol/li)
|
||
- **API:** `POST /api/exercises/ai/suggest` — **`include_instructions`**, Body **`preparation`**, **`trainer_notes`**; Response **`instructions.fields`**; **`POST …/ai/regenerate`** mit **`instructions`** in `regenerate`
|
||
- **Pflege:** Superadmin **`/admin/ai-prompts`**, **`/admin/ai-skill-retrieval`**
|
||
- **Diagnose:** **`SHINKAN_AI_DEBUG=1`** — Logs `shinkan.exercise_ai`, `shinkan.openrouter`
|
||
- **Frontend Formular:** Tab **Anleitung** — **„KI: Anleitung überarbeiten“**; Vorschau-Dialog pro Feld (**`ExerciseFormPageRoot.jsx`**)
|
||
- **Frontend Schnellanlage:** **`ExercisePickerModal`** (Planung/Rahmen) — Volltext vs. Planungs-KI; KI-Neuanlage im Picker. **`ExercisesListPageRoot`** — Schalter **„Neu mit KI-Assistent“**: Planungs-KI-Suche (`usePlanningExerciseSuggestSearch`) + **`ExerciseAiQuickCreateModal`**; normales **„+ Neu“** ausgeblendet solange aktiv.
|
||
|
||
---
|
||
|
||
## 3. Trainingsrahmenprogramm & Planungs‑Blueprint (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`.
|
||
|
||
### Trainingsplanung: Einheiten-Editor als Vollseite (Stand **0.8.149**)
|
||
|
||
- **Routen:** `/planning` (Hub), `/planning/units/new`, `/planning/units/:id/edit`; Legacy `/planning?unit={id}` → Redirect auf Edit-Route.
|
||
- **Code:** `TrainingUnitEditPage.jsx`, `TrainingUnitFormShell.jsx`, `planningUnitRoutes.js`, `trainingUnitEditorCore.js` (Payload-Drift-Schutz + Vitest).
|
||
- **Hub:** `TrainingPlanningPageRoot.jsx` ohne Einheiten-Modal; Modals nur noch Import, Trainer zuweisen, Rahmen-Session/Modul aus Liste.
|
||
- **Spec / DoD:** `docs/architecture/TRAINING_UNIT_EDIT_PAGE_MIGRATION.md`; Playwright **14–15** (Edit-Route, Legacy-Redirect).
|
||
|
||
### Trainingsplan: Phasen, parallele Streams und Coaching (Stand **0.8.137–0.8.140**)
|
||
|
||
- **Schema / API:** Migration **063** — `training_unit_phases`, `training_unit_parallel_streams`; Sektionen mit `phase_id` bzw. `parallel_stream_id`. **`GET /api/training-units/:id`** liefert **`phases`** (verschachtelt) und weiterhin flache **`sections`**. **`PUT/POST`** mit **`phases`** für Breakout-Einheiten (vgl. `CHANGELOG` **0.8.138**); Legacy: flache `sections` → implizite Ganzgruppen-Phase.
|
||
- **Planung (Frontend):** Breakout-Panel — neue Ganzgruppen-/parallele Phase, Streams in der Parallelphase; Speichern sendet `phases` bei phasierten Einheiten (`trainingUnitSectionsForm.js`, `TrainingPlanningPage`).
|
||
- **Durchführung „Plan & Ablauf“:** `TrainingUnitRunPage.jsx` nutzt **`sectionsWithPlanLocForDisplay`** / **`buildPlanRunViewModelFromSections`** aus **`frontend/src/utils/trainingPlanUtils.js`**, damit Anzeige mit Phasen/Streams konsistent ist (inkl. Normalisierung fehlender `planLoc` auf flachen Sektionen).
|
||
- **Coaching-Modus (`TrainingCoachPage.jsx`):**
|
||
- Flache Timeline aus Phasen (`flattenPlanTimeline`): **Split-Punkte** (`branch_gate`) bis Stream-Wahl, eine gewählte Spur pro Parallelphase, **Outline**, Timer, Ist-Minuten pro Item.
|
||
- **Rejoin nach Parallelphase:** Beim Übergang **Parallel → Ganzgruppe** (oder **Parallel → nächster Split** / `branch_gate`) erscheint die Karte „Parallelphase · Abschluss“ mit **„Gruppen zusammengeführt — weiter mit dem Plan“**, solange noch Einträge folgen; am Planende weiter **„Zur Nachbereitung“** (`coachShouldPromptSplitRejoinTransition` in `trainingPlanUtils.js`).
|
||
- **Nachbereitung / Speichern:** Payload über **`buildCoachSavePlanPayload`** (wie Planungseditor: **`phases`**, keine Zerstörung phasierter Struktur). Nach erfolgreichem Speichern: Coach-Session-Storage bereinigt, **`navigate('/planning/run/:unitId', { replace: true })`** (Plan & Ablauf).
|
||
- **Robustheit:** Abschnitte ohne Eintrag im `phases`-Baum, die nach Erben fälschlich **`parallel`** wären, werden für die **Anzeige** als **Ganzgruppenblock** nach der letzten bekannten Phasen-Ordnung ausgewiesen (`sectionsWithPlanLocForDisplay`).
|
||
- **Konzept / technische Spec:** `.claude/docs/functional/PARALLEL_TRAINING_STREAMS_CONCEPT.md`, `.claude/docs/technical/PARALLEL_TRAINING_STREAMS_SPEC.md`.
|
||
|
||
#### Arbeitspaket „Coaching & Breakout“ — noch offen
|
||
|
||
| # | Thema | Kurzbeschreibung |
|
||
|---|--------|------------------|
|
||
| 1 | **Backend / Datenkonsistenz** | Neue oder verschobene Sektionen konsistent in **`phases`** persistieren (nicht nur Client-Normalisierung). |
|
||
| 2 | **UX nach Speichern** | Optional: **im Coach bleiben** vs. **Planansicht** (aktuell: immer Plan & Ablauf). |
|
||
| 3 | **Kantenfälle Coach** | „Fertig“ bei abweichendem **Timer-Owner** vs. **Rejoin**/letzter Schritt prüfen. |
|
||
| 4 | **Tests** | Smoke: zwei Splitphasen, Ganzgruppe dazwischen/am Ende, Nachbereitung speichern, Rejoin. |
|
||
| 5 | **Run-UI vs. Spec** | Technische Spec §5.2 (Tabs pro Stream): Abgleich mit **`TrainingUnitRunPage`**. |
|
||
| 6 | **Trainer pro Stream** | UI und Policy zu **`assigned_trainer_profile_ids`** / Kopf-Co-Trainer offen. |
|
||
| 7 | **Vorlagen** | `training_plan_templates` phasen-/stream-kompatibel (Spec §5.3). |
|
||
| 8 | **Kombi-Coach B/C** | Fachspez **§ 10.4 / § 10.6**, `TRAINING_MODULES_IMPLEMENTATION_PLAN.md` Phase **4**. |
|
||
|
||
### Trainingsmodule, Kombinationsübungen und Coach Stufe A
|
||
|
||
- **Fachspez & Drift-Schutz:** `.claude/docs/functional/Shinkan Trainingsmodule Kombinationsuebungen Spezifikation V2.md` (**§ 10.2.1** IDs, **§ 10.4** Coaching-Stufen, **§ 10.6** Produkt-Backlog, **Anhang A** Abgleich).
|
||
- **Umsetzungsplan:** `.claude/docs/working/TRAINING_MODULES_IMPLEMENTATION_PLAN.md` (Phase **2** / **4** teilweise; Pakete **4a–g** — u. a. **4e** Archetyp-Admin, **4f** Massen-Vorbelegung, **4g** Backend-Validierung).
|
||
- **Ist kurz:** Trainingsmodule-Bibliothek (Phase **1**) umgesetzt; Kombi-Katalog (**056**), Planungs-Snapshot **`planning_method_profile` (057)** mit **Client-Merge** Katalog+Planung (`comboPlanningMethodProfile.js`); Planung: Modal **„Ablauf bearbeiten…“**, Klammer `CombinationPlanBracket`; Coach **Stufe A** mit lesenden Profil-Labels und konsistenter Slot-Darstellung (`CombinationCoachSlots`, `ExerciseFullContent`). **Offen:** Coach **Stufe B/C** (individuelle Archetyp-Steuerung), **Administrierbarkeit der Archetypen** (derzeit nur Konstanten), **einfache Vorbelegung aller** Zeit-/Anzahlfelder, **serverseitige** Profil↔Archetyp-Restriktionen — siehe Fachspez **§ 10.6**.
|
||
|
||
---
|
||
|
||
## 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. Inline-Medien im Fließtext (Spec Abschnitt 11 — umgesetzt)
|
||
|
||
**Ist:** Platzhalter-Syntax, zentraler Render-Pfad, Modal-Picker, Größenwahl, Drag-and-Drop in den Übungstextfeldern — siehe **`MEDIA_ASSETS_AND_ARCHIVE_SPEC.md`** (Abschnitt 11), **`FEATURES_DELIVERED_2026-Q2.md`** Abschnitt 12.3 und **`PROJECT_STATUS.md`**.
|
||
|
||
**Weiteres:** UX-Politik, ggf. strategische Vereinheitlichung der Referenzmodellierung (reine Asset-Referenz vs. `exercise_media`) — siehe Nächste Schritte in **`PROJECT_STATUS.md`**.
|
||
|
||
---
|
||
|
||
## 6. P-13: Content-Meldeverfahren (vollständig implementiert, 2026-05-11)
|
||
|
||
**DSA-konformes Meldeverfahren (KRIT-03) — App 0.8.87–0.8.94.**
|
||
|
||
**Backend (`backend/routers/content_reports.py`, Migrationen 052–053):**
|
||
- `POST /api/content-reports` — optionale Auth; `official`-Medien ohne Login meldbar; E-Mail-Bestätigung an Melder + Benachrichtigung aller Plattform-Admins (best-effort).
|
||
- `GET /api/me/inbox/content-reports` — Plattform-Admin: alle Meldungen; Club-Admin: nur Meldungen zu Medien eigener Vereine.
|
||
- `GET /api/content-reports/{id}` — Plattform-Admin + zuständiger Club-Admin.
|
||
- `PATCH /api/content-reports/{id}` — Status-Übergang (submitted → under_review → resolved/rejected); Wiedereröffnen (→ submitted) setzt Prüferfelder zurück; Audit-Log-Einträge bei Status- und Notizänderungen.
|
||
- `POST /api/content-reports/{id}/legal-hold` — Superadmin (immer) oder Club-Admin (Vereinsmedien, nicht `official`); integriert P-11 `set_legal_hold()`; plain Admin erhält früh 403.
|
||
- Automatische Priorisierung `high` für `minors`/`illegal_content`/`youth_protection`.
|
||
- Migration 053: `content_report_filed` Event-Typ in `media_asset_audit_log` CHECK-Constraint.
|
||
- `open_report_count` in `list_media_assets`-Response für Admin-Nutzer.
|
||
- 15 Backend-Tests in `backend/tests/test_p13_content_reports.py` (alle grün nach CI-Fix 0.8.94).
|
||
|
||
**Frontend:**
|
||
- `ReportContentModal.jsx` — Melde-Formular; `onSuccess`-Callback; readOnly-Felder für eingeloggte Nutzer.
|
||
- `MediaPreviewModal.jsx` — geteilter Vorschau-Dialog; optionale Melden- und Bearbeiten-Buttons.
|
||
- `InboxPage.jsx` — zweiter Abschnitt „Inhaltsmeldungen”; `WorkflowBar` (3-Schritte-Fortschrittsbalken); `ReportDetailModal` mit Workflow, Prüferinfo, Notiz, Wiedereröffnen-Button; Archiv-Trennung (offen vs. abgeschlossen, kollabierbar); Legal-Hold-Button für Superadmin + Club-Admin.
|
||
- `OrgInboxContext.jsx` — liefert `contentReports`, `contentReportCount`, `canAccessContentReports`, `isClubAdmin`, `isPlatformAdmin`, `isSuperadmin`, `contentReportsError`; Club-Admins haben Zugriff auf Berichte.
|
||
- `MediaLibraryPage.jsx` — rotes Badge mit `open_report_count` auf Medienkarten; Journal-Eintrag für `content_report_filed`; Badge-Aktualisierung via `onSuccess`.
|
||
- Melde-Button in **MediaLibraryPage** (Grid + Liste + Viewer), **ExerciseFormPage** (Viewer), **ExerciseAttachmentMediaStrip** (Viewer).
|
||
|
||
**Offen (explizit zurückgestellt):**
|
||
- P-14 Moderations-UI (eigene Seite), P-15 Uploader-Benachrichtigung bei Sperrung, P-16 Beschwerdeverfahren.
|
||
- Melde-Einstieg im Coaching-Modus (Feedback-Schritt, nicht kritisch).
|
||
|
||
---
|
||
|
||
## 7. Nächste Session — sinnvolle Arbeitspakete
|
||
|
||
### Planungs-KI (priorisiert)
|
||
|
||
1. **H1 Katalog-Prompt-Snippets:** modulare LLM-Anweisungen — **`docs/architecture/PLANNING_CATALOG_PROMPT_SNIPPETS.md`** (Priorität: Primärfokus → Trainingsstil → Zielgruppe → Stilrichtung).
|
||
2. **Dev-Regression:** Katalog-Match für Gewaltschutz, Breitensport, Kinder — nicht nur Mae-Geri-Härtetest.
|
||
3. **PathBuilder-Parität:** `planning_catalog_context`-Dropdowns auch in `ExerciseProgressionPathBuilder`.
|
||
4. **UI-Wizard:** 4 Schritte (Ziel & Katalog → Roadmap → Match → Lücken); Backend-Pipeline unverändert.
|
||
5. **Phase D′:** automatisches KI-Gap-Fill bei persistent `roadmap_unfilled`.
|
||
6. **Trainingsplanung G0–G4:** Katalog in Einheits-Editor, Scopes `training_section`/`framework_slot`, Abschnitts-QS, Gruppenkontext-Pack — Details **`PLANNING_PROGRESSION_GRAPH_KI.md`** §16, **`PLANNING_KI_ROADMAP.md`**.
|
||
7. **Technik-Katalog externalisieren** (Backlog): `concept_groups` konfigurierbar statt Code-Tuples.
|
||
8. **Mitai Workflow-Engine** erst nach stabiler Phase G.
|
||
|
||
### Allgemein
|
||
|
||
6. **Coaching & Breakout (Regression):** Mehrphasen-Einheit mit zwei Splits und Ganzgruppen dazwischen — Rejoin-Karten, Nachbereitung speichern, Anzeige in Plan & Ablauf (`docs/HANDOVER.md` Arbeitspaket-Tabelle).
|
||
7. **P-13 Frontend-Verifikation:** Melde-Flow in Medienbibliothek, Inbox-Workflow (Status, Archiv, Wiedereröffnen), Club-Admin-Ansicht manuell auf Dev-System durchspielen. E-Mail-Benachrichtigungen verifizieren (SMTP-Log).
|
||
8. **Inline (Spec Abschnitt 11):** Basis umgesetzt — verbleibend: gezielte UX-Politik; optional Server-Normalisierung/Absicherung prüfen, falls Produkt es verlangt.
|
||
9. **Tests:** pytest für `media_assets`-Router (Leserechte, Lifecycle, `from-asset`); ggf. Snapshot der Pfad-Umzug-Logik.
|
||
10. **Retention:** Job-Dokumentation + Betrieb (ENV, Intervall); Dry-Run beschreiben.
|
||
11. **S3/Adapter:** Speicher-Abstraktion (Spec Abschnitt 7) — wenn Produkt es verlangt.
|
||
12. **Rahmen/UI:** Kalender „aus Rahmen übernehmen” weiter anbinden (parallel, unabhängig von Medien).
|
||
13. **Fachlicher Nutzerüberblick:** bei größeren UX-Änderungen **`docs/FACHLICHE_NUTZERFUNKTIONEN.md`** mitpflegen.
|
||
14. **Kombinations-Coach (Archetyp B/C):** Fachspez § 10.4 / **§ 10.6**; nach Implementierung **Anhang A** + `TRAINING_MODULES_IMPLEMENTATION_PLAN.md` aktualisieren (kein Doc-Drift).
|
||
15. **Archetyp-Administration:** Konfiguration oder DB statt nur `COMBINATION_ARCHETYPE_IDS` / `combinationArchetypes.js` (Paket **4e**).
|
||
16. **Kombi-Zeitfelder:** Massen-Vorbelegung aller Slots aus Archetyp/Global + optionales Modal beim Archetypwechsel (Paket **4f**, `COMBINATION_TIMING_PROFILE_PLAN.md`).
|
||
17. **Backend-Validierung** `method_profile` / `planning_method_profile` je Archetyp (Paket **4g**).
|
||
|
||
---
|
||
|
||
## 8. Technische Referenz (kurz)
|
||
|
||
| Bereich | Einstieg |
|
||
|---------|----------|
|
||
| Backend API | `backend/main.py`; u. a. **`media_assets.py`**, **`exercises.py`** (`COMBINATION_ARCHETYPE_IDS`, `enrich_exercise_detail`), **`profiles.py`**, **`training_framework_programs.py`**, `tenant_context.py` |
|
||
| Coach, Plan-Timeline, PUT-Payload phasiert | `TrainingCoachPage.jsx`, **`frontend/src/utils/trainingPlanUtils.js`** (`flattenPlanTimeline`, `buildCoachSavePlanPayload`, `sectionsWithPlanLocForDisplay`, Split-Rejoin-Helfer), `TrainingUnitRunPage.jsx` |
|
||
| Coach-Kombination / Merge-Profil (Frontend) | `ExerciseFullContent.jsx`, `CombinationCoachSlots.jsx`, `CombinationPlanBracket.jsx`, `utils/comboPlanningMethodProfile.js`, `utils/combinationMethodProfileUi.js`, `constants/combinationArchetypes.js` |
|
||
| 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` |
|
||
|
||
---
|
||
|
||
## 9. Veraltete Hinweise
|
||
|
||
`.claude/docs/working/HANDOVER_NEXT_SESSION.md` verweist auf **dieses** Dokument (`docs/HANDOVER.md`) als aktuelle Basis.
|
||
|
||
---
|
||
|
||
*Ende Handover-Dokument.*
|