-- Platform Kernel v1 (spec sectiunile 3, 4, 11, 29). -- Aditiv si idempotent: coloanele noi sunt nullable sau au default, ca sa nu -- pice pe randurile existente. -- 1. Workspaces ------------------------------------------------------------- DO $$ BEGIN CREATE TYPE "workspace_type" AS ENUM ('personal','family','business','community','project'); EXCEPTION WHEN duplicate_object THEN NULL; END $$; CREATE TABLE IF NOT EXISTS "workspaces" ( "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, "tenant_id" uuid NOT NULL, "name" text NOT NULL, "type" "workspace_type" DEFAULT 'business' NOT NULL, "is_default" integer DEFAULT 0 NOT NULL, "created_at" timestamp DEFAULT now() NOT NULL, "created_by" uuid, "deleted_at" timestamp ); CREATE INDEX IF NOT EXISTS "workspaces_tenant_idx" ON "workspaces" ("tenant_id"); -- Backfill: fiecare tenant existent primeste workspace-ul implicit. Fara asta, -- SessionGuard ar respinge toate requesturile tenantilor creati inainte. INSERT INTO "workspaces" ("tenant_id", "name", "type", "is_default") SELECT t."id", t."name", 'business', 1 FROM "tenants" t WHERE NOT EXISTS (SELECT 1 FROM "workspaces" w WHERE w."tenant_id" = t."id"); -- 2. Memberships: scope pe workspace + fereastra de valabilitate ------------- ALTER TABLE "memberships" ADD COLUMN IF NOT EXISTS "workspace_id" uuid; ALTER TABLE "memberships" ADD COLUMN IF NOT EXISTS "valid_from" timestamp; ALTER TABLE "memberships" ADD COLUMN IF NOT EXISTS "valid_until" timestamp; CREATE INDEX IF NOT EXISTS "memberships_workspace_idx" ON "memberships" ("workspace_id"); -- 3. Event envelope complet ------------------------------------------------- ALTER TABLE "outbox_events" ADD COLUMN IF NOT EXISTS "workspace_id" uuid; ALTER TABLE "outbox_events" ADD COLUMN IF NOT EXISTS "occurred_at" timestamp DEFAULT now() NOT NULL; ALTER TABLE "outbox_events" ADD COLUMN IF NOT EXISTS "actor_id" uuid; ALTER TABLE "outbox_events" ADD COLUMN IF NOT EXISTS "aggregate_type" text; ALTER TABLE "outbox_events" ADD COLUMN IF NOT EXISTS "causation_id" uuid; ALTER TABLE "outbox_events" ADD COLUMN IF NOT EXISTS "classification" text DEFAULT 'c2' NOT NULL; ALTER TABLE "outbox_events" ADD COLUMN IF NOT EXISTS "provenance" jsonb DEFAULT '{}'::jsonb NOT NULL; CREATE INDEX IF NOT EXISTS "outbox_unprocessed_idx" ON "outbox_events" ("processed_at","created_at"); -- 4. Audit envelope complet ------------------------------------------------- ALTER TABLE "audit_log" ADD COLUMN IF NOT EXISTS "workspace_id" uuid; ALTER TABLE "audit_log" ADD COLUMN IF NOT EXISTS "actor_type" text DEFAULT 'user' NOT NULL; ALTER TABLE "audit_log" ADD COLUMN IF NOT EXISTS "purpose" text; ALTER TABLE "audit_log" ADD COLUMN IF NOT EXISTS "changed_fields" jsonb; ALTER TABLE "audit_log" ADD COLUMN IF NOT EXISTS "before_hash" text; ALTER TABLE "audit_log" ADD COLUMN IF NOT EXISTS "after_hash" text; ALTER TABLE "audit_log" ADD COLUMN IF NOT EXISTS "session_id" text; CREATE INDEX IF NOT EXISTS "audit_tenant_created_idx" ON "audit_log" ("tenant_id","created_at");