#13 Built the complete Oracle Tab with all the functionalities. Co-authored-by: Sayan Datta <sayan@Sayans-MacBook-Air.local> Reviewed-on: #14
207 lines
10 KiB
SQL
207 lines
10 KiB
SQL
-- 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);
|