-- Migration 092: Katalog-Prompt-Slots (H2) — Slot-Typ-Vokabular + Werte pro Stammdaten-Zeile CREATE TABLE IF NOT EXISTS catalog_prompt_slot_types ( slot_key VARCHAR(64) PRIMARY KEY, display_name VARCHAR(200) NOT NULL, description TEXT, applicable_kinds TEXT[] NOT NULL DEFAULT '{}', sort_order INT DEFAULT 99, for_llm BOOLEAN NOT NULL DEFAULT true, for_code BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS catalog_prompt_slots ( id SERIAL PRIMARY KEY, catalog_kind VARCHAR(32) NOT NULL, catalog_id INT NOT NULL, slot_key VARCHAR(64) NOT NULL REFERENCES catalog_prompt_slot_types(slot_key) ON DELETE CASCADE, content TEXT NOT NULL DEFAULT '', updated_at TIMESTAMP DEFAULT NOW(), UNIQUE (catalog_kind, catalog_id, slot_key) ); CREATE INDEX IF NOT EXISTS idx_catalog_prompt_slots_kind_id ON catalog_prompt_slots (catalog_kind, catalog_id); INSERT INTO catalog_prompt_slot_types (slot_key, display_name, description, applicable_kinds, sort_order, for_llm, for_code) VALUES ( 'description', 'Allgemeine Beschreibung', 'Fachliche Einordnung des Katalog-Eintrags für Planungs-KI.', ARRAY['focus_area', 'training_type', 'target_group', 'style_direction'], 10, true, false ), ( 'hints_on_progression', 'Hinweise Progressionsgraph', 'Didaktik für Roadmap, Major Steps und Stufenspezifikation.', ARRAY['focus_area', 'training_type', 'target_group', 'style_direction'], 20, true, false ), ( 'hints_on_exercise', 'Hinweise Übungsanlage', 'Kontext für Gap-Fill, Übungs-KI und Schnellanlage.', ARRAY['focus_area', 'training_type', 'target_group', 'style_direction'], 30, true, false ), ( 'hints_on_path_qa', 'Hinweise Pfad-QS', 'Bewertungsmaßstäbe für Pfad-Qualitätssicherung.', ARRAY['focus_area', 'training_type', 'target_group', 'style_direction'], 40, true, false ), ( 'anti_patterns', 'Anti-Patterns', 'Explizite Fehlbewertungen vermeiden.', ARRAY['focus_area', 'training_type', 'target_group', 'style_direction'], 50, true, false ), ( 'rematch_guard', 'Rematch-Guard', 'Wann kein Auto-Rematch sinnvoll ist (primär Code-Logik).', ARRAY['focus_area', 'training_type', 'target_group', 'style_direction'], 60, false, true ) ON CONFLICT (slot_key) DO NOTHING; -- Seed aus H1-Registry (Name-Match auf Stammdaten) INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'focus_area', fa.id, 'description', 'Planung zielt auf Prävention, Deeskalation, Grenzen und sichere Übungsformen — nicht auf Wettkampf-Perfektion oder Technik-Show.' FROM focus_areas fa WHERE fa.name ILIKE 'Gewaltschutz' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'focus_area', fa.id, 'hints_on_path_qa', 'Gute Pfade bauen Sicherheit, Kommunikation und Alternativen auf; „Lücken“ sind fehlende Deeskalations- oder Rollenspiel-Stufen, nicht fehlende Kick-Varianten.' FROM focus_areas fa WHERE fa.name ILIKE 'Gewaltschutz' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'focus_area', fa.id, 'anti_patterns', 'Nicht nach Kumite-Tiefe, Explosivität oder Wettkampf-Belastung bewerten.' FROM focus_areas fa WHERE fa.name ILIKE 'Gewaltschutz' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'training_type', tt.id, 'description', 'Partizipation, Verständlichkeit, Freude am Bewegen; weniger maximale Spezialisierung.' FROM training_types tt WHERE tt.name ILIKE 'Breitensport' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'training_type', tt.id, 'hints_on_path_qa', 'Hohe OK-Rate bei moderatem Schwierigkeitsanstieg; „Perfektion“-Stufen nur optional, nicht als Pflicht-Lücke.' FROM training_types tt WHERE tt.name ILIKE 'Breitensport' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'training_type', tt.id, 'rematch_guard', 'Keine leeren Slots erzwingen, nur um eine Leistungs-Perfektionsstufe zu füllen.' FROM training_types tt WHERE tt.name ILIKE 'Breitensport' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'target_group', tg.id, 'description', 'Kinder: kurze Einheiten, spielerische Einstiege, Sicherheit und altersgerechte Komplexität.' FROM target_groups tg WHERE tg.name ILIKE 'Kinder' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'target_group', tg.id, 'hints_on_path_qa', 'Didaktik ohne Überforderung; klare Regeln und Sicherheit vor Perfektion; Lücken bei Spiel-/Rollenelementen wichtiger als Wettkampftiefe.' FROM target_groups tg WHERE tg.name ILIKE 'Kinder' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'target_group', tg.id, 'anti_patterns', 'Keine Erwachsenen-Wettkampf-Perfektion als QS-Maßstab.' FROM target_groups tg WHERE tg.name ILIKE 'Kinder' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'target_group', tg.id, 'description', 'Leistungsgruppe: höhere Anspruchskurven und Spezialisierung sind fachlich passend.' FROM target_groups tg WHERE tg.name ILIKE 'Leistungssportler' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'target_group', tg.id, 'hints_on_path_qa', 'Höhere Anspruchskurven, Belastungs- und Kombinationsprogressionen sind relevant; Lücken in Spezialisierung können echte Hinweise sein.' FROM target_groups tg WHERE tg.name ILIKE 'Leistungssportler' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'style_direction', sd.id, 'description', 'Shotokan-Linie: klare Kihon-Struktur, Hüft- und Standarbeit als wiederkehrende Qualitätsanker.' FROM style_directions sd WHERE sd.name ILIKE 'Shotokan' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'style_direction', sd.id, 'hints_on_progression', 'Nuancen in Stellung und Hüfttechnik, kein neuer Planungstyp.' FROM style_directions sd WHERE sd.name ILIKE 'Shotokan' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'training_type', tt.id, 'description', 'Wettkampforientiertes Training mit höherer Anspruchskurve und belastungsnahen Phasen.' FROM training_types tt WHERE tt.name ILIKE 'Wettkampf' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW(); INSERT INTO catalog_prompt_slots (catalog_kind, catalog_id, slot_key, content) SELECT 'training_type', tt.id, 'hints_on_path_qa', 'Spezialisierung, Kombination und Belastung unter Druck sind relevant; Lücken in Anwendungs- oder Perfektionsphasen können echte Hinweise sein.' FROM training_types tt WHERE tt.name ILIKE 'Wettkampf' ON CONFLICT (catalog_kind, catalog_id, slot_key) DO UPDATE SET content = EXCLUDED.content, updated_at = NOW();