shinkan-jinkendo/backend/migrations/009_target_groups_mn_refactor.sql
Lars 2a5f06a8f5
Some checks failed
Deploy Development / deploy (push) Successful in 36s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 5s
Test Suite / playwright-tests (push) Failing after 1m55s
feat: Refactor target groups to M:N relationship and update related endpoints
2026-04-23 09:27:13 +02:00

81 lines
3.7 KiB
SQL

-- 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