-- PROJ: workflows / Consumption-Regeln -- Doku-only (siehe README.md in diesem Verzeichnis) — die tatsächliche -- Ausführung passiert idempotent über internal/storage/workflows.go -- initWorkflowsSchema(), aufgerufen aus (*Store).initSchema() NACH -- initClassificationTemplatesSchema (eine Workflow-Action kann eine -- Klassifizierungsvorlage referenzieren: apply_classification_template). -- -- Workflows (Consumption-Regeln): tenant-skopierte Automatisierungsregeln, die -- an einem Trigger-Punkt (MVP: on_upload) ausgewertet werden. Ein passender -- Workflow führt seine geordneten Actions auf dem Dokument aus. Die -- Bedingung ist ein JSONB-Condition-Tree (bool. Gruppen and/or + Leaf-Knoten -- mit Feld/Algorithmus/Pattern, MVP-Verschachtelungstiefe 2). Jede Auswertung -- wird dokument-skopiert in workflow_runs protokolliert (GoBD-Reproduzierbarkeit -- parallel zum globalen internal/audit-Log). -- -- Best-effort-Ausführung: eine fehlgeschlagene Action bricht den Upload niemals -- ab — Fehler werden in workflow_runs.error festgehalten und die Schleife läuft -- weiter (spiegelt die "never fail the upload"-Philosophie der OCR-/ -- Auto-Assign-Schritte in storeUploadedFile). CREATE TABLE IF NOT EXISTS workflows ( id BIGSERIAL PRIMARY KEY, tenant_id BIGINT NOT NULL, name TEXT NOT NULL, enabled BOOLEAN NOT NULL DEFAULT true, trigger_type TEXT NOT NULL CHECK (trigger_type IN ('on_upload')), condition_tree JSONB NOT NULL, priority INT NOT NULL DEFAULT 100, created_by BIGINT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), UNIQUE(tenant_id, name) ); CREATE INDEX IF NOT EXISTS idx_workflows_tenant ON workflows(tenant_id); CREATE TABLE IF NOT EXISTS workflow_actions ( id BIGSERIAL PRIMARY KEY, workflow_id BIGINT NOT NULL REFERENCES workflows(id) ON DELETE CASCADE, step_order INT NOT NULL, action_type TEXT NOT NULL CHECK (action_type IN ('add_tag','set_doc_type','set_correspondent','apply_classification_template','set_custom_field')), action_config JSONB NOT NULL DEFAULT '{}' ); CREATE INDEX IF NOT EXISTS idx_workflow_actions_workflow ON workflow_actions(workflow_id, step_order); CREATE TABLE IF NOT EXISTS workflow_runs ( id BIGSERIAL PRIMARY KEY, workflow_id BIGINT NOT NULL REFERENCES workflows(id) ON DELETE CASCADE, tenant_id BIGINT NOT NULL, document_id BIGINT, triggered_at TIMESTAMPTZ NOT NULL DEFAULT now(), matched BOOLEAN NOT NULL, actions_applied JSONB, error TEXT ); CREATE INDEX IF NOT EXISTS idx_workflow_runs_workflow ON workflow_runs(workflow_id); CREATE INDEX IF NOT EXISTS idx_workflow_runs_document ON workflow_runs(document_id);