116 lines
4.5 KiB
PL/PgSQL
116 lines
4.5 KiB
PL/PgSQL
-- Migration 014: Variant Progression System + Search Vector + Legacy Cleanup
|
|
-- Autor: Claude Code
|
|
-- Datum: 2026-04-24
|
|
-- Zweck: Varianten-Progression, Volltext-Suche, Legacy-Spalten entfernen
|
|
|
|
DO $$
|
|
BEGIN
|
|
|
|
-- ============================================================================
|
|
-- HELPER FUNCTION: update_timestamp (für Triggers)
|
|
-- ============================================================================
|
|
|
|
CREATE OR REPLACE FUNCTION update_timestamp()
|
|
RETURNS trigger AS $func$
|
|
BEGIN
|
|
NEW.updated_at = NOW();
|
|
RETURN NEW;
|
|
END;
|
|
$func$ LANGUAGE plpgsql;
|
|
|
|
-- ============================================================================
|
|
-- VARIANT PROGRESSION
|
|
-- ============================================================================
|
|
|
|
-- Erweitere exercise_variants Tabelle
|
|
ALTER TABLE exercise_variants
|
|
ADD COLUMN IF NOT EXISTS progression_level INT DEFAULT 1 CHECK (progression_level BETWEEN 1 AND 10),
|
|
ADD COLUMN IF NOT EXISTS sequence_order INT,
|
|
ADD COLUMN IF NOT EXISTS prerequisite_variant_id INT REFERENCES exercise_variants(id) ON DELETE SET NULL;
|
|
|
|
-- Index für Prerequisites
|
|
CREATE INDEX IF NOT EXISTS idx_exercise_variants_prerequisite
|
|
ON exercise_variants(prerequisite_variant_id);
|
|
|
|
-- ============================================================================
|
|
-- SEARCH VECTOR (Volltext-Suche)
|
|
-- ============================================================================
|
|
|
|
-- Füge search_vector zu exercises hinzu
|
|
ALTER TABLE exercises
|
|
ADD COLUMN IF NOT EXISTS search_vector tsvector;
|
|
|
|
-- Index für Volltext-Suche
|
|
CREATE INDEX IF NOT EXISTS idx_exercises_search
|
|
ON exercises USING gin(search_vector);
|
|
|
|
-- Funktion für automatisches Update
|
|
CREATE OR REPLACE FUNCTION update_exercises_search_vector()
|
|
RETURNS trigger AS $func$
|
|
BEGIN
|
|
NEW.search_vector :=
|
|
setweight(to_tsvector('german', COALESCE(NEW.title, '')), 'A') ||
|
|
setweight(to_tsvector('german', COALESCE(NEW.summary, '')), 'B') ||
|
|
setweight(to_tsvector('german', COALESCE(NEW.execution, '')), 'C') ||
|
|
setweight(to_tsvector('german', COALESCE(NEW.trainer_notes, '')), 'D');
|
|
RETURN NEW;
|
|
END;
|
|
$func$ LANGUAGE plpgsql;
|
|
|
|
-- Trigger
|
|
DROP TRIGGER IF EXISTS exercises_search_update ON exercises;
|
|
CREATE TRIGGER exercises_search_update
|
|
BEFORE INSERT OR UPDATE ON exercises
|
|
FOR EACH ROW EXECUTE FUNCTION update_exercises_search_vector();
|
|
|
|
-- Initiales Befüllen (für existierende Zeilen)
|
|
UPDATE exercises SET search_vector = (
|
|
setweight(to_tsvector('german', COALESCE(title, '')), 'A') ||
|
|
setweight(to_tsvector('german', COALESCE(summary, '')), 'B') ||
|
|
setweight(to_tsvector('german', COALESCE(execution, '')), 'C') ||
|
|
setweight(to_tsvector('german', COALESCE(trainer_notes, '')), 'D')
|
|
) WHERE search_vector IS NULL;
|
|
|
|
-- ============================================================================
|
|
-- LEGACY COLUMN CLEANUP
|
|
-- Deprecated Felder aus exercises (ersetzt durch M:N Tabellen in Migration 008+)
|
|
-- ============================================================================
|
|
|
|
-- age_groups JSONB → ersetzt durch exercise_age_groups M:N (seit Migration 008)
|
|
ALTER TABLE exercises DROP COLUMN IF EXISTS age_groups;
|
|
|
|
-- focus_area VARCHAR → ersetzt durch exercise_focus_areas M:N (seit Migration 008)
|
|
ALTER TABLE exercises DROP COLUMN IF EXISTS focus_area;
|
|
|
|
-- secondary_areas JSONB → ersetzt durch exercise_focus_areas M:N
|
|
ALTER TABLE exercises DROP COLUMN IF EXISTS secondary_areas;
|
|
|
|
-- training_character VARCHAR → ersetzt durch exercise_training_characters M:N (seit Migration 012)
|
|
ALTER TABLE exercises DROP COLUMN IF EXISTS training_character;
|
|
|
|
-- ============================================================================
|
|
-- ADDITIONAL INDEXES (Performance)
|
|
-- ============================================================================
|
|
|
|
-- Häufige Filter
|
|
CREATE INDEX IF NOT EXISTS idx_exercises_visibility ON exercises(visibility);
|
|
CREATE INDEX IF NOT EXISTS idx_exercises_status ON exercises(status);
|
|
CREATE INDEX IF NOT EXISTS idx_exercises_created_at ON exercises(created_at DESC);
|
|
|
|
-- M:N Relations (falls noch nicht vorhanden)
|
|
CREATE INDEX IF NOT EXISTS idx_exercise_focus_areas_focus
|
|
ON exercise_focus_areas(focus_area_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_exercise_styles_style
|
|
ON exercise_style_directions(style_direction_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_exercise_target_groups_group
|
|
ON exercise_target_groups(target_group_id);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_exercise_skills_skill
|
|
ON exercise_skills(skill_id);
|
|
|
|
RAISE NOTICE 'Migration 014 completed successfully';
|
|
|
|
END $$;
|