Files
yakpanel-core/architecture/2026/02-core-schema.sql
2026-04-07 20:29:49 +05:30

185 lines
6.8 KiB
SQL

-- YakPanel 2026 core schema
-- PostgreSQL 15+ compatible
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "citext";
-- Shared timestamps helper convention:
-- created_at timestamptz not null default now()
-- updated_at timestamptz not null default now()
CREATE TABLE tenants (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
name varchar(150) NOT NULL,
slug citext NOT NULL UNIQUE,
status varchar(32) NOT NULL DEFAULT 'active',
plan_code varchar(64) NOT NULL DEFAULT 'starter',
settings jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE users (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
email citext NOT NULL UNIQUE,
password_hash text NOT NULL,
display_name varchar(120) NOT NULL,
is_platform_admin boolean NOT NULL DEFAULT false,
last_login_at timestamptz NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE tenant_users (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
status varchar(32) NOT NULL DEFAULT 'active',
joined_at timestamptz NOT NULL DEFAULT now(),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (tenant_id, user_id)
);
CREATE TABLE roles (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
name varchar(64) NOT NULL,
description text NOT NULL DEFAULT '',
is_system boolean NOT NULL DEFAULT false,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (tenant_id, name)
);
CREATE TABLE permissions (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
code varchar(100) NOT NULL UNIQUE,
description text NOT NULL DEFAULT '',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE role_permissions (
role_id uuid NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
permission_id uuid NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
created_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (role_id, permission_id)
);
CREATE TABLE user_roles (
tenant_user_id uuid NOT NULL REFERENCES tenant_users(id) ON DELETE CASCADE,
role_id uuid NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
created_at timestamptz NOT NULL DEFAULT now(),
PRIMARY KEY (tenant_user_id, role_id)
);
CREATE TABLE scopes (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
role_id uuid NULL REFERENCES roles(id) ON DELETE CASCADE,
resource_type varchar(64) NOT NULL,
resource_id uuid NULL,
action varchar(64) NOT NULL,
effect varchar(8) NOT NULL DEFAULT 'allow',
conditions jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE servers (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
name varchar(120) NOT NULL,
host varchar(255) NOT NULL,
port integer NOT NULL DEFAULT 443,
os_type varchar(32) NOT NULL,
status varchar(32) NOT NULL DEFAULT 'provisioning',
region varchar(64) NOT NULL DEFAULT 'global',
labels jsonb NOT NULL DEFAULT '[]'::jsonb,
heartbeat_at timestamptz NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (tenant_id, name)
);
CREATE TABLE server_agents (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
server_id uuid NOT NULL REFERENCES servers(id) ON DELETE CASCADE,
agent_uid varchar(128) NOT NULL UNIQUE,
agent_version varchar(32) NOT NULL,
capabilities jsonb NOT NULL DEFAULT '{}'::jsonb,
cert_fingerprint varchar(255) NOT NULL,
last_seen_at timestamptz NULL,
status varchar(32) NOT NULL DEFAULT 'offline',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE jobs (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
server_id uuid NULL REFERENCES servers(id) ON DELETE SET NULL,
requested_by_user_id uuid NULL REFERENCES users(id) ON DELETE SET NULL,
type varchar(64) NOT NULL,
status varchar(32) NOT NULL DEFAULT 'queued',
priority smallint NOT NULL DEFAULT 5,
idempotency_key varchar(120) NOT NULL,
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
result jsonb NULL,
started_at timestamptz NULL,
finished_at timestamptz NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (tenant_id, idempotency_key)
);
CREATE TABLE job_steps (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
job_id uuid NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
step_order integer NOT NULL,
name varchar(80) NOT NULL,
status varchar(32) NOT NULL DEFAULT 'pending',
input jsonb NOT NULL DEFAULT '{}'::jsonb,
output jsonb NULL,
error text NULL,
started_at timestamptz NULL,
finished_at timestamptz NULL,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
UNIQUE (job_id, step_order)
);
CREATE TABLE job_events (
id bigserial PRIMARY KEY,
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
job_id uuid NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
event_type varchar(64) NOT NULL,
source varchar(32) NOT NULL,
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX idx_job_events_tenant_job_created ON job_events (tenant_id, job_id, created_at DESC);
CREATE TABLE audit_logs (
id bigserial PRIMARY KEY,
tenant_id uuid NULL REFERENCES tenants(id) ON DELETE SET NULL,
actor_user_id uuid NULL REFERENCES users(id) ON DELETE SET NULL,
actor_type varchar(32) NOT NULL,
action varchar(80) NOT NULL,
resource_type varchar(64) NOT NULL,
resource_id uuid NULL,
request_id varchar(64) NULL,
ip inet NULL,
user_agent text NULL,
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX idx_audit_logs_tenant_created ON audit_logs (tenant_id, created_at DESC);
CREATE INDEX idx_scopes_tenant_action ON scopes (tenant_id, action);
CREATE INDEX idx_servers_tenant_status ON servers (tenant_id, status);
CREATE INDEX idx_jobs_tenant_status ON jobs (tenant_id, status);