167 lines
5.4 KiB
SQL
167 lines
5.4 KiB
SQL
-- Extended V1 domain tables. Secrets are referenced by encrypted_ref only;
|
|
-- user files live in staging/object adapters and never in static directories.
|
|
CREATE TABLE IF NOT EXISTS balance_units (
|
|
id TEXT PRIMARY KEY,
|
|
version INTEGER NOT NULL,
|
|
name TEXT NOT NULL,
|
|
short_code TEXT NOT NULL,
|
|
icon TEXT NOT NULL,
|
|
precision INTEGER NOT NULL DEFAULT 0,
|
|
currency_code TEXT NOT NULL,
|
|
conversion_rate NUMERIC(24, 8) NOT NULL,
|
|
rounding TEXT NOT NULL,
|
|
published_at TIMESTAMPTZ
|
|
);
|
|
CREATE TABLE IF NOT EXISTS balance_buckets (
|
|
id UUID PRIMARY KEY,
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
source TEXT NOT NULL,
|
|
remaining NUMERIC(24, 6) NOT NULL CHECK (remaining >= 0),
|
|
priority INTEGER NOT NULL DEFAULT 0,
|
|
expires_at TIMESTAMPTZ
|
|
);
|
|
CREATE TABLE IF NOT EXISTS membership_plans (
|
|
id TEXT PRIMARY KEY,
|
|
code TEXT NOT NULL UNIQUE,
|
|
version INTEGER NOT NULL DEFAULT 1,
|
|
snapshot JSONB NOT NULL,
|
|
published BOOLEAN NOT NULL DEFAULT false
|
|
);
|
|
CREATE TABLE IF NOT EXISTS user_plan_entitlements (
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
plan_id TEXT NOT NULL REFERENCES membership_plans(id),
|
|
version INTEGER NOT NULL,
|
|
starts_at TIMESTAMPTZ NOT NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
PRIMARY KEY (user_id, plan_id, version)
|
|
);
|
|
CREATE TABLE IF NOT EXISTS recharge_orders (
|
|
id UUID PRIMARY KEY,
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
provider TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
fiat_amount NUMERIC(24, 6) NOT NULL,
|
|
balance_amount NUMERIC(24, 6) NOT NULL,
|
|
unit_version INTEGER NOT NULL,
|
|
idempotency_key TEXT NOT NULL UNIQUE,
|
|
provider_order_id TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
paid_at TIMESTAMPTZ
|
|
);
|
|
CREATE TABLE IF NOT EXISTS payment_events (
|
|
id UUID PRIMARY KEY,
|
|
provider TEXT NOT NULL,
|
|
provider_event_id TEXT NOT NULL,
|
|
order_id UUID REFERENCES recharge_orders(id),
|
|
payload_digest TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE(provider, provider_event_id)
|
|
);
|
|
CREATE TABLE IF NOT EXISTS generation_outputs (
|
|
id UUID PRIMARY KEY,
|
|
task_id UUID NOT NULL REFERENCES generation_tasks(id),
|
|
owner_id UUID NOT NULL REFERENCES users(id),
|
|
object_key TEXT NOT NULL,
|
|
mime_type TEXT NOT NULL,
|
|
status TEXT NOT NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
revoked_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS upload_objects (
|
|
id UUID PRIMARY KEY,
|
|
owner_id UUID NOT NULL REFERENCES users(id),
|
|
object_key TEXT NOT NULL,
|
|
mime_type TEXT NOT NULL,
|
|
byte_size BIGINT NOT NULL,
|
|
checksum TEXT NOT NULL,
|
|
scan_status TEXT NOT NULL,
|
|
expires_at TIMESTAMPTZ NOT NULL,
|
|
deleted_at TIMESTAMPTZ
|
|
);
|
|
CREATE TABLE IF NOT EXISTS assets (
|
|
id UUID PRIMARY KEY,
|
|
owner_id UUID NOT NULL REFERENCES users(id),
|
|
task_id UUID REFERENCES generation_tasks(id),
|
|
object_id UUID REFERENCES upload_objects(id),
|
|
asset_type TEXT NOT NULL,
|
|
snapshot JSONB NOT NULL,
|
|
deleted_at TIMESTAMPTZ,
|
|
retention_expires_at TIMESTAMPTZ
|
|
);
|
|
CREATE TABLE IF NOT EXISTS email_sms_outbox (
|
|
id UUID PRIMARY KEY,
|
|
target_hash TEXT NOT NULL,
|
|
channel TEXT NOT NULL,
|
|
purpose TEXT NOT NULL,
|
|
payload JSONB NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
attempts INTEGER NOT NULL DEFAULT 0,
|
|
next_attempt_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
CREATE TABLE IF NOT EXISTS webdav_configs (
|
|
user_id UUID PRIMARY KEY REFERENCES users(id),
|
|
encrypted_url_ref TEXT NOT NULL,
|
|
encrypted_username_ref TEXT,
|
|
encrypted_password_ref TEXT,
|
|
directory TEXT NOT NULL,
|
|
state TEXT NOT NULL,
|
|
last_synced_at TIMESTAMPTZ,
|
|
retention_days INTEGER NOT NULL DEFAULT 30
|
|
);
|
|
CREATE TABLE IF NOT EXISTS webdav_manifests (
|
|
id UUID PRIMARY KEY,
|
|
user_id UUID NOT NULL REFERENCES users(id),
|
|
version BIGINT NOT NULL,
|
|
checksum TEXT NOT NULL,
|
|
manifest JSONB NOT NULL,
|
|
state TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
UNIQUE(user_id, version)
|
|
);
|
|
CREATE TABLE IF NOT EXISTS storage_policies (
|
|
id TEXT PRIMARY KEY,
|
|
version INTEGER NOT NULL,
|
|
snapshot JSONB NOT NULL,
|
|
published BOOLEAN NOT NULL DEFAULT false
|
|
);
|
|
CREATE TABLE IF NOT EXISTS admin_roles (
|
|
id TEXT PRIMARY KEY,
|
|
permissions JSONB NOT NULL,
|
|
enabled BOOLEAN NOT NULL DEFAULT true
|
|
);
|
|
CREATE TABLE IF NOT EXISTS admin_user_roles (
|
|
admin_id UUID NOT NULL,
|
|
role_id TEXT NOT NULL REFERENCES admin_roles(id),
|
|
PRIMARY KEY (admin_id, role_id)
|
|
);
|
|
CREATE TABLE IF NOT EXISTS admin_approvals (
|
|
id UUID PRIMARY KEY,
|
|
requester_id UUID NOT NULL,
|
|
approver_id UUID,
|
|
action TEXT NOT NULL,
|
|
object_type TEXT NOT NULL,
|
|
object_id TEXT,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
before_value JSONB,
|
|
after_value JSONB,
|
|
expires_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
approved_at TIMESTAMPTZ
|
|
);
|
|
CREATE TABLE IF NOT EXISTS task_event_log (
|
|
task_id UUID NOT NULL REFERENCES generation_tasks(id),
|
|
sequence BIGINT NOT NULL,
|
|
event_id UUID NOT NULL UNIQUE,
|
|
event_type TEXT NOT NULL,
|
|
payload JSONB NOT NULL,
|
|
occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (task_id, sequence)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS upload_objects_owner_idx ON upload_objects(owner_id, expires_at);
|
|
CREATE INDEX IF NOT EXISTS generation_outputs_owner_idx ON generation_outputs(owner_id, expires_at);
|
|
CREATE INDEX IF NOT EXISTS recharge_orders_user_created_idx ON recharge_orders(user_id, created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS task_event_log_task_sequence_idx ON task_event_log(task_id, sequence);
|