-- Migration 068: KI Skill-Retrieval-Profile pro Fokusbereich (+ Standardprofil) -- Purpose: Gewichtungen/Quota fuer exercise_ai Skill-Katalog (OpenRouter Kontext) CREATE TABLE IF NOT EXISTS ai_skill_retrieval_profiles ( id SERIAL PRIMARY KEY, focus_area_id INT REFERENCES focus_areas(id) ON DELETE CASCADE, is_default BOOLEAN NOT NULL DEFAULT FALSE, name VARCHAR(200) NOT NULL, description TEXT, active BOOLEAN NOT NULL DEFAULT TRUE, config JSONB NOT NULL DEFAULT '{}'::jsonb, updated_at TIMESTAMP DEFAULT NOW() ); CREATE UNIQUE INDEX IF NOT EXISTS ux_ai_skill_retrieval_profile_focus_area ON ai_skill_retrieval_profiles (focus_area_id) WHERE focus_area_id IS NOT NULL AND active = TRUE; CREATE UNIQUE INDEX IF NOT EXISTS ux_ai_skill_retrieval_profile_default_only ON ai_skill_retrieval_profiles (is_default) WHERE is_default IS TRUE AND active = TRUE; COMMENT ON TABLE ai_skill_retrieval_profiles IS 'Gewichte/Quota fuer Skill-Katalog in exercise_ai; optional gebunden an focus_areas, genau eine is_default=TRUE'; INSERT INTO ai_skill_retrieval_profiles (focus_area_id, is_default, name, description, active, config) VALUES ( NULL, TRUE, 'Standard', 'Kein/Undefinierter Fokusbereich: neutrale Gewichte mit sanften Caps auf sehr breite Unterkategorien.', TRUE, '{ "version": 1, "importance_multiplier": 1, "text_overlap_bonus": 2, "main_slug_weights": { "karate": 1, "allgemeine": 1 }, "category_slug_weights": {}, "category_max_share": { "kondition": 0.38, "koordination": 0.35 }, "main_min_share": {}, "description_plain_max_len": 160, "karate_relevance_max_len": 72, "keyword_overrides": [ { "keywords_any": ["rollenspiel", "szenario", "deesk", "diskussion"], "case_insensitive": true, "patch": { "category_slug_weights": { "psychische_faehigkeiten": 1.65, "soziale_faehigkeiten": 1.65, "kognition": 1.4 }, "category_max_share": { "kondition": 0.08, "koordination": 0.1 } } }, { "keywords_any": ["befreiung", "haltegriff", "greifer", "umklammer"], "case_insensitive": true, "patch": { "category_slug_weights": { "selbstverteidigung": 2.2, "koordination": 0.9 }, "main_slug_weights": { "karate": 1.35 } } } ] }'::jsonb ); INSERT INTO ai_skill_retrieval_profiles (focus_area_id, is_default, name, description, active, config) SELECT fa.id, FALSE, 'Gewaltschutz', 'Kaum klassische Sportfaehigkeit; Gewicht auf Deeskalation, Kognition/Soziales; SV-Schwerpunkt per Keywords verstaerken.', TRUE, '{ "version": 1, "importance_multiplier": 1, "text_overlap_bonus": 2.25, "main_slug_weights": { "karate": 1.08, "allgemeine": 1.06 }, "category_slug_weights": { "kognition": 1.72, "psychische_faehigkeiten": 1.78, "soziale_faehigkeiten": 1.78, "selbstverteidigung": 1.82, "kondition": 0.32, "koordination": 0.4 }, "category_max_share": { "kondition": 0.12, "koordination": 0.16 }, "main_min_share": {}, "description_plain_max_len": 150, "karate_relevance_max_len": 0, "keyword_overrides": [ { "keywords_any": ["befreiung", "haltegriff", "greifer"], "case_insensitive": true, "patch": { "category_slug_weights": { "selbstverteidigung": 3.25, "koordination": 1.08 }, "main_slug_weights": { "karate": 1.5 } } } ] }'::jsonb FROM focus_areas fa WHERE fa.name = 'Gewaltschutz' AND (fa.status IS NULL OR fa.status = 'active') AND NOT EXISTS ( SELECT 1 FROM ai_skill_retrieval_profiles p WHERE p.focus_area_id = fa.id AND p.active = TRUE ) LIMIT 1;