**Relevant für nächsten Schritt:** CURR‑002 **(2)** Trainingsplanung / Rahmen über mehrere Einheiten — der hier dokumentierte **Progressionsgraph Stufe 1** ist bewusst **unterstützend**, keine Pflicht für Slot-Zuordnungen (**CURR‑013**).
**Konsequenz:** Diese Datei bleibt der **technische Arbeitspool** für Rahmenprogramm Stufe 1–2. Abschnitt **§4** beschreibt explizit den **aktuellen Produktfreigabe-Umfang** und **bekannte Lücken** (damit Trainingsplanung weiter gebaut werden kann ohne falscher Erwartung an „Alternative‑Pakete“ in der UI).
**Fachlich:** Das Rahmenprogramm ist eine **wiederverwendbare Bibliotheksvorlage** ohne Bindung an eine Trainingsgruppe oder einen Kalendertermin (**Migration 036** entfernte `plan_mode`, `group_id` am Kopf sowie die Nutzung von `training_framework_slots.training_unit_id` für „konkrete“ Kopplung).
**Slot‑Inhalt (Migration 037):** Pro `training_framework_slot` existiert genau eine **Blueprint‑Zeile** in `training_units` mit **`framework_slot_id`** (partieller **UNIQUE**-Index); der Ablauf entspricht **derselben** Struktur wie geplante Einheiten über **`training_unit_sections`** und **`training_unit_section_items`** (Übungen, Notizen, Varianten wie in der Planung). Die frühere Tabelle **`training_framework_slot_exercises`** wird nach Datenübernahme **`DROP`**pt.
**Geplante Einheit aus Rahmen:** **`POST /api/training-units/from-framework-slot`** kopiert diese Blueprint‑Unit (**tiefe Kopie**) mit **`group_id` + `planned_date`**; **`origin_framework_slot_id`** hält die Herkunft (Lineage‑Light). **`GET /api/training-units`** blendet Einheiten mit **`framework_slot_id IS NOT NULL`** aus (Kalender/API‑Liste ohne Rahmen‑Blueprints).
**CHECK‑Constraint auf `training_units`:** Zeile ist entweder **Blueprint** (`framework_slot_id` gesetzt, `group_id`/`planned_date` NULL, kein `origin_framework_slot_id`) oder **Kalender‑Einheit** (`framework_slot_id` NULL, `group_id` und `planned_date` gesetzt; `origin_framework_slot_id` optional).
**Konsequenz KonzeptCURR‑012 („concrete/library“):** Persistiert wird **ein** Kopf ohne Modus-Spalte: Immer Bibliotheks‑Rolle; Konkretisierung nur über Planung/API‑Kopie. Historische DDL mit `plan_mode` siehe **`035`**/`036` in dieser Datei (**§5 Changelog**) und `backend/migrations/`.
- [x]**Bibliothek only (036):** Kopf ohne `plan_mode`/`group_id`; Kontextfilter **`focus_area_id`**, **`style_direction_id`**; M:N **`training_framework_program_training_types`**, **`training_framework_program_target_groups`**.
- [x]**Zielliste:**`training_framework_goals`, API **≥1** Ziel (**CURR‑011**).
- [x]**Slots:**`training_framework_slots` mit **`sort_order`**, optional **Titel/Notizen**; **Ablauf** über zugehörige **Blueprint‑`training_units`** + Sektionen/Items (**037**), nicht mehr `training_framework_slot_exercises`.
- [x]**Progressionsgraph:** Stufe1 (**§3–§4**); **kein Pflichtbezug** pro Slot (**CURR‑013**).
- [x]**Kein Live‑Write** von Kalendereinheiten zurück in die Vorlage (**CURR‑006**); Konkretisierung = **Kopie** (siehe **§2.4**).
- [x]**Instanziierung (MVP):**`POST /api/training-units/from-framework-slot` — weiterer Ausbau: Bulk, Kalender‑UI‑Flow, **`training_plan_template_id` pro Slot** weiterhin optional/deferred (**CURR‑010**).
| GET | `/training-framework-programs` | Liste; Admin/Superadmin alle, sonst eigene (`created_by`); u. a. `goals_count`, `slots_count`, Kontext‑Counts |
| GET | `/training-framework-programs/{id}` | Detail inkl. `goals[]`, `slots[]` mit je **`blueprint_training_unit_id`**, **`sections[]`**, **`exercises[]`** (letzteres aus Sektionen geflacht, kompatibel zum Editor) |
- **Zwischen Übungen:** gerichtete Kanten auf Ebene **`exercises`** mit optionalen Endpunkten auf konkreten **`exercise_variants`** (Knoten = „Übung“ oder „Übung · Variante“). Migrationen **032–034**.
- **Innerhalb einer Übung:** Reihenfolge / Progressionsmetadaten der Varianten unverändert über **`exercise_variants`** (Migration **014**) — nicht duplizieren.
AuthZ analog **`training_plan_templates`**: Graph nur für **Admin/Superadmin** oder **Ersteller** (`created_by`); Anlegen neuer Graphen mit **`_has_planning_role`**.
### 3.2 Migrationen & Schema (Kurz)
| Mig. | Inhalt |
|------|--------|
| **032** | `exercise_progression_graphs` (Name, Beschreibung, **`visibility`**, **`club_id`**, **`created_by`**); `exercise_progression_edges` (`graph_id`, von/nach Übung, `edge_type` VARCHAR Default `next_exercise`). FK CASCADE zu Graph und Übungen. |
| **033** | `exercise_progression_edges.notes` (freier Text / „Entwicklungsziel“ pro Kante). |
| **034** | `from_exercise_variant_id`, `to_exercise_variant_id` (nullable, FK `exercise_variants`, CASCADE). CHECK: gleiche Übung nur mit **zwei verschiedenen Varianten**. UNIQUE-Index über Graph + Endpunkte inkl. `COALESCE(variant_id,0)` + `edge_type`. |
Kantentypen in Produktnutzung: **`next_exercise`** (Nachfolger), **`sibling`** (Schwester / gleiche „Entwicklungslage“, semantisch oft Paar — weiterhin eine gerichtete Kante in DB).
| POST | `/exercise-progression-graphs/{id}/edges` | Einzelkante; Duplikat/Constraint → **409** |
| POST | `/exercise-progression-graphs/{id}/edges/sequence` | **Bulk:**`{ steps: [{ exercise_id, variant_id? }, …], segment_notes?: [...] }` — nur **`next_exercise`**, Transaktion alle oder keine Zeile |
| PUT | `/exercise-progression-graphs/{id}/edges/{edge_id}` | z.B. **`notes`** |
| DELETE | `/exercise-progression-graphs/{id}/edges/{edge_id}` | eine Kante |
| POST | `/exercise-progression-graphs/{id}/edges/delete-batch` | `{ edge_ids: [...] }` — z.B. gesamte sichtbare „Reihe“ löschen |
- Panel‑Funktionen: **Sequenz‑Editor** (mehrere Schritte → ein Bulk‑Speichern), zusammengefasste **Reihen‑Lesart** für `next_exercise`, eigene Liste für **Schwestern**, Einzelkantenbereich, Tab **Alle Kanten (Tabelle)**.
**Freigabe:** Der beschriebene Stand unterstützt **Rahmen‑Bibliothek mit vollem Ablauf pro Slot** (wie Planung) und **Kopie in die Gruppenplanung**; der **Progressionsgraph** bleibt **unterstützend** (**CURR‑013**). Offen: Kalender‑UI‑Flow, Bulk‑Instanziierung, erweiterte Lineage/Feedback (**Konzept Schritt E**).
- **Parallele gleichwertige Alternativen** („Paket B bestehend aus mehreren Übungen als echte Alternative zu Paket A“) sind **nicht** als erste‑Klass‑UX modelliert: mehrere Nachfolger aus einem Knoten sind technisch möglich (mehrere `next_exercise`‑Kanten), aber **keine** dedizierte Gruppe „Alternativ‑Set“. Pflege kann mehrzeilig und koplastisch wirken.
- **Visualisierung echter Bäume** (Join‑Points, mehrere ausgehende Pfeile in einem Bild) ist nur eingeschränkt über Reihen‑Zusammenfassung + Tabelle abbildbar.