Initial import of LWLT AIBOT platform
This commit is contained in:
161
control-plane/migrations/001_initial.sql
Normal file
161
control-plane/migrations/001_initial.sql
Normal file
@@ -0,0 +1,161 @@
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version text PRIMARY KEY,
|
||||
applied_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS organizations (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
slug text NOT NULL UNIQUE,
|
||||
name text NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
username text NOT NULL,
|
||||
password_hash text NOT NULL,
|
||||
role text NOT NULL DEFAULT 'admin' CHECK (role = 'admin'),
|
||||
is_active boolean NOT NULL DEFAULT true,
|
||||
failed_login_count integer NOT NULL DEFAULT 0,
|
||||
locked_until timestamptz,
|
||||
last_login_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (organization_id, username)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
token_hash bytea NOT NULL UNIQUE,
|
||||
csrf_token_hash bytea NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
last_seen_at timestamptz NOT NULL DEFAULT now(),
|
||||
expires_at timestamptz NOT NULL,
|
||||
idle_expires_at timestamptz NOT NULL,
|
||||
revoked_at timestamptz,
|
||||
ip_address inet,
|
||||
user_agent text
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS sessions_active_idx
|
||||
ON sessions (token_hash, expires_at, idle_expires_at)
|
||||
WHERE revoked_at IS NULL;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tasks (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
task_id text NOT NULL,
|
||||
original_text_ciphertext text,
|
||||
operation_ciphertext text,
|
||||
parse_response_ciphertext text,
|
||||
execution_result_ciphertext text,
|
||||
operation jsonb,
|
||||
parse_response jsonb,
|
||||
summary jsonb,
|
||||
status text NOT NULL,
|
||||
stage text NOT NULL,
|
||||
message text,
|
||||
error text,
|
||||
handoff_status text,
|
||||
execution_result jsonb,
|
||||
created_by uuid REFERENCES users(id),
|
||||
confirmed_by uuid REFERENCES users(id),
|
||||
confirmed_at timestamptz,
|
||||
idempotency_key text,
|
||||
lease_owner text,
|
||||
lease_expires_at timestamptz,
|
||||
last_event_id bigint,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (organization_id, task_id),
|
||||
UNIQUE (organization_id, idempotency_key)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS tasks_queue_idx
|
||||
ON tasks (organization_id, status, lease_expires_at, created_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS task_events (
|
||||
id bigserial PRIMARY KEY,
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
status text NOT NULL,
|
||||
stage text NOT NULL,
|
||||
message text,
|
||||
payload jsonb,
|
||||
actor_user_id uuid REFERENCES users(id),
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS task_events_task_idx ON task_events (task_id, id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS task_attempts (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
task_id uuid NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
attempt_no integer NOT NULL,
|
||||
phase text NOT NULL,
|
||||
status text NOT NULL,
|
||||
request_hash text,
|
||||
response_hash text,
|
||||
error_code text,
|
||||
details jsonb,
|
||||
started_at timestamptz NOT NULL DEFAULT now(),
|
||||
finished_at timestamptz,
|
||||
UNIQUE (task_id, attempt_no, phase)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS idempotency_keys (
|
||||
id bigserial PRIMARY KEY,
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
scope text NOT NULL,
|
||||
idempotency_key text NOT NULL,
|
||||
request_hash text NOT NULL,
|
||||
task_id uuid REFERENCES tasks(id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
expires_at timestamptz,
|
||||
UNIQUE (organization_id, scope, idempotency_key)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_events (
|
||||
id bigserial PRIMARY KEY,
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
actor_user_id uuid REFERENCES users(id),
|
||||
event_type text NOT NULL,
|
||||
entity_type text NOT NULL,
|
||||
entity_id text,
|
||||
request_id text,
|
||||
metadata jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS audit_events_created_idx ON audit_events (organization_id, created_at DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS browser_connections (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
connection_id text NOT NULL,
|
||||
extension_version text,
|
||||
status text NOT NULL DEFAULT 'connected',
|
||||
last_seen_at timestamptz NOT NULL DEFAULT now(),
|
||||
metadata jsonb,
|
||||
UNIQUE (organization_id, connection_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS outbox_events (
|
||||
id bigserial PRIMARY KEY,
|
||||
organization_id uuid NOT NULL REFERENCES organizations(id),
|
||||
topic text NOT NULL,
|
||||
aggregate_type text NOT NULL,
|
||||
aggregate_id text NOT NULL,
|
||||
payload jsonb NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
published_at timestamptz
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS outbox_pending_idx ON outbox_events (organization_id, created_at) WHERE published_at IS NULL;
|
||||
Reference in New Issue
Block a user