Built the Oracle Tab (#14)
This commit is contained in:
206
backend/oracle/schema_oracle.sql
Normal file
206
backend/oracle/schema_oracle.sql
Normal file
@@ -0,0 +1,206 @@
|
||||
-- Oracle Canvas Schema — Section 16.4 of the Oracle Architecture Document v1.0
|
||||
-- Run this against your PostgreSQL database to create the Oracle persistence layer.
|
||||
-- Requires: UUID extension, JSONB support (PostgreSQL 14+)
|
||||
|
||||
-- ── Prerequisites ─────────────────────────────────────────────────────────────
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
||||
|
||||
-- ── Core tables ───────────────────────────────────────────────────────────────
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_canvas_pages (
|
||||
page_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
owner_id TEXT NOT NULL,
|
||||
branch_id TEXT NOT NULL,
|
||||
branch_name TEXT NOT NULL DEFAULT 'main',
|
||||
page_type TEXT NOT NULL DEFAULT 'main' CHECK (page_type IN ('main', 'fork')),
|
||||
title TEXT NOT NULL DEFAULT 'Untitled Canvas',
|
||||
is_shared BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
head_revision INTEGER NOT NULL DEFAULT 0,
|
||||
base_revision INTEGER NOT NULL DEFAULT 0,
|
||||
sharing_policy JSONB NOT NULL DEFAULT '{"shareMode":"direct_fork_only","allowReshare":false,"defaultForkVisibility":"private"}'::JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_canvas_page_revisions (
|
||||
revision_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
page_id UUID NOT NULL REFERENCES oracle_canvas_pages(page_id) ON DELETE CASCADE,
|
||||
tenant_id TEXT NOT NULL,
|
||||
revision_number INTEGER NOT NULL,
|
||||
commit_kind TEXT NOT NULL CHECK (commit_kind IN ('prompt', 'merge', 'rollback', 'manual_edit')),
|
||||
commit_summary TEXT,
|
||||
actor_id TEXT NOT NULL,
|
||||
execution_id UUID,
|
||||
merge_request_id UUID,
|
||||
components_snapshot JSONB NOT NULL DEFAULT '[]'::JSONB,
|
||||
idempotency_key TEXT UNIQUE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
UNIQUE (page_id, revision_number)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_canvas_components (
|
||||
component_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
page_id UUID NOT NULL REFERENCES oracle_canvas_pages(page_id) ON DELETE CASCADE,
|
||||
tenant_id TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
version INTEGER NOT NULL DEFAULT 1,
|
||||
lifecycle_state TEXT NOT NULL DEFAULT 'active' CHECK (lifecycle_state IN ('draft','active','superseded','archived','revoked')),
|
||||
data_source_descriptor JSONB NOT NULL,
|
||||
visualization_parameters JSONB NOT NULL DEFAULT '{}'::JSONB,
|
||||
data_bindings JSONB NOT NULL DEFAULT '{}'::JSONB,
|
||||
provenance JSONB NOT NULL,
|
||||
rendering_hints JSONB NOT NULL,
|
||||
layout JSONB NOT NULL,
|
||||
access_controls JSONB NOT NULL,
|
||||
style_signature JSONB NOT NULL DEFAULT '{}'::JSONB,
|
||||
validation_state JSONB NOT NULL DEFAULT '{}'::JSONB,
|
||||
audit_log TEXT[] NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_prompt_executions (
|
||||
execution_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
page_id UUID NOT NULL REFERENCES oracle_canvas_pages(page_id) ON DELETE CASCADE,
|
||||
branch_id TEXT NOT NULL,
|
||||
actor_id TEXT NOT NULL,
|
||||
prompt TEXT NOT NULL,
|
||||
intent_class TEXT NOT NULL DEFAULT 'analytical',
|
||||
status TEXT NOT NULL DEFAULT 'received',
|
||||
model_runtime TEXT NOT NULL DEFAULT 'nemoclaw_hosted',
|
||||
semantic_model_version TEXT NOT NULL DEFAULT 'oracle_semantic_v1',
|
||||
retrieval_plan JSONB,
|
||||
visualization_plan JSONB,
|
||||
warnings TEXT[] NOT NULL DEFAULT '{}',
|
||||
summary TEXT,
|
||||
components_created TEXT[] NOT NULL DEFAULT '{}',
|
||||
client_request_id TEXT UNIQUE,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
completed_at TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_component_templates (
|
||||
template_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
category TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'catalog_active',
|
||||
origin TEXT NOT NULL DEFAULT 'premade',
|
||||
version TEXT NOT NULL DEFAULT '1.0.0',
|
||||
accepted_shapes TEXT[] NOT NULL DEFAULT '{}',
|
||||
style_signature JSONB DEFAULT NULL,
|
||||
validation_state JSONB DEFAULT NULL,
|
||||
provenance JSONB DEFAULT NULL,
|
||||
use_count INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_forks (
|
||||
fork_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
source_page_id UUID NOT NULL REFERENCES oracle_canvas_pages(page_id),
|
||||
source_branch_id TEXT NOT NULL,
|
||||
source_revision INTEGER NOT NULL,
|
||||
fork_page_id UUID NOT NULL REFERENCES oracle_canvas_pages(page_id),
|
||||
fork_branch_id TEXT NOT NULL,
|
||||
recipient_user_id TEXT NOT NULL,
|
||||
created_by TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active','merged','closed')),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_merge_requests (
|
||||
merge_request_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
source_page_id UUID NOT NULL REFERENCES oracle_canvas_pages(page_id),
|
||||
source_branch_id TEXT NOT NULL,
|
||||
source_head_revision INTEGER NOT NULL,
|
||||
target_page_id UUID NOT NULL REFERENCES oracle_canvas_pages(page_id),
|
||||
target_branch_id TEXT NOT NULL,
|
||||
target_base_revision INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open','changes_requested','approved','merged','closed')),
|
||||
conflicts JSONB NOT NULL DEFAULT '[]'::JSONB,
|
||||
diff_summary JSONB DEFAULT NULL,
|
||||
resolutions JSONB DEFAULT NULL,
|
||||
created_by TEXT NOT NULL,
|
||||
reviewed_by TEXT,
|
||||
reviewer_comment TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_lineage_records (
|
||||
lineage_record_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
source_kind TEXT NOT NULL,
|
||||
source_id TEXT NOT NULL,
|
||||
transformation_type TEXT NOT NULL,
|
||||
transformation_spec_hash TEXT,
|
||||
produced_kind TEXT NOT NULL,
|
||||
produced_id TEXT NOT NULL,
|
||||
policy_snapshot_id TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS oracle_audit_events (
|
||||
audit_event_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
entity_type TEXT NOT NULL,
|
||||
entity_id TEXT NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
actor_id TEXT NOT NULL,
|
||||
actor_type TEXT NOT NULL DEFAULT 'user',
|
||||
correlation_id TEXT NOT NULL,
|
||||
execution_id UUID,
|
||||
details JSONB NOT NULL DEFAULT '{}'::JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- ── Indexes ───────────────────────────────────────────────────────────────────
|
||||
|
||||
-- Canvas pages: tenant lookup, branch lookup
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_pages_tenant ON oracle_canvas_pages(tenant_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_pages_owner ON oracle_canvas_pages(owner_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_pages_branch ON oracle_canvas_pages(branch_id);
|
||||
|
||||
-- Revisions: page-scoped revision queries
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_revisions_page ON oracle_canvas_page_revisions(page_id, revision_number DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_revisions_tenant ON oracle_canvas_page_revisions(tenant_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_revisions_execution ON oracle_canvas_page_revisions(execution_id);
|
||||
|
||||
-- Components: page-scoped, lifecycle
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_components_page ON oracle_canvas_components(page_id, lifecycle_state);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_components_tenant ON oracle_canvas_components(tenant_id);
|
||||
|
||||
-- Prompt executions: page/actor lookup
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_executions_page ON oracle_prompt_executions(page_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_executions_actor ON oracle_prompt_executions(actor_id, created_at DESC);
|
||||
|
||||
-- Templates: tenant + category + status
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_templates_tenant_cat ON oracle_component_templates(tenant_id, category, status);
|
||||
|
||||
-- Forks: source and recipient lookup
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_forks_source ON oracle_forks(source_page_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_forks_recipient ON oracle_forks(recipient_user_id);
|
||||
|
||||
-- Merge requests: target/source page, status
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_mrs_target ON oracle_merge_requests(target_page_id, status);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_mrs_source ON oracle_merge_requests(source_page_id, status);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_mrs_tenant ON oracle_merge_requests(tenant_id, status);
|
||||
|
||||
-- Lineage: source/produced lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_lineage_source ON oracle_lineage_records(source_kind, source_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_lineage_produced ON oracle_lineage_records(produced_kind, produced_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_lineage_tenant ON oracle_lineage_records(tenant_id);
|
||||
|
||||
-- Audit: entity lookup, correlation lookup
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_audit_entity ON oracle_audit_events(entity_type, entity_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_audit_correlation ON oracle_audit_events(correlation_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_oracle_audit_tenant ON oracle_audit_events(tenant_id, created_at DESC);
|
||||
Reference in New Issue
Block a user