Backend: - DB-Migration 034: workflow_definitions, workflow_question_catalog, workflow_executions - ai_prompts.question_augmentations JSONB-Spalte (Hybridmodell: Prompt-Defaults) - 6 Grundtypen Fragenergänzungen mit Normalisierungsregeln (Seed-Daten) - Pydantic-Modelle (16 Models, 11 Enums) in workflow_models.py - Workflow-Engine: Graph-Parsing, Topologische Sortierung, DAG-Validierung - Dispatcher-Erweiterung type='workflow' (Stub für Phase 1-3) - Adjacency Lists, Erreichbarkeits-Prüfungen, Zyklen-Erkennung Testing: - 22 Unit-Tests (alle bestanden): Graph-Parsing, Validierung, Topologische Sortierung - Fixtures: simple_valid_graph, parallel_graph, branching_graph Version: - APP_VERSION 0.9i - DB_SCHEMA_VERSION 20260403 - Module: workflow 0.1.0 Anforderungsanalyse: .claude/task/Workflow_engine_prompting_engine/anforderungsanalyse_umsetzungsplan.md Konzept-Basis: .claude/task/Workflow_engine_prompting_engine/konzept_workflow_engine_konsolidated.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
133 lines
7.1 KiB
SQL
133 lines
7.1 KiB
SQL
-- 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.';
|