-- Saga Manager (Sprint 4-6). Coordoneaza procese cu mai multi pasi care nu -- incap intr-o tranzactie. Garantia nu e atomicitatea, ci compensarea in -- ordine inversa a pasilor deja executati. DO $$ BEGIN CREATE TYPE "saga_status" AS ENUM ('RUNNING','COMPLETED','COMPENSATING','COMPENSATED','FAILED','TIMED_OUT'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; DO $$ BEGIN CREATE TYPE "saga_step_status" AS ENUM ('PENDING','RUNNING','COMPLETED','FAILED','COMPENSATED','SKIPPED'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; CREATE TABLE IF NOT EXISTS "saga_instances" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "tenant_id" uuid NOT NULL, "workspace_id" uuid, "saga_name" text NOT NULL, "saga_version" integer NOT NULL, "status" "saga_status" DEFAULT 'RUNNING' NOT NULL, "current_step" integer DEFAULT 0 NOT NULL, "trigger_event_id" uuid NOT NULL, "correlation_id" uuid, "context" jsonb DEFAULT '{}'::jsonb NOT NULL, "attempt" integer DEFAULT 0 NOT NULL, "next_attempt_at" timestamp DEFAULT now() NOT NULL, "timeout_at" timestamp, "last_error" text, "locked_until" timestamp, "created_at" timestamp DEFAULT now() NOT NULL, "updated_at" timestamp DEFAULT now() NOT NULL, "completed_at" timestamp ); -- Un eveniment porneste o singura instanta dintr-o saga data. Aceasta -- constrangere e ce face pornirea idempotenta, nu o verificare in cod. CREATE UNIQUE INDEX IF NOT EXISTS "saga_trigger_uq" ON "saga_instances" ("saga_name","saga_version","trigger_event_id"); CREATE INDEX IF NOT EXISTS "saga_due_idx" ON "saga_instances" ("status","next_attempt_at"); CREATE INDEX IF NOT EXISTS "saga_tenant_idx" ON "saga_instances" ("tenant_id","created_at"); CREATE TABLE IF NOT EXISTS "saga_steps" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "saga_instance_id" uuid NOT NULL, "step_name" text NOT NULL, "sequence" integer NOT NULL, "status" "saga_step_status" DEFAULT 'PENDING' NOT NULL, "attempts" integer DEFAULT 0 NOT NULL, "output" jsonb, "last_error" text, "started_at" timestamp, "completed_at" timestamp, "compensated_at" timestamp ); -- Un pas apare o singura data per instanta: baza idempotentei la avans. CREATE UNIQUE INDEX IF NOT EXISTS "saga_step_uq" ON "saga_steps" ("saga_instance_id","sequence");