-- Projection Kernel (Sprint 1). Read models: NU sunt sursa de adevar, pot fi -- sterse si reconstruite oricand din tabelele canonice. -- Garantia de idempotency: acelasi eveniment nu se aplica de doua ori. CREATE TABLE IF NOT EXISTS "projection_processed_events" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "projection_name" text NOT NULL, "projection_version" integer NOT NULL, "event_id" uuid NOT NULL, "processed_at" timestamp DEFAULT now() NOT NULL ); CREATE UNIQUE INDEX IF NOT EXISTS "projection_processed_uq" ON "projection_processed_events" ("projection_name","projection_version","event_id"); -- Checkpoint = optimizare (de unde reia scanarea), nu garantia de corectitudine. CREATE TABLE IF NOT EXISTS "projection_checkpoints" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "projection_name" text NOT NULL, "projection_version" integer NOT NULL, "last_event_at" timestamp, "last_event_id" uuid, "status" text DEFAULT 'active' NOT NULL, "last_error" text, "updated_at" timestamp DEFAULT now() NOT NULL ); CREATE UNIQUE INDEX IF NOT EXISTS "projection_checkpoint_uq" ON "projection_checkpoints" ("projection_name","projection_version"); CREATE TABLE IF NOT EXISTS "executive_dashboard_projection" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "tenant_id" uuid NOT NULL, "workspace_id" uuid NOT NULL, "open_tasks_count" integer DEFAULT 0 NOT NULL, "overdue_tasks_count" integer DEFAULT 0 NOT NULL, "deadlines_next_7_days" integer DEFAULT 0 NOT NULL, "organizations_count" integer DEFAULT 0 NOT NULL, "segments_count" integer DEFAULT 0 NOT NULL, "research_briefs_count" integer DEFAULT 0 NOT NULL, "documents_missing_count" integer DEFAULT 0 NOT NULL, "transactions_unclassified_count" integer DEFAULT 0 NOT NULL, "pending_approvals_count" integer DEFAULT 0 NOT NULL, "generated_at" timestamp DEFAULT now() NOT NULL, "projection_version" integer DEFAULT 1 NOT NULL ); -- Cheia de UPSERT (spec ยง5.3): o linie per tenant+workspace. CREATE UNIQUE INDEX IF NOT EXISTS "executive_dashboard_tenant_ws_uq" ON "executive_dashboard_projection" ("tenant_id","workspace_id");