-- Migration 034: Progressionskanten optional mit Übungsvarianten (Knoten = Übung oder konkrete Variante). -- UNIQUE und CHECK angepasst; Kanten innerhalb derselben Übung nur zwischen verschiedenen Varianten. ALTER TABLE exercise_progression_edges ADD COLUMN IF NOT EXISTS from_exercise_variant_id INT REFERENCES exercise_variants(id) ON DELETE CASCADE, ADD COLUMN IF NOT EXISTS to_exercise_variant_id INT REFERENCES exercise_variants(id) ON DELETE CASCADE; CREATE INDEX IF NOT EXISTS idx_progression_edges_from_variant ON exercise_progression_edges(from_exercise_variant_id) WHERE from_exercise_variant_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_progression_edges_to_variant ON exercise_progression_edges(to_exercise_variant_id) WHERE to_exercise_variant_id IS NOT NULL; DO $$ BEGIN ALTER TABLE exercise_progression_edges DROP CONSTRAINT exercise_progression_edges_graph_id_from_exercise_id_to_exercise_id_edge_type_key; EXCEPTION WHEN undefined_object THEN NULL; END $$; DO $$ BEGIN ALTER TABLE exercise_progression_edges DROP CONSTRAINT exercise_progression_edges_check; EXCEPTION WHEN undefined_object THEN NULL; END $$; ALTER TABLE exercise_progression_edges ADD CONSTRAINT exercise_progression_edges_endpoints_distinct CHECK ( (from_exercise_id <> to_exercise_id) OR ( from_exercise_variant_id IS NOT NULL AND to_exercise_variant_id IS NOT NULL AND from_exercise_variant_id <> to_exercise_variant_id ) ); CREATE UNIQUE INDEX IF NOT EXISTS exercise_progression_edges_unique_endpoints ON exercise_progression_edges ( graph_id, from_exercise_id, COALESCE(from_exercise_variant_id, 0), to_exercise_id, COALESCE(to_exercise_variant_id, 0), edge_type );