shinkan-jinkendo/backend/migrations/067_ai_prompts_exercise_assistant.sql
Lars e4451e1362
Some checks failed
Test Suite / playwright-tests (push) Waiting to run
Deploy Development / deploy (push) Successful in 43s
Test Suite / pytest-backend (push) Failing after 1s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Has been cancelled
Enhance Exercise Management and AI Integration
- Updated the exercise form to include a tabbed navigation structure, improving user experience with sections for Stammdaten, Anleitung, Einordnung, Varianten, and Medien & Mehr.
- Introduced the concept of **Freigabelevel** (visibility level) in the UI, replacing previous terminology for clarity and consistency across components.
- Implemented new AI endpoints for exercise suggestions and regeneration, allowing for dynamic content generation without direct database writes.
- Removed the legacy `is_primary` flag from exercise skills in the UI, ensuring that intensity levels (`niedrig`, `mittel`, `hoch`) are the primary focus for skill management.
- Enhanced the variant management process with improved saving mechanisms and UI updates to reflect changes more intuitively.
2026-05-22 07:52:31 +02:00

142 lines
4.9 KiB
SQL

-- Migration 067: Konfigurierbare KI-Prompts + Tracking-Feld fuer Uebungs-Zusammenfassung
-- Datum: 2026-05-22
-- Spec: technical/KI_FEATURES_SPEC.md, AI_PROMPT_SYSTEM_SPEC.md
-- ============================================================================
-- AI PROMPTS
-- ============================================================================
CREATE TABLE IF NOT EXISTS ai_prompts (
id SERIAL PRIMARY KEY,
slug VARCHAR(100) NOT NULL UNIQUE,
display_name VARCHAR(200) NOT NULL,
description TEXT,
template TEXT NOT NULL,
category VARCHAR(50) DEFAULT 'exercise'
CHECK (category IN ('exercise', 'training', 'matrix', 'import', 'admin')),
output_format VARCHAR(10) DEFAULT 'text'
CHECK (output_format IN ('text', 'json')),
output_schema JSONB,
is_system_default BOOLEAN DEFAULT false,
default_template TEXT,
active BOOLEAN DEFAULT true,
sort_order INT DEFAULT 0,
created_by INT REFERENCES profiles(id) ON DELETE SET NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_ai_prompts_slug ON ai_prompts(slug);
CREATE INDEX IF NOT EXISTS idx_ai_prompts_category ON ai_prompts(category);
CREATE INDEX IF NOT EXISTS idx_ai_prompts_active ON ai_prompts(active, sort_order);
DROP TRIGGER IF EXISTS ai_prompts_update ON ai_prompts;
CREATE TRIGGER ai_prompts_update
BEFORE UPDATE ON ai_prompts
FOR EACH ROW EXECUTE FUNCTION update_timestamp();
-- ============================================================================
-- TRACKING SUMMARY (KI)
-- ============================================================================
ALTER TABLE exercises ADD COLUMN IF NOT EXISTS summary_ai_generated BOOLEAN DEFAULT false;
COMMENT ON COLUMN exercises.summary_ai_generated IS 'TRUE wenn Kurzbeschreibung zuletzt von KI vorgeschlagen und uebernommen (UI setzt bei manueller Aenderung false)';
-- ============================================================================
-- SEED PROMPTS (idempotent)
-- ============================================================================
INSERT INTO ai_prompts (
slug, display_name, description, template,
category, output_format, is_system_default, default_template, active, sort_order
)
SELECT
'pipeline',
'Mehrstufige Gesamtanalyse',
'Master-Schalter fuer die Pipeline-Anzeige.',
'PIPELINE_MASTER',
'admin',
'text',
false,
'PIPELINE_MASTER',
true,
-10
WHERE NOT EXISTS (SELECT 1 FROM ai_prompts WHERE slug = 'pipeline');
INSERT INTO ai_prompts (
slug, display_name, description, template,
category, output_format, is_system_default, default_template, active, sort_order
)
SELECT
'exercise_summary',
'Uebungs-Zusammenfassung',
'Erzeugt eine kurze Kurzbeschreibung fuer Listen/Galerie.',
$s$Du bist Assistent fuer Kampfsport-Trainer.
Erstelle eine kurze Kurzbeschreibung fuer Listen und Trainingsplaene.
Anforderungen:
- Hochstens etwa 200 Zeichen (bei Bedarf gekuerzt fuer Mobile)
- Kern: Welche Trainingsqualitaeten? Wie fuehrt man die Uebung kurz aus?
- Sachlich, auf Deutsch
Uebung: {{exercise_title}}
Fokuskontext: {{exercise_focus_area}}
Ziel (Fliesstext, kann HTML sein): {{exercise_goal}}
Durchfuehrung (Fliesstext, kann HTML sein): {{exercise_execution}}
Antworte NUR mit der Kurzbeschreibung als einfachen Text (keine Markdown-Codeblocks, keine Anfuehrungszeichen um den ganzen Text).$s$,
'exercise',
'text',
true,
NULL,
true,
1
WHERE NOT EXISTS (SELECT 1 FROM ai_prompts WHERE slug = 'exercise_summary');
INSERT INTO ai_prompts (
slug, display_name, description, template,
category, output_format, is_system_default, default_template, active, sort_order
)
SELECT
'exercise_skill_suggestions',
'Faehigkeiten-Empfehlungen',
'Schlaegt passende Skills mit Stufen/Intensitaet vor (JSON-Ausgabe-Prompt).',
$j$Du bist Assistent fuer Kampfsport-Trainer.
Ordne diese Uebung dem globalen Skill-Katalog zu.
Daten zur Uebung:
Titel: {{exercise_title}}
Fokuskontext (optional): {{exercise_focus_area}}
Ziel (gekuerzt_plain): {{exercise_goal}}
Durchfuehrung (gekuerzt_plain): {{exercise_execution}}
Verfuegbare Faehigkeiten (Auswahl NUR ueber diese IDs keine anderen IDs verwenden):
{{skills_catalog}}
Waehle hoechstens 5 passende Skills. Für jede Faehigkeit:
- skill_id: ganze Zahl aus der Liste
- required_level: eines von basis, grundlagen, aufbau, fortgeschritten, optimierung
- target_level: derselbe Wertvorrat
- intensity: eines von niedrig, mittel, hoch
- is_primary (optional): true fuer die Hauptfaehigkeit der Uebung, sondern false/weglassen
Antworte NUR mit einem JSON-Array ohne Erklaertext, keine Markdown-Fences.
Beispielformat:
[{"skill_id": 1, "required_level": "grundlagen", "target_level": "aufbau", "intensity": "hoch", "is_primary": true}]
Wenn nichts gut passt, antworte mit [].$j$,
'exercise',
'json',
true,
NULL,
true,
2
WHERE NOT EXISTS (SELECT 1 FROM ai_prompts WHERE slug = 'exercise_skill_suggestions');