# Trainingsrahmenprogramm — Technische Spezifikation (Stub) **Status:** Entwurf · angelegt 2026-04-28 **Bindendes Fachkonzept / Entscheide:** `.claude/docs/functional/TRAINING_CURRICULUM_AND_GOVERNANCE_CONCEPT.md` (CURR‑001 bis CURR‑013) --- ## 1. Abgrenzung zu anderen Dokumenten | Dokument | Rolle · warum **nicht** hier hineinmischen | |----------|--------------------------------------------| | `EXERCISES_DATABASE_FINAL.md`, `EXERCISES_ARCHITECTURE.md`, `EXERCISES_API_SPEC.md` | **Übungskatalog** inkl. Varianten-Progression (Migration 014). Kein Ort für Multi-Session-Rahmen, Slots, Rahmen-Ziele oder `training_units`-Orchestrierung. | | `DATABASE_SCHEMA.md` | **Nachgeordnete** Übersicht: Migrationshistorie und kompakte Tabellenliste. Neue Migrationen hier **einzeilig** ergänzen, Detail-DDL gehört primär hierher (**§3**) oder in Migrations-SQL. | | `functional/DOMAIN_MODEL.md` | Fachliche Kernbegriffe; bei Release des Rahmenfeatures **ein kurzer Unterabschnitt** „Rahmen-Vorlage / Slots“ ergänzen, Verweis auf diese Datei. | | `TRAINING_CURRICULUM_AND_GOVERNANCE_CONCEPT.md` | **Was** und **warum** (Modus A/B, Governance, CURR‑Tabelle). Keine DDL-Pflicht. | **Konsequenz:** Diese Datei ist der **technische Arbeitspool** für Rahmenprogramm-Stufe 1–2 (Graph + Rahmenentität + Slots + Zielliste + API/Migrationen). --- ## 2. Noch auszuarbeiten (Checkliste) - [ ] **Entität(en):** eigene Bibliotheks-Entität für Mehr-Slot-Rahmen (`training_framework_*` o. Ä., siehe **CURR‑009**); Abgrenzung zu `training_plan_templates` (**C5**). - [ ] **Modus A vs. B:** ein Typ mit nullable `group_id` / `plan_mode` vs. zwei Objekttypen — **offen** (Funktionskonzept §6). - [ ] **Zielliste:** ≥1 Zieleinträge pro Rahmen (**CURR‑011**); Felder und Optionalität. - [ ] **Slots:** Reihenfolge, Notizen, **direkte Übungszuordnungen** (M:N oder Join-Tabelle); optionales `training_plan_template_id` pro Slot (**CURR‑010**, MVP offen). - [x] **Progressionsgraph zwischen Übungen:** Tabellen/Kanten, getrennt von Varianten-Progression in `exercise_variants` (**CURR‑002 (1)**, **CURR‑013**) — siehe **§3**. - [ ] **Instanziierung (Modus B):** FK/Metadaten zu `training_units`, Bulk vs. Verknüpfen (**CURR‑012**). - [ ] **Governance:** `visibility`, `club_id`, `created_by` für neue Bibliothekstypen (**CURR‑005**); Nachzug `training_plan_templates` (**CURR‑007**, **CURR‑008**). - [ ] **REST/API:** Endpoints grob, AuthZ analog Trainingsplanung. --- ## 3. Progressionsgraph Übung → Übung (Stufe 1, Migration 032) **Abgrenzung:** Kanten verbinden **`exercises.id` → `exercises.id`**. Die Varianten-Kette innerhalb einer Übung bleibt in `exercise_variants` (Migration 014). ### Schema | Tabelle | Zweck | |---------|--------| | `exercise_progression_graphs` | Kontainer für mehrere getrennte Graphen (Name, Beschreibung, **`visibility`** `private\|club\|official`, **`club_id`**, **`created_by`**). | | `exercise_progression_edges` | Gerichtete Kante: `graph_id`, `from_exercise_id`, `to_exercise_id`, **`edge_type`** (VARCHAR, Default `next_exercise`, erweiterbar ohne ENUM-Zwang). | - **Eindeutigkeit:** `UNIQUE (graph_id, from_exercise_id, to_exercise_id, edge_type)`; `CHECK (from_exercise_id <> to_exercise_id)`. - **Löschregeln (FK):** - Kante → Graph: **`ON DELETE CASCADE`** (Graph löschen entfernt alle Kanten). - Kante → Übung (von/nach): **`ON DELETE CASCADE`** (Übung löschen entfernt alle incident Kanten in allen Graphen — konsistent mit anderen Übungs-Abhängigkeiten wie `exercise_skills`). - **Indizes:** `graph_id`, `from_exercise_id`, `to_exercise_id`. ### API (FastAPI, Prefix `/api`) | Methode | Pfad | Kurzbeschreibung | |---------|------|------------------| | GET | `/exercise-progression-graphs` | Liste (Admin/Superadmin: alle; sonst nur eigene `created_by`). | | GET | `/exercise-progression-graphs/{id}` | Detail; Query `include_edges=true` für eingebettete Kanten. | | POST | `/exercise-progression-graphs` | Anlegen (`_has_planning_role`, wie Trainingsvorlagen). | | PUT | `/exercise-progression-graphs/{id}` | Metadaten (`name`, `description`, `visibility`, `club_id`). | | DELETE | `/exercise-progression-graphs/{id}` | Graph + Kanten (CASCADE). | | GET | `/exercise-progression-graphs/{id}/edges` | Kantenliste; optional Filter `from_exercise_id`, `to_exercise_id`. | | POST | `/exercise-progression-graphs/{id}/edges` | Kante anlegen; Duplikat → **409**. | | DELETE | `/exercise-progression-graphs/{id}/edges/{edge_id}` | Kante löschen. | **AuthZ:** Analog `training_plan_templates`: Zugriff auf einen Graphen nur **Admin/Superadmin** oder **Ersteller** (`created_by`). ### Offen / später - Weitere **`edge_type`**-Semantik und Filter in der UI („Vorschläge“ beim Planen). - **CURR‑013:** Graph bleibt unterstützend; keine Pflicht, jeden Trainingsplan über den Graph zu modellieren. - Anbindung **`training_units`** / Rahmen-Slots (**Stufe 2**, CURR‑009–012). ### Manuelle Prüfung 1. Nach Migration: `GET /api/exercise-progression-graphs` mit gültigem `X-Auth-Token`. 2. `POST /exercise-progression-graphs` mit `{"name":"Testgraph"}` → `201`. 3. `POST …/{id}/edges` mit gültigen `from_exercise_id` / `to_exercise_id`; zweites identisches Quadrupel → `409`. 4. Übung löschen, die an einer Kante beteiligt ist: Kanten verschwinden (CASCADE). --- ## 4. Changelog | Datum | Änderung | |-------|----------| | 2026-04-30 | §3: Migration 032 + REST-Endpunkte Progressionsgraph (CURR‑002 (1)); Checkliste Graph erledigt. | | 2026-04-28 | Erstanlage: Abgrenzung + Checkliste (Artefakt der Doku-Entscheidung „eigene technische Spec“). |