Files
Tomas Dvorak 355a97bab4 overhaul
2026-04-14 18:04:48 +02:00

195 lines
5.3 KiB
Go

package storage
const schemaSQL = `
PRAGMA journal_mode = WAL;
PRAGMA foreign_keys = ON;
CREATE TABLE IF NOT EXISTS users (
id TEXT PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
force_password_reset INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
last_login_at TEXT
);
CREATE TABLE IF NOT EXISTS sessions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
access_token_hash TEXT NOT NULL,
refresh_token_hash TEXT NOT NULL,
access_expires_at TEXT NOT NULL,
refresh_expires_at TEXT NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
revoked_at TEXT,
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS idx_sessions_access ON sessions(access_token_hash);
CREATE INDEX IF NOT EXISTS idx_sessions_refresh ON sessions(refresh_token_hash);
CREATE TABLE IF NOT EXISTS invites (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
email TEXT NOT NULL,
token_hash TEXT NOT NULL UNIQUE,
expires_at TEXT NOT NULL,
used_at TEXT,
created_by TEXT,
created_at TEXT NOT NULL,
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY(created_by) REFERENCES users(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS password_resets (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
token_hash TEXT NOT NULL UNIQUE,
expires_at TEXT NOT NULL,
used_at TEXT,
created_at TEXT NOT NULL,
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS roles (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
description TEXT,
is_system INTEGER NOT NULL DEFAULT 0,
enabled INTEGER NOT NULL DEFAULT 1,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS permissions (
id TEXT PRIMARY KEY,
code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
description TEXT,
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS role_permissions (
role_id TEXT NOT NULL,
permission_id TEXT NOT NULL,
created_at TEXT NOT NULL,
PRIMARY KEY(role_id, permission_id),
FOREIGN KEY(role_id) REFERENCES roles(id) ON DELETE CASCADE,
FOREIGN KEY(permission_id) REFERENCES permissions(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS user_roles (
user_id TEXT NOT NULL,
role_id TEXT NOT NULL,
created_at TEXT NOT NULL,
PRIMARY KEY(user_id, role_id),
FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY(role_id) REFERENCES roles(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS services (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
upstream_url TEXT NOT NULL,
route_prefix TEXT NOT NULL UNIQUE,
health_path TEXT NOT NULL DEFAULT '/health',
upstream_auth_header TEXT,
upstream_auth_value TEXT,
internal_token TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
rpm_limit INTEGER,
monthly_quota INTEGER,
request_timeout_ms INTEGER,
last_validation_at TEXT,
last_validation_status TEXT,
last_validation_message TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS database_connections (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
provider TEXT NOT NULL,
connection_url TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
last_validation_at TEXT,
last_validation_status TEXT,
last_validation_message TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS api_keys (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
key_hash TEXT NOT NULL UNIQUE,
key_prefix TEXT NOT NULL,
plan TEXT NOT NULL,
allowed_service_ids TEXT NOT NULL DEFAULT '[]',
enabled INTEGER NOT NULL DEFAULT 1,
rpm_limit INTEGER,
monthly_quota INTEGER,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
last_used_at TEXT
);
CREATE TABLE IF NOT EXISTS usage_counters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
api_key_id TEXT NOT NULL,
service_id TEXT NOT NULL,
period_month TEXT NOT NULL,
request_count INTEGER NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL,
UNIQUE(api_key_id, service_id, period_month),
FOREIGN KEY(api_key_id) REFERENCES api_keys(id) ON DELETE CASCADE,
FOREIGN KEY(service_id) REFERENCES services(id) ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS incident_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
service_id TEXT,
api_key_id TEXT,
code TEXT NOT NULL,
message TEXT NOT NULL,
severity TEXT NOT NULL DEFAULT 'medium',
http_status INTEGER,
count INTEGER NOT NULL DEFAULT 1,
occurred_at TEXT NOT NULL,
FOREIGN KEY(api_key_id) REFERENCES api_keys(id) ON DELETE SET NULL,
FOREIGN KEY(service_id) REFERENCES services(id) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS metrics_timeseries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
metric TEXT NOT NULL,
value REAL NOT NULL,
labels_json TEXT,
occurred_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_metrics_metric_time ON metrics_timeseries(metric, occurred_at DESC);
CREATE TABLE IF NOT EXISTS umami_sync_cache (
cache_key TEXT PRIMARY KEY,
payload_json TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS audit_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
actor_user_id TEXT,
action TEXT NOT NULL,
target_type TEXT,
target_id TEXT,
payload_json TEXT,
occurred_at TEXT NOT NULL,
FOREIGN KEY(actor_user_id) REFERENCES users(id) ON DELETE SET NULL
);
`