All checks were successful
Deploy Development / deploy (push) Successful in 39s
Test Suite / pytest-backend (push) Successful in 36s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / playwright-tests (push) Successful in 56s
- Added new API endpoints for managing training modules, including listing, creating, updating, and deleting modules. - Implemented the ability to apply training modules to training units, allowing users to copy module content into specific sections. - Enhanced the frontend with new pages for managing training modules and integrated modal functionality for applying modules within the training planning page. - Updated version to 0.8.97 and adjusted database schema version accordingly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
61 lines
2.7 KiB
SQL
61 lines
2.7 KiB
SQL
-- Migration 054: Trainingsmodule (Bibliothek / Planung) — Phase 1 MVP
|
|
-- Fachgrundlage: functional/Shinkan Trainingsmodule Kombinationsuebungen Spezifikation V2.md
|
|
|
|
CREATE TABLE IF NOT EXISTS training_modules (
|
|
id SERIAL PRIMARY KEY,
|
|
club_id INT REFERENCES clubs(id) ON DELETE SET NULL,
|
|
created_by INT REFERENCES profiles(id) ON DELETE SET NULL,
|
|
title VARCHAR(200) NOT NULL,
|
|
summary TEXT,
|
|
goal TEXT,
|
|
recommended_duration_min INT,
|
|
target_group_notes TEXT,
|
|
deployment_context_notes TEXT,
|
|
primary_method_id INT REFERENCES training_methods(id) ON DELETE SET NULL,
|
|
visibility VARCHAR(50) NOT NULL DEFAULT 'club'
|
|
CHECK (visibility IN ('private', 'club', 'official')),
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_training_modules_club ON training_modules(club_id);
|
|
CREATE INDEX IF NOT EXISTS idx_training_modules_creator ON training_modules(created_by);
|
|
CREATE INDEX IF NOT EXISTS idx_training_modules_visibility ON training_modules(visibility);
|
|
CREATE INDEX IF NOT EXISTS idx_training_modules_method ON training_modules(primary_method_id)
|
|
WHERE primary_method_id IS NOT NULL;
|
|
|
|
DROP TRIGGER IF EXISTS training_modules_update ON training_modules;
|
|
CREATE TRIGGER training_modules_update
|
|
BEFORE UPDATE ON training_modules
|
|
FOR EACH ROW EXECUTE FUNCTION update_timestamp();
|
|
|
|
CREATE TABLE IF NOT EXISTS training_module_items (
|
|
id SERIAL PRIMARY KEY,
|
|
module_id INT NOT NULL REFERENCES training_modules(id) ON DELETE CASCADE,
|
|
order_index INT NOT NULL,
|
|
item_type VARCHAR(20) NOT NULL CHECK (item_type IN ('exercise', 'note')),
|
|
exercise_id INT REFERENCES exercises(id) ON DELETE SET NULL,
|
|
exercise_variant_id INT REFERENCES exercise_variants(id) ON DELETE SET NULL,
|
|
planned_duration_min INT,
|
|
notes TEXT,
|
|
note_body TEXT,
|
|
UNIQUE (module_id, order_index),
|
|
CHECK (
|
|
(item_type = 'exercise' AND exercise_id IS NOT NULL AND note_body IS NULL)
|
|
OR
|
|
(item_type = 'note' AND exercise_id IS NULL)
|
|
)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_training_module_items_module ON training_module_items(module_id);
|
|
CREATE INDEX IF NOT EXISTS idx_training_module_items_exercise ON training_module_items(exercise_id)
|
|
WHERE exercise_id IS NOT NULL;
|
|
|
|
-- Herkunft bei Übernahme aus Modul-Bibliothek (Kopie, keine Live-Verknüpfung)
|
|
ALTER TABLE training_unit_section_items
|
|
ADD COLUMN IF NOT EXISTS source_training_module_id INT REFERENCES training_modules(id) ON DELETE SET NULL;
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_training_unit_section_items_source_module
|
|
ON training_unit_section_items(source_training_module_id)
|
|
WHERE source_training_module_id IS NOT NULL;
|