# Parallele Trainingsstreams — Technische Spezifikation (Umsetzung)

**Status:** Umsetzung **Phase 1 (teils)** · **Stand:** 2026-05-14  
**Fachgrundlage:** `.claude/docs/functional/PARALLEL_TRAINING_STREAMS_CONCEPT.md`

Dieses Dokument beschreibt die **Umsetzung** auf Basis der **aktuellen Codebasis** (Stand 2026-05-14): **`training_unit_phases` / `training_unit_parallel_streams`** (Migration **063**) und **`training_unit_sections`** mit Phasen-/Stream-Bezug; **`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 und Coaching über **`TrainingUnitRunPage`**, **`TrainingCoachPage`** und **`trainingPlanUtils.js`**.

---

## 1. Ist-Stand (Code, 2026-05-14)

| Bereich | Aktuell |
|---------|---------|
| **Schema** | Migration **063:** `training_unit_phases`, `training_unit_parallel_streams`; Sektionen mit `phase_id` **oder** `parallel_stream_id`. |
| **API** | `GET /api/training-units/:id` — **`phases`** (verschachtelt) + flache **`sections`**. `PUT/POST` mit **`phases`** für Breakout-Einheiten (**0.8.138**); höchstens eines von `phases`, `sections`, `exercises` pro Request (Planning-Router). Legacy-PUT mit nur `sections` erzeugt/ergänzt Ganzgruppen-Phase. |
| **Planung (UI)** | Breakout-Panel: Ganzgruppen-/parallele Phasen, Streams; Speichern phasenbasiert (`trainingUnitSectionsForm.js`, `TrainingPlanningPage`). |
| **Durchführung** | `TrainingUnitRunPage.jsx` + `trainingPlanUtils.js` (`sectionsWithPlanLocForDisplay`, `buildPlanRunViewModelFromSections`) — Phasenfolge in „Plan & Ablauf“. |
| **Coaching** | `TrainingCoachPage.jsx` + `flattenPlanTimeline`, Stream-Picks, Rejoin vor Ganzgruppe/nächstem Split (`coachShouldPromptSplitRejoinTransition`), Nachbereitung mit `buildCoachSavePlanPayload`, danach Navigation zu `/planning/run/:id`. |
| **Kombinationsübung** | Unverändert je Item; `planning_method_profile`, Coach-Kombi-Stufe A. |
| **Trainer-Zuweisung** | `lead_trainer_profile_id`, `assistant_trainer_profile_ids` am Einheitskopf; **Stream-**`assigned_trainer_profile_ids` im Schema — UI/Policy noch nicht vollständig (siehe **§8 offen**). |
| **Rahmenprogramm** | Blueprint-`training_units` können dieselbe Phasenstruktur tragen; Kopie aus Slot (`from-framework-slot`, **0.8.138**). |

**Hinweis:** Die frühere Planungsvariante „nur lineare `training_unit_sections` ohne Phasen“ gilt weiter für Alt-Daten; Migration **063** ordnet Bestand einer Default-Ganzgruppenphase zu.

---

## 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

**Ist (063):** Die unten skizzierte **empfohlene** Normalform ist unter den genannten Tabellennamen produktiv; die Abschnitte 3.1/3.2 bleiben zur Einordnung erhalten.

### 3.1 Empfohlen: explizite Phasen + Streams (normalisiert)

Die Tabellen sind **umgesetzt** (Namen final):

| 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 (Abgleich)

| Phase | Inhalt | Stand 2026-05-14 |
|-------|--------|------------------|
| **P1** | Schema Phasen + Streams; Migration **063**; GET/PUT verschachtelt; Planungs-UI; Run + Coach phasenbasiert | **Teilweise erledigt** — Run-UI nutzt Phasen-Timeline in der Anzeige; **Stream-Tabs** optional noch zu vereinheitlichen (§5.2) |
| **P2** | Trainer-Zuordnung pro Stream + effektive Anzeige; Vorlagen erweitert | **Offen** |
| **P3** | Synchroner Hallen-Takt / Rotationsmatrix (falls fachlich freigegeben) | **Offen** |

**Offene Punkte (kurz):** siehe **`docs/HANDOVER.md`** Tabelle „Coaching & Breakout“.

## 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 |
| `TrainingPlanningPage.jsx`, `TrainingUnitRunPage.jsx`, `TrainingFrameworkProgramEditPage.jsx` | Planung, Durchführung, Rahmen |
| `frontend/src/utils/trainingPlanUtils.js`, `TrainingCoachPage.jsx` | Phasen-Timeline, Rejoin, Coach-Speichern |
