-- Migration 009: Zielgruppen M:N Refactoring -- Erstellt: 2026-04-23 -- Beschreibung: Umstellung von hierarchisch (training_style_id FK) zu M:N (Junction-Tabelle) -- Grund: Zielgruppen sollten Global sein und mehreren Stilen zugeordnet werden können -- ============================================================================ -- PHASE 1: Neue M:N Junction-Tabelle erstellen -- ============================================================================ CREATE TABLE IF NOT EXISTS training_style_target_groups ( id SERIAL PRIMARY KEY, training_style_id INT REFERENCES training_styles(id) ON DELETE CASCADE, target_group_id INT REFERENCES target_groups(id) ON DELETE CASCADE, is_primary BOOLEAN DEFAULT false, created_at TIMESTAMP DEFAULT NOW(), UNIQUE(training_style_id, target_group_id) ); CREATE INDEX IF NOT EXISTS idx_training_style_target_groups_style ON training_style_target_groups(training_style_id); CREATE INDEX IF NOT EXISTS idx_training_style_target_groups_target ON training_style_target_groups(target_group_id); CREATE INDEX IF NOT EXISTS idx_training_style_target_groups_primary ON training_style_target_groups(is_primary); -- ============================================================================ -- PHASE 2: Daten-Migration - Alte Zuordnungen zu M:N übernehmen -- ============================================================================ INSERT INTO training_style_target_groups (training_style_id, target_group_id, is_primary) SELECT training_style_id, id, true FROM target_groups WHERE training_style_id IS NOT NULL ON CONFLICT (training_style_id, target_group_id) DO NOTHING; -- ============================================================================ -- PHASE 3: Alte target_groups.training_style_id Column entfernen -- ============================================================================ DO $$ BEGIN -- Prüfe ob training_style_id noch existiert IF EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'target_groups' AND column_name = 'training_style_id' ) THEN -- Entferne Foreign Key Constraint ALTER TABLE target_groups DROP CONSTRAINT IF EXISTS target_groups_training_style_id_fkey CASCADE; -- Entferne die Spalte ALTER TABLE target_groups DROP COLUMN training_style_id CASCADE; END IF; END $$; -- ============================================================================ -- PHASE 4: Alte Index aufräumen (falls vorhanden) -- ============================================================================ DROP INDEX IF EXISTS idx_target_groups_style; -- ============================================================================ -- PHASE 5: Validierung - Zielgruppen sind jetzt unabhängig -- ============================================================================ -- Nach dieser Migration: -- - target_groups hat KEINE training_style_id FK mehr -- - Zielgruppen sind vollständig unabhängig global definiert -- - Zuordnung zu Stilen erfolgt über training_style_target_groups (M:N) -- - Eine Zielgruppe kann mehreren Stilen zugeordnet sein -- - Beispiel: "Breitensportler" → Shotokan, Goju-Ryu, Wado-Ryu -- ============================================================================ -- PHASE 6: Rückwärtskompatibilität -- ============================================================================ -- Falls Übungen direkt auf target_group_id referenzieren (exercise_target_groups), -- funktioniert das weiterhin ohne Probleme (keine Schema-Änderung auf exercises). -- Die exercise_target_groups Tabelle bleibt unverändert. -- Neue Logik: Exercise kann Zielgruppen beliebig zuordnen -- Zielgruppen sind unabhängig von Stilen definiert