shinkan-jinkendo/.claude/docs/technical/TRAINING_FRAMEWORK_SPEC.md
Lars b054c642a3
Some checks failed
Deploy Development / deploy (push) Successful in 33s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 14s
Test Suite / playwright-tests (push) Failing after 40s
chore: update training framework specifications and versioning
- Incremented version to 0.8.8 and updated database schema version to 20260505035.
- Added new entity `training_framework_programs` to manage training frameworks, including goals and slots.
- Enhanced `training_plan_templates` with a visibility attribute and backfilled existing data.
- Updated API to support CRUD operations for training frameworks, ensuring proper authorization similar to existing planning libraries.
- Revised documentation in DOMAIN_MODEL.md, TRAINING_CURRICULUM_AND_GOVERNANCE_CONCEPT.md, and TRAINING_FRAMEWORK_SPEC.md to reflect these changes.
2026-05-05 08:41:43 +02:00

13 KiB
Raw Blame History

Trainingsrahmenprogramm — Technische Spezifikation

Status: Zwischenstand dokumentiert · Stand: 2026-05-05
Bindendes Fachkonzept / Entscheide: .claude/docs/functional/TRAINING_CURRICULUM_AND_GOVERNANCE_CONCEPT.md (CURR‑001 bis CURR‑013)

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).


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 innerhalb einer Übung (Migration 014). Kanten zwischen Übungen siehe §3.
DATABASE_SCHEMA.md Nachgeordnete Übersicht: Migrationshistorie und Tabellenliste; Detail-DDL primär hier §2–§3 + SQL unter backend/migrations/.
functional/DOMAIN_MODEL.md Fachliche Begriffe; Kurzverweis auf Progressionsgraph ergänzt.
TRAINING_CURRICULUM_AND_GOVERNANCE_CONCEPT.md Was und warum (Modus A/B, Governance, CURR‑Tabelle).

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).


2. Rahmenprogramm (CURR‑002 Stufe 2) — Checkliste & technische Ausarbeitung

2.0 Technische Entscheidung: eine Tabelle + plan_mode (Modus A | B)

Entscheid: Eine Hauptentität training_framework_programs mit plan_mode ∈ {concrete, library} statt zweier getrennter Tabellentypen.

Begründung: Gleiche Lebenszyklus‑ und CRUD‑Form (Header, Ziele, Slots, Übungen); die fachliche Unterscheidung A/B lässt sich mit CHECK- und API‑Regeln ausdrücken (library ⇒ group_id IS NULL, keine training_unit_id an Slots), ohne doppelte Router/Joins. Zwei physische Typen würden ohne Mehrwert Polymorphismus in der API erzwingen oder eine künstliche Supertyp‑Tabelle nach sich ziehen.

Abgrenzung Konzept §6: Dokumentiert hier; Funktionskonzept kann auf diesen Abschnitt verweisen.

2.1 Checkliste (Abhak-Stand)

  • Entität(en): eigene Bibliotheks-Entität training_framework_programs (CURR‑009); training_plan_templates unverändert eine‑Einheit‑Mikrovorlage (C5).
  • Modus A vs. B: ein Datensatz + plan_mode + Nullables (§2.0); library erzwingt group_id NULL; training_plan_template_id pro Slot — deferred (Technical: MVP ohne Spalte, bis Nutzen geklärt, CURR‑010).
  • Zielliste: training_framework_goals, API erzwingt ≥ 1 Ziel beim Anlegen/Ersetzen (CURR‑011).
  • Slots: training_framework_slots mit sort_order, optional Titel/Notizen; Übungen über training_framework_slot_exercises (Sortierung order_index, optional exercise_variant_id).
  • Progressionsgraph: Stufe 1 besteht (§3–§4); kein Pflichtbezug pro Slot (CURR‑013).
  • Konkretkontakt Modus A: optional training_unit_id pro Slot; bei gesetzter Rahmen-group_id muss die Einheit zur gleichen Gruppe gehören. Live‑Writes zurück in die Bibliotheksvorlage: nicht vorgesehen (CURR‑006).
  • Instanziierung (Modus B): Persistenz der Vorlage (MVP); Bulk-Anlage von training_units aus dem Rahmen — Ausbauschritt/zweiter PR (CURR‑012 C4a/b).
  • Governance neue Objekte: visibility, club_id, created_by wie Progressionsgraph (CURR‑005). training_plan_templates.visibility nachgezogen in derselben Migration 035 mit Backfill club (CURR‑007, CURR‑008; frühe Installationen).
  • REST Rahmenprogramm: /api/training-framework-programs (§2.3); Progressions‑API weiter §3.3.

2.2 DDL‑Skizze (Migration 035, Kurzüberblick)

-- Header
training_framework_programs (
  id, title NOT NULL, description,
  plan_mode NOT NULL CHECK (IN 'concrete','library'),
  group_id FK training_groups NULL,
  planned_period_start, planned_period_end NULL,  -- reine Meta-/UI‑Hilfe
  visibility NOT NULL, club_id, created_by,
  CHECK ((plan_mode = 'library' AND group_id IS NULL) OR plan_mode = 'concrete'),
  timestamps + update_trigger
)

-- Ziele (≥1 über API beim Speichern)
training_framework_goals (
  id, framework_program_id FK CASCADE, sort_order UNIQUE per framework,
  title, notes
)

-- Slots
training_framework_slots (
  id, framework_program_id FK CASCADE, sort_order UNIQUE per framework,
  title, notes, training_unit_id FK training_units SET NULL
)

-- Stückliste pro Slot (Übung → FK CASCADE beim Löschen der Übung)
training_framework_slot_exercises (
  id, slot_id FK CASCADE,
  exercise_id FK exercises CASCADE,
  exercise_variant_id FK exercise_variants NULL,
  order_index UNIQUE per slot
)

Löschkaskaden: löschen eines Rahmens ⇒ Ziele + Slots ⇒ Slot‑Übungen (alles ON DELETE CASCADE vom Rahmen über Slots). löschen eines training_unit ⇒ FK am Slot SET NULL. löschen einer Übung ⇒ Zeilen in training_framework_slot_exercises entfallen (CASCADE).

Deferred (nicht im MVP): training_plan_templates.id FK je Slot (CURR‑010 Optional).

2.3 REST‑Überblick (router training_framework_programs)

Methode Pfad Zweck
GET /training-framework-programs Liste; Admin/Superadmin alle, sonst eigene (created_by); Aggregation goals_count, slots_count
GET /training-framework-programs/{id} Detail inkl. goals[], slots[] mit jeweils exercises[] (inkl. Titel‑Joins)
POST /training-framework-programs Neu; Pflicht: title, plan_mode, goals (≥ 1 Eintrag mit title); optional slots
PUT /training-framework-programs/{id} Header‑Felder; optional volles Ersetzen von goals und/oder slots wie bei Vorlagen‑Sektionen
DELETE /training-framework-programs/{id} Rahmen löschen (CASCADE Kinder)

AuthZ: Schreibzugriff nur mit _has_planning_role (wie training_plan_templates); Lesen/Ändern/Löschen: Admin/Superadmin oder Ersteller (created_by).

Payload‑Hinweise (JSON):

  • goals: [{ sort_order?, title, notes? }, …] — sort_order default Reihenfolge im Array
  • slots: [{ sort_order?, title?, notes?, training_unit_id?, exercises: [{ exercise_id, exercise_variant_id?, order_index? }] }, …]
  • Bei library: training_unit_id an Slots → 400; nach Wechsel auf library werden bestehende Slot-Verknüpfungen zu training_units geleert.

Minimal‑UI: im Lieferumfang dieser Iteration nicht enthalten (OpenAPI /docs / Postman); siehe Funktionskonzept §6.


3. Progressionsgraph Übung → Übung (implementierter Stand)

3.1 Abgrenzung

  • 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).

Listenqueries liefern Join‑Felder from_exercise_title, to_exercise_title, from_variant_name, to_variant_name.

3.3 REST (/api, Router exercise_progression_graphs.py)

Methode Pfad Zweck
GET /exercise-progression-graphs Liste (+ edges_count); Admin sieht alle, sonst nur eigene.
GET /exercise-progression-graphs/{id} Detail; ?include_edges=true
POST /exercise-progression-graphs Graph anlegen
PUT /exercise-progression-graphs/{id} Metadaten
DELETE /exercise-progression-graphs/{id} Graph + Kanten
GET /exercise-progression-graphs/{id}/edges Kanten; Query optional from_exercise_id, to_exercise_id
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

3.4 Frontend (Stand Code)

  • ExercisesListPage: Tabs Liste · Progressionsgraphen → ExerciseProgressionGraphPanel.
  • ExerciseFormPage (nur Edit): eingeklappter Block Progressionsgraph mit Kontext „diese Übung“ + Filter „nur betroffene Kanten“.
  • 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).
  • API‑Client: frontend/src/utils/api.js (createExerciseProgressionSequence, deleteExerciseProgressionEdgesBatch, …).

4. Zwischenstand für Produkt / Trainingsplanung (bewusste Grenzen)

Freigabe: Der beschriebene Stand gilt als ausreichend, um mit dem Trainingsplanungsmodul und später Rahmen/Slots (CURR‑002 (2)) weiterzuarbeiten — ohne dass Pflicht zur Pflege komplexer Graph‑Strukturen entsteht (CURR‑013).

Was gut nutzbar ist

  • Lineare Reihen mehrerer Übungen (bzw. Varianten‑Knoten) über Sequenz‑API bzw. Sequenz‑UI.
  • Nachfolger‑Lesart als zusammenhängende Kette in der Übersicht.
  • Schwester‑Kanten als eigene Liste (Alternative gleicher „Stufe“ zwischen zwei Knoten).
  • Einzelkanten für Sonderfälle und Verzweigungen.

Was noch nicht „ein Knopf“ ist (bekannt)

  • 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.

Nächste sinnvolle Ausbaustufen (Backlog Graph‑UX, nicht Blocker Planung)

  • Semantik alternative_group_id oder Hyperkanten (ein UX‑Schritt legt mehrere Kanten mit gemeinsamer Gruppe an).
  • Komfort beim Pflegen symmetrischer Schwestern (ein Klick für zwei Richtungen / Dedupe).
  • Karten-/Baum‑Layout statt nur Zeilen.

Details weiterhin Diskussionsgrundlage in TRAINING_CURRICULUM_AND_GOVERNANCE_CONCEPT.md §6 (Kantentypen).


5. Changelog (Dokument)

Datum Änderung
2026-05-05 CURR‑002 (2): §2 Rahmenprogramm — Entscheid eine Tabelle + plan_mode, DDL‑Skizze, REST‑Überblick; Migration 035; training_plan_templates.visibility.
2026-04-30 Zwischen-Doku: §3 auf Migrationen 032–034 + API sequence/delete-batch + Frontend erweitert; §4 Produktfreigabe vs. Lücken (parallele Alternativen); Changelog §5.
2026-04-30 §3: erste Fassung Migration 032 + REST‑Basis (CURR‑002 (1)).
2026-04-28 Erstanlage Stub mit Checkliste.