ceo-api/drizzle/0000_ancient_silver_surfer.sql
valentinbvro 5656f1cc1c feat: scaffold Business/Life/Intelligence/Trust Engine tables
Per Blueprint v4.0 §12 canonical data models:
- Business Engine: organizations extended (legal_name, country, registry_id,
  domain, external_ids), transactions (minor-unit amounts, evidence_status),
  documents (metadata only -- binary/OCR stays in Paperless via paperless_id)
- Life Engine: goals (horizon/metric/target/milestones)
- Intelligence Engine: decisions (context/options/assumptions/evidence),
  opportunities, ai_requests (context_manifest_hash for audit without
  storing sensitive payload content in Postgres)
- Trust Engine: observations (generic subject_type/subject_id so any
  entity -- user, org, device -- can feed reputation/trust scores)

Applied directly to Supabase staging Postgres (14 tables total now).
This is also the first drizzle/ migration actually committed -- the
earlier one from the Identity Engine work never made it into git.
2026-07-21 19:44:45 +02:00

187 lines
6.4 KiB
SQL

CREATE TYPE "public"."document_classification" AS ENUM('c0', 'c1', 'c2', 'c3', 'c4');--> statement-breakpoint
CREATE TYPE "public"."goal_status" AS ENUM('not_started', 'on_track', 'at_risk', 'achieved', 'abandoned');--> statement-breakpoint
CREATE TYPE "public"."membership_role" AS ENUM('owner', 'admin', 'member');--> statement-breakpoint
CREATE TYPE "public"."task_status" AS ENUM('open', 'in_progress', 'blocked', 'done', 'cancelled');--> statement-breakpoint
CREATE TYPE "public"."transaction_evidence_status" AS ENUM('missing', 'partial', 'complete', 'not_required');--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "ai_requests" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"requested_by_user_id" uuid NOT NULL,
"purpose" text NOT NULL,
"context_manifest_hash" text NOT NULL,
"model" text NOT NULL,
"template_version" text,
"cost_usd_minor_units" integer,
"result_status" text DEFAULT 'pending' NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"completed_at" timestamp
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "audit_log" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"actor_id" uuid,
"action" text NOT NULL,
"resource" text NOT NULL,
"reason" text,
"correlation_id" uuid,
"created_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "consent_records" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"user_id" uuid NOT NULL,
"purpose" text NOT NULL,
"granted_at" timestamp DEFAULT now() NOT NULL,
"revoked_at" timestamp
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "decisions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"owner_user_id" uuid NOT NULL,
"context" text NOT NULL,
"options" jsonb DEFAULT '[]'::jsonb NOT NULL,
"assumptions" jsonb DEFAULT '[]'::jsonb NOT NULL,
"evidence" jsonb DEFAULT '[]'::jsonb NOT NULL,
"selected_option" text,
"outcome_review" text,
"review_due_at" timestamp,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "documents" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"organization_id" uuid,
"owner_user_id" uuid NOT NULL,
"classification" "document_classification" DEFAULT 'c2' NOT NULL,
"paperless_id" text,
"filename" text NOT NULL,
"checksum" text,
"expires_at" timestamp,
"retention_policy" text,
"ocr_status" text,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp,
"version" integer DEFAULT 1 NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "goals" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"owner_user_id" uuid NOT NULL,
"horizon" text NOT NULL,
"metric" text NOT NULL,
"target" text NOT NULL,
"milestones" jsonb DEFAULT '[]'::jsonb NOT NULL,
"status" "goal_status" DEFAULT 'not_started' NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp,
"version" integer DEFAULT 1 NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "memberships" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"user_id" uuid NOT NULL,
"role" "membership_role" DEFAULT 'member' NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "observations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"subject_type" text NOT NULL,
"subject_id" text NOT NULL,
"metric" text NOT NULL,
"value" text NOT NULL,
"unit" text,
"source" text NOT NULL,
"observed_at" timestamp DEFAULT now() NOT NULL,
"confidence" numeric(5, 4)
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "opportunities" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"source" text NOT NULL,
"entity_type" text,
"entity_id" text,
"value_range_min" numeric(18, 0),
"value_range_max" numeric(18, 0),
"probability" numeric(5, 4),
"next_action" text,
"expires_at" timestamp,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "organizations" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"name" text NOT NULL,
"legal_name" text,
"country" text,
"registry_id" text,
"domain" text,
"external_ids" jsonb DEFAULT '{}'::jsonb NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp,
"version" integer DEFAULT 1 NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "outbox_events" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"event_type" text NOT NULL,
"event_version" integer DEFAULT 1 NOT NULL,
"subject_id" uuid,
"payload" jsonb NOT NULL,
"correlation_id" uuid,
"created_at" timestamp DEFAULT now() NOT NULL,
"processed_at" timestamp
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "tasks" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"owner_user_id" uuid NOT NULL,
"title" text NOT NULL,
"priority" integer DEFAULT 3 NOT NULL,
"due_at" timestamp,
"source_entity_type" text,
"source_entity_id" uuid,
"status" "task_status" DEFAULT 'open' NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp,
"version" integer DEFAULT 1 NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "tenants" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"name" text NOT NULL,
"created_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "transactions" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"tenant_id" uuid NOT NULL,
"organization_id" uuid NOT NULL,
"type" text NOT NULL,
"amount_minor_units" numeric(18, 0) NOT NULL,
"currency" text NOT NULL,
"transaction_date" timestamp NOT NULL,
"evidence_status" "transaction_evidence_status" DEFAULT 'missing' NOT NULL,
"source" text,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp,
"version" integer DEFAULT 1 NOT NULL
);