shinkan-jinkendo/backend/migrations/054_training_modules.sql
Lars c1243651bb
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
feat(training-modules): implement training module functionality and UI integration
- 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>
2026-05-12 21:35:07 +02:00

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;