# Parallele Trainingsstreams — Technische Spezifikation (Umsetzung) **Status:** Entwurf · **Stand:** 2026-05-14 **Fachgrundlage:** `.claude/docs/functional/PARALLEL_TRAINING_STREAMS_CONCEPT.md` Dieses Dokument beschreibt die **Umsetzung** auf Basis der **aktuellen Codebasis** (Stand Analyse 2026-05-14): eine `training_unit` mit **`training_unit_sections`** und **`training_unit_section_items`** (Übung/Notiz, optional `planning_method_profile` für Kombinationsübungen, Migration **057**); Rahmen-**Blueprint**-Einheiten mit `framework_slot_id` (**037**); Leitung **`lead_trainer_profile_id`** (**038**); Co-Trainer **`assistant_trainer_profile_ids`** JSONB (**042**); Durchführung **`TrainingUnitRunPage`** (sequentiell über Sektionen). --- ## 1. Ist-Stand (relevant) | Bereich | Aktuell | |---------|---------| | Planstruktur | **Eine** lineare Liste `training_unit_sections` je `training_unit_id`; Items in `training_unit_section_items`. | | Rahmenprogramm | `training_framework_slots` verweisen auf **Blueprint**-`training_units` — Slots = **Serien-Spalten**, nicht simultane Breakouts in **einer** Halle. | | Kombinationsübung | Ein **Item** kann Kombi sein; `planning_method_profile` = Snapshot; Coaching-UI teilweise (`CombinationPlanBracket` in Run/Peek). | | Trainer-Zuweisung | `lead_trainer_profile_id`, `assistant_trainer_profile_ids` am **`training_units`**-Kopf; **keine** Zuordnung zu „welcher parallelen Spur“. | | Run-Modus | `TrainingUnitRunPage`: sortierte Sektionen/Items, Checkliste, Fortschritt in `sessionStorage` pro Einheit. | **Konsequenz:** Parallele Streams erfordern ein **erweitertes konzeptionelles „Gefäß“** unterhalb der Einheit (Phasen und/oder Streams) und eine **Verknüpfung** bestehender Sektionen mit diesem Gefäß — oder eine **Migration** zu einem neuen Pflicht-Container (siehe §3). --- ## 2. Zielarchitektur (logisch) ``` training_unit (Kalender-Einheit) ├── phase (order, kind: whole_group | parallel, optional Metadaten) │ ├── [whole_group] → sections[] → items[] (wie heute) │ └── [parallel] → stream (order, label, optional trainer_ids[]) │ └── sections[] → items[] ``` **Abwärtskompatibilität:** Einheiten **ohne** explizite Phasen/Streams verhalten sich wie heute: **implizit** eine einzige „Gemeinschaftsphase“ mit den vorhandenen Sektionen (Migration: alle bestehenden Sektionen an diese Default-Hülle hängen). --- ## 3. Datenmodell — Optionen ### 3.1 Empfohlen: explizite Phasen + Streams (normalisiert) Neue Tabellen (Namen bei Implementierung final festlegen): | Tabelle | Zweck | |---------|--------| | `training_unit_phases` | `training_unit_id`, `order_index`, `phase_kind` (`whole_group` \| `parallel`), optional `title`, `guidance_notes`, optional `planned_duration_min` | | `training_unit_parallel_streams` | `phase_id` (FK, nur wenn parent parallel), `order_index`, `title`/`label`, optional `notes`, optional `assigned_trainer_profile_ids` JSONB (oder 1:n-Hilfstabelle) | **Anpassung `training_unit_sections`:** Zusätzliche FK-Spalte(n), z. B.: - `phase_id` **NULL** und `parallel_stream_id` **NULL** → **Legacy / Default-Einheitsphase** (Migration setzt Default-Phase); oder - genau einer von `phase_id` (whole group) oder `parallel_stream_id` gesetzt. **Constraints:** CHECK: nicht beide gesetzt; bei `phase_kind = parallel` Sektionen nur unter `parallel_stream_id`; bei `whole_group` nur unter `phase_id`. **Vorteil:** Klare Semantik, Reporting, API-Shape konsistent. ### 3.2 Minimalvariante (nicht ideal fachlich) Nur **`training_unit_parallel_streams`** + `parallel_stream_id` auf Sektionen; Phasen implizit durch „Marker“-Sektionen oder Konvention. **Nicht empfohlen**, erschwert UI und Erklärbarkeit. --- ## 4. API - **`GET /api/training-units/:id`** (und Listen-Payloads wo vollständiger Plan nötig): verschachtelte Struktur **Phasen → Streams → sections → items** oder flache `sections` mit ausgefüllten `phase_id` / `parallel_stream_id` (Frontend kann normalisieren). - **`PUT/PATCH`:** Atomares Ersetzen der Phasen/Streams/Sektionen analog zu bestehendem `_replace_unit_sections`-Muster; **Validierung** der CHECK-Regeln serverseitig. - **Blueprint / Rahmen:** Blueprint-`training_units` dürfen dieselbe Struktur tragen; `GET` Kalenderliste blendet Blueprints weiter aus (`framework_slot_id IS NOT NULL`). **Governance / Mandant:** Unverändert über Einheit → `group_id`; keine neuen Mandanten-Entitäten. --- ## 5. Frontend ### 5.1 Planung (`TrainingPlanningPage`) - Darstellung als **vertikale Phasen**: Gemeinschaftsblöcke + Parallelphase mit **N Spalten** (Streams). - **Wiederverwendung:** `TrainingUnitSectionsEditor` **pro Stream** und pro Gemeinschaftsphase — analog zur Wiederverwendung **pro Rahmen-Slot** in `TrainingFrameworkProgramEditPage`. - **Co-Trainer:** UI pro Stream (`assigned_trainer_profile_ids`); Regel zur **Kopfliste** `assistant_trainer_profile_ids` festlegen (z. B. Union aller Stream-Zuweisungen für „Wer ist heute dabei“ + Rückwärtskompatibilität wenn Stream-Felder leer). ### 5.2 Durchführung (`TrainingUnitRunPage`) - Gemeinschaftsphasen: heutiges **lineares** Verhalten. - Parallelphase: **Tabs, Akkordeon oder Swipe** zwischen Streams; Fortschritt **pro Stream** (Storage-Key z. B. `${unitId}:${streamId}`). - Kombi-Items: unverändert `CombinationPlanBracket` / `effectiveComboMethodProfile`. - Optional später: Filter „nur meine Spur“ anhand Session-Profil vs. Stream-Zuweisung. ### 5.3 Vorlagen (`training_plan_templates`) - Erweiterung um **dieselbe** Phasen/Streams-Semantik (Kindtabellen oder serialisiertes JSON — Abgleich mit Kopierlogik aus Vorlage in Einheit). - **Kein** Live-Spiegel: weiterhin Materialisierung beim Anwenden. --- ## 6. Bezug Kombinationsübungen - **Variante A** (Rotation innerhalb einer Teilstrecke): ein oder mehrere **Items** vom Typ Kombi im jeweiligen Stream; Archetyp und Parameter wie in `TRAINING_MODULES_AND_COMBINATION_EXERCISES_SPEC.md`. - **Variante B** (synchron Hallenweit): erweiterte **Phasen-** oder **Stream-übergreifende** Metadaten — **nicht** in MVP-Zwang; eigenes Teilpaket nach fachlicher Freigabe (`PARALLEL_TRAINING_STREAMS_CONCEPT.md` §5.2). --- ## 7. Migration und Risiken 1. **Datenmigration:** Alle existierenden `training_unit_sections` einer Einheit einer **Default-Phase** `whole_group` zuordnen. 2. **API-Versionierung:** Clients, die nur flache `sections` erwarten, müssen angepasst werden (oder Server liefert **beides** kurzzeitig — nur wenn nötig). 3. **Performance:** Tiefe Kopien (Rahmen-Slot, Duplikat Einheit) müssen rekursiv Phasen/Streams mitsamt Sektionen/Items kopieren. 4. **Tests:** pytest für PUT/GET mit gemischten Phasen; ggf. Playwright-Smoke für Planung/Run. --- ## 8. Implementierungsphasen (Vorschlag) | Phase | Inhalt | |-------|--------| | **P1** | Schema Phasen + Streams; Migration; GET/PATCH Einheit verschachtelt; Planungs-UI; Run-UI mit Stream-Tabs | | **P2** | Trainer-Zuordnung pro Stream + effektive Anzeige; Vorlagen erweitert | | **P3** | Synchroner Hallen-Takt / Rotationsmatrix (falls fachlich freigegeben) | --- ## 9. Verwandte Dokumente | Dokument | Bezug | |----------|--------| | `functional/PARALLEL_TRAINING_STREAMS_CONCEPT.md` | Fachziele, Begriffe, Entscheidungsfragen | | `technical/TRAINING_FRAMEWORK_SPEC.md` | Rahmen-Slot vs. Parallelität | | `technical/TRAINING_MODULES_AND_COMBINATION_EXERCISES_SPEC.md` | Kombi, `planning_method_profile` | | `technical/DATABASE_SCHEMA.md`, `backend/migrations/` | DDL-Historie | | `frontend/src/pages/TrainingPlanningPage.jsx`, `TrainingUnitRunPage.jsx`, `TrainingFrameworkProgramEditPage.jsx` | Ist-UI |