-- Migration 034: Workflow Foundation -- Phase 0: Datenmodell für Workflow-Erweiterung der Prompt Engine -- Erstellt: 2026-04-03 -- ============================================================ -- Tabelle: workflow_definitions -- Speichert Workflow-Graphen (Knoten + Kanten) -- ============================================================ CREATE TABLE IF NOT EXISTS workflow_definitions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, slug VARCHAR(100) UNIQUE NOT NULL, description TEXT, graph JSONB NOT NULL, -- Der Workflow-Graph (Knoten + Kanten) version INTEGER DEFAULT 1, active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_workflow_definitions_slug ON workflow_definitions(slug); CREATE INDEX IF NOT EXISTS idx_workflow_definitions_active ON workflow_definitions(active); -- ============================================================ -- Tabelle: workflow_question_catalog -- Katalog der Fragenergänzungen (6 Grundtypen) -- ============================================================ CREATE TABLE IF NOT EXISTS workflow_question_catalog ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), question_type VARCHAR(50) NOT NULL, -- relevanz, prioritaet, selektion, ausschluss, eskalation, unsicherheit label VARCHAR(255) NOT NULL, question_template TEXT NOT NULL, -- Template für die Frage answer_spectrum JSONB NOT NULL, -- z.B. ["ja", "nein", "unklar"] normalization_rules JSONB, -- Regeln für Normalisierung (Synonyme, etc.) active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_workflow_question_catalog_type ON workflow_question_catalog(question_type); CREATE INDEX IF NOT EXISTS idx_workflow_question_catalog_active ON workflow_question_catalog(active); -- Seed: 6 Grundtypen der Fragenergänzungen INSERT INTO workflow_question_catalog (question_type, label, question_template, answer_spectrum, normalization_rules, active) VALUES ( 'relevanz', 'Relevanz-Frage', 'Ist eine vertiefte Analyse in diesem Bereich relevant?', '["ja", "nein", "unklar"]'::JSONB, '{"synonyms": {"ja": ["yes", "Ja", "JA", "relevant", "sinnvoll"], "nein": ["no", "Nein", "NEIN", "nicht relevant", "unwichtig"], "unklar": ["unclear", "unsure", "vielleicht", "möglicherweise"]}}'::JSONB, true ), ( 'prioritaet', 'Prioritäts-Frage', 'Wie hoch ist die Priorität für eine Analyse in diesem Bereich?', '["hoch", "mittel", "niedrig", "unklar"]'::JSONB, '{"synonyms": {"hoch": ["high", "Hoch", "HOCH", "urgent", "dringend"], "mittel": ["medium", "Mittel", "MITTEL", "moderat"], "niedrig": ["low", "Niedrig", "NIEDRIG", "gering"], "unklar": ["unclear", "unsure", "kann nicht einschätzen"]}}'::JSONB, true ), ( 'selektion', 'Selektions-Frage', 'Soll dieser Pfad ausgewählt werden?', '["ja", "nein", "unklar"]'::JSONB, '{"synonyms": {"ja": ["yes", "Ja", "JA", "auswählen", "select"], "nein": ["no", "Nein", "NEIN", "nicht auswählen", "skip"], "unklar": ["unclear", "unsure", "vielleicht"]}}'::JSONB, true ), ( 'ausschluss', 'Ausschluss-Frage', 'Soll dieser Pfad ausgeschlossen werden?', '["ja", "nein", "unklar"]'::JSONB, '{"synonyms": {"ja": ["yes", "Ja", "JA", "ausschließen", "exclude"], "nein": ["no", "Nein", "NEIN", "nicht ausschließen", "include"], "unklar": ["unclear", "unsure", "vielleicht"]}}'::JSONB, true ), ( 'eskalation', 'Eskalations-Frage', 'Ist eine Eskalation oder besondere Aufmerksamkeit erforderlich?', '["ja", "nein", "unklar"]'::JSONB, '{"synonyms": {"ja": ["yes", "Ja", "JA", "eskalieren", "alert"], "nein": ["no", "Nein", "NEIN", "normal", "routine"], "unklar": ["unclear", "unsure", "vielleicht"]}}'::JSONB, true ), ( 'unsicherheit', 'Unsicherheits-Frage', 'Besteht Unsicherheit in der Bewertung?', '["ja", "nein", "unklar"]'::JSONB, '{"synonyms": {"ja": ["yes", "Ja", "JA", "unsicher", "uncertain"], "nein": ["no", "Nein", "NEIN", "sicher", "certain"], "unklar": ["unclear", "unsure", "vielleicht"]}}'::JSONB, true ); -- ============================================================ -- Tabelle: workflow_executions -- Ausführungs-Log für Workflow-Runs -- ============================================================ CREATE TABLE IF NOT EXISTS workflow_executions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), workflow_id UUID REFERENCES workflow_definitions(id) ON DELETE CASCADE, profile_id UUID REFERENCES profiles(id) ON DELETE CASCADE, status VARCHAR(20) NOT NULL DEFAULT 'running', -- running, completed, failed, partial node_states JSONB, -- Status jedes Knotens (executed, skipped, unclear, failed) execution_log JSONB, -- Detaillierter Ablauf started_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), completed_at TIMESTAMP WITH TIME ZONE ); CREATE INDEX IF NOT EXISTS idx_workflow_executions_workflow_id ON workflow_executions(workflow_id); CREATE INDEX IF NOT EXISTS idx_workflow_executions_profile_id ON workflow_executions(profile_id); CREATE INDEX IF NOT EXISTS idx_workflow_executions_status ON workflow_executions(status); CREATE INDEX IF NOT EXISTS idx_workflow_executions_started_at ON workflow_executions(started_at DESC); -- ============================================================ -- Erweiterung bestehende Tabelle: ai_prompts -- Optionale Prompt-gebundene Standard-Fragenergänzungen -- (Sekundär: Knotenspezifische Fragen haben Vorrang) -- ============================================================ ALTER TABLE ai_prompts ADD COLUMN IF NOT EXISTS question_augmentations JSONB; COMMENT ON COLUMN ai_prompts.question_augmentations IS 'Optionale Standard-Fragenergänzungen für diesen Prompt. Knotenspezifische Fragen im Workflow-Graph haben Vorrang (Hybridmodell mit Vorrangregel).'; -- ============================================================ -- Kommentare für Dokumentation -- ============================================================ COMMENT ON TABLE workflow_definitions IS 'Workflow-Graphen (Knoten + Kanten) als JSONB. Erweitert die Prompt Engine um verzweigbare, bedingte Analysen.'; COMMENT ON TABLE workflow_question_catalog IS 'Katalog der 6 Grundtypen von Fragenergänzungen mit Antwortspektren und Normalisierungsregeln.'; COMMENT ON TABLE workflow_executions IS 'Ausführungs-Log für Workflow-Runs mit Knoten-Status und detailliertem Ablauf.'; COMMENT ON COLUMN workflow_definitions.graph IS 'JSONB: {nodes: [{id, type, prompt_slug, question_augmentations, position}, ...], edges: [{id, from, to}, ...]}'; COMMENT ON COLUMN workflow_executions.node_states IS 'JSONB: {node_id: {status: "executed|skipped|unclear|failed", ...}, ...}'; COMMENT ON COLUMN workflow_executions.execution_log IS 'JSONB: Chronologischer Ablauf mit Timestamps, Entscheidungen, normalisierten Signalen.';