- 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.
93 lines
4.7 KiB
SQL
93 lines
4.7 KiB
SQL
-- Migration 035: Trainingsrahmenprogramm (Rahmen‑Vorlage, CURR‑002 Stufe 2 / CURR‑009–013)
|
||
-- + CURR‑007/008: training_plan_templates.visibility (Backfill club, dann NOT NULL + Default)
|
||
|
||
-- ── Trainings‑Mikrovorlagen: gemeinsamer Governance‑Kern (visibility) ─────
|
||
ALTER TABLE training_plan_templates
|
||
ADD COLUMN IF NOT EXISTS visibility VARCHAR(50)
|
||
CHECK (visibility IN ('private', 'club', 'official'));
|
||
|
||
UPDATE training_plan_templates
|
||
SET visibility = 'club'
|
||
WHERE visibility IS NULL;
|
||
|
||
ALTER TABLE training_plan_templates
|
||
ALTER COLUMN visibility SET DEFAULT 'club';
|
||
|
||
ALTER TABLE training_plan_templates
|
||
ALTER COLUMN visibility SET NOT NULL;
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_training_plan_templates_visibility ON training_plan_templates(visibility);
|
||
|
||
-- ── Rahmen‑Header ────────────────────────────────────────────────────────────
|
||
CREATE TABLE IF NOT EXISTS training_framework_programs (
|
||
id SERIAL PRIMARY KEY,
|
||
title VARCHAR(200) NOT NULL,
|
||
description TEXT,
|
||
plan_mode VARCHAR(20) NOT NULL
|
||
CHECK (plan_mode IN ('concrete', 'library')),
|
||
-- Modus B (library): immer NULL · Modus A (concrete): optional gebunden an eine Trainingsgruppe
|
||
group_id INT REFERENCES training_groups(id) ON DELETE SET NULL,
|
||
planned_period_start DATE,
|
||
planned_period_end DATE,
|
||
visibility VARCHAR(50) NOT NULL DEFAULT 'private'
|
||
CHECK (visibility IN ('private', 'club', 'official')),
|
||
club_id INT REFERENCES clubs(id) ON DELETE SET NULL,
|
||
created_by INT REFERENCES profiles(id) ON DELETE SET NULL,
|
||
created_at TIMESTAMP DEFAULT NOW(),
|
||
updated_at TIMESTAMP DEFAULT NOW(),
|
||
CHECK (
|
||
(plan_mode = 'library' AND group_id IS NULL)
|
||
OR plan_mode = 'concrete'
|
||
)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_programs_creator ON training_framework_programs(created_by);
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_programs_club ON training_framework_programs(club_id);
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_programs_visibility ON training_framework_programs(visibility);
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_programs_mode ON training_framework_programs(plan_mode);
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_programs_group ON training_framework_programs(group_id);
|
||
|
||
DROP TRIGGER IF EXISTS training_framework_programs_update ON training_framework_programs;
|
||
CREATE TRIGGER training_framework_programs_update
|
||
BEFORE UPDATE ON training_framework_programs
|
||
FOR EACH ROW EXECUTE FUNCTION update_timestamp();
|
||
|
||
-- ── Zielliste (CURR‑011: ≥ 1 durch API beim Speichern) ─────────────────────
|
||
CREATE TABLE IF NOT EXISTS training_framework_goals (
|
||
id SERIAL PRIMARY KEY,
|
||
framework_program_id INT NOT NULL REFERENCES training_framework_programs(id) ON DELETE CASCADE,
|
||
sort_order INT NOT NULL,
|
||
title VARCHAR(500) NOT NULL,
|
||
notes TEXT,
|
||
UNIQUE (framework_program_id, sort_order)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_goals_framework ON training_framework_goals(framework_program_id);
|
||
|
||
-- ── Slots (Sessions im Rahmen) ──────────────────────────────────────────────
|
||
CREATE TABLE IF NOT EXISTS training_framework_slots (
|
||
id SERIAL PRIMARY KEY,
|
||
framework_program_id INT NOT NULL REFERENCES training_framework_programs(id) ON DELETE CASCADE,
|
||
sort_order INT NOT NULL,
|
||
title VARCHAR(200),
|
||
notes TEXT,
|
||
training_unit_id INT REFERENCES training_units(id) ON DELETE SET NULL,
|
||
UNIQUE (framework_program_id, sort_order)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_slots_framework ON training_framework_slots(framework_program_id);
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_slots_unit ON training_framework_slots(training_unit_id);
|
||
|
||
-- ── Übungen pro Slot (tragende „Stückliste“, CURR‑010) ────────────────────────
|
||
CREATE TABLE IF NOT EXISTS training_framework_slot_exercises (
|
||
id SERIAL PRIMARY KEY,
|
||
slot_id INT NOT NULL REFERENCES training_framework_slots(id) ON DELETE CASCADE,
|
||
exercise_id INT NOT NULL REFERENCES exercises(id) ON DELETE CASCADE,
|
||
exercise_variant_id INT REFERENCES exercise_variants(id) ON DELETE SET NULL,
|
||
order_index INT NOT NULL,
|
||
UNIQUE (slot_id, order_index)
|
||
);
|
||
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_slot_exercises_slot ON training_framework_slot_exercises(slot_id);
|
||
CREATE INDEX IF NOT EXISTS idx_training_framework_slot_exercises_exercise ON training_framework_slot_exercises(exercise_id);
|