Specul de arhitectura cere Platform Kernel INAINTEA modulelor de domeniu. Modulele A1/A2 au fost construite peste un kernel caruia ii lipseau exact piesele astea. Le adaug acum, aditiv, fara sa rup ce merge. - workspaces: tenant != workspace. Workspace-ul e contextul de lucru DIN tenant. Backfill: fiecare tenant existent primeste workspace implicit, altfel SessionGuard i-ar respinge toate requesturile. - memberships.workspace_id + valid_from/valid_until: rol per workspace si acces delegat cu expirare (contabil pana la o data). SessionGuard respinge membership expirat si membership legat de alt workspace. - ExecutionContext inlocuieste sesiunea subtire (userId+tenantId+role): requestId, correlationId, workspaceId, membershipId, roles, permissions, purpose, timezone, source. Tipul vechi ramane exportat sub acelasi nume, ca sa nu ating ~15 module de domeniu doar pentru o redenumire. - GET /v1/navigation: menu registry mutat in backend. Filtreaza pe rol, tip de workspace, permisiuni si feature flags; intoarce doar itemii autorizati. Ramane UX, nu securitate -- fiecare endpoint verifica din nou. - event envelope: workspace_id, occurred_at, actor_id, aggregate_type, causation_id, classification, provenance - audit envelope: workspace_id, actor_type, purpose, changed_fields, before/after hash, session_id
53 lines
3 KiB
SQL
53 lines
3 KiB
SQL
-- 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");
|