mirror of
https://github.com/Dvorinka/Containr.git
synced 2026-06-03 20:12:58 +00:00
230 lines
8.8 KiB
SQL
230 lines
8.8 KiB
SQL
-- APwhy Gateway schema integration
|
|
-- Add API gateway functionality to Containr
|
|
|
|
-- Users table extension for APwhy auth system
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS password_hash TEXT;
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS enabled INTEGER NOT NULL DEFAULT 1;
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS force_password_reset INTEGER NOT NULL DEFAULT 0;
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS last_login_at TIMESTAMP;
|
|
|
|
-- Sessions table for APwhy authentication
|
|
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,
|
|
access_token_hash TEXT NOT NULL,
|
|
refresh_token_hash TEXT NOT NULL,
|
|
access_expires_at TIMESTAMP NOT NULL,
|
|
refresh_expires_at TIMESTAMP NOT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
revoked_at TIMESTAMP
|
|
);
|
|
|
|
-- Invites table for user management
|
|
CREATE TABLE IF NOT EXISTS invites (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
email TEXT NOT NULL,
|
|
token_hash TEXT NOT NULL UNIQUE,
|
|
expires_at TIMESTAMP NOT NULL,
|
|
used_at TIMESTAMP,
|
|
created_by UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Password resets table
|
|
CREATE TABLE IF NOT EXISTS password_resets (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
token_hash TEXT NOT NULL UNIQUE,
|
|
expires_at TIMESTAMP NOT NULL,
|
|
used_at TIMESTAMP,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Roles table
|
|
CREATE TABLE IF NOT EXISTS roles (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
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 TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Permissions table
|
|
CREATE TABLE IF NOT EXISTS permissions (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
code TEXT NOT NULL UNIQUE,
|
|
name TEXT NOT NULL,
|
|
description TEXT,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Role permissions junction table
|
|
CREATE TABLE IF NOT EXISTS 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 TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (role_id, permission_id)
|
|
);
|
|
|
|
-- User roles junction table
|
|
CREATE TABLE IF NOT EXISTS user_roles (
|
|
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (user_id, role_id)
|
|
);
|
|
|
|
-- API Services table
|
|
CREATE TABLE IF NOT EXISTS api_services (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
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 DEFAULT 8000,
|
|
last_validation_at TIMESTAMP,
|
|
last_validation_status TEXT,
|
|
last_validation_message TEXT,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Database connections table
|
|
CREATE TABLE IF NOT EXISTS database_connections (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
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 TIMESTAMP,
|
|
last_validation_status TEXT,
|
|
last_validation_message TEXT,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- API Keys table
|
|
CREATE TABLE IF NOT EXISTS api_keys (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
name TEXT NOT NULL,
|
|
key_hash TEXT NOT NULL UNIQUE,
|
|
key_prefix TEXT NOT NULL,
|
|
plan TEXT NOT NULL DEFAULT 'free',
|
|
allowed_service_ids TEXT NOT NULL DEFAULT '[]',
|
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
rpm_limit INTEGER DEFAULT 60,
|
|
monthly_quota INTEGER DEFAULT 1000,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
last_used_at TIMESTAMP
|
|
);
|
|
|
|
-- Usage counters table
|
|
CREATE TABLE IF NOT EXISTS usage_counters (
|
|
id SERIAL PRIMARY KEY,
|
|
api_key_id UUID NOT NULL REFERENCES api_keys(id) ON DELETE CASCADE,
|
|
service_id UUID NOT NULL REFERENCES api_services(id) ON DELETE CASCADE,
|
|
period_month TEXT NOT NULL,
|
|
request_count INTEGER NOT NULL DEFAULT 0,
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
UNIQUE(api_key_id, service_id, period_month)
|
|
);
|
|
|
|
-- Incident events table
|
|
CREATE TABLE IF NOT EXISTS incident_events (
|
|
id SERIAL PRIMARY KEY,
|
|
service_id UUID REFERENCES api_services(id) ON DELETE SET NULL,
|
|
api_key_id UUID REFERENCES api_keys(id) ON DELETE SET NULL,
|
|
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 TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Metrics timeseries table
|
|
CREATE TABLE IF NOT EXISTS metrics_timeseries (
|
|
id SERIAL PRIMARY KEY,
|
|
metric TEXT NOT NULL,
|
|
value REAL NOT NULL,
|
|
labels_json TEXT,
|
|
occurred_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Umami sync cache table
|
|
CREATE TABLE IF NOT EXISTS umami_sync_cache (
|
|
cache_key TEXT PRIMARY KEY,
|
|
payload_json TEXT NOT NULL,
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Audit log table
|
|
CREATE TABLE IF NOT EXISTS audit_log (
|
|
id SERIAL PRIMARY KEY,
|
|
actor_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
|
action TEXT NOT NULL,
|
|
target_type TEXT,
|
|
target_id TEXT,
|
|
payload_json TEXT,
|
|
occurred_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Insert default roles and permissions
|
|
INSERT INTO roles (id, name, slug, description, is_system, enabled, created_at, updated_at) VALUES
|
|
(gen_random_uuid(), 'Owner', 'owner', 'Full system access', 1, 1, NOW(), NOW()),
|
|
(gen_random_uuid(), 'Admin', 'admin', 'Administrative access', 1, 1, NOW(), NOW()),
|
|
(gen_random_uuid(), 'User', 'user', 'Basic user access', 1, 1, NOW(), NOW()),
|
|
(gen_random_uuid(), 'Viewer', 'viewer', 'Read-only access', 1, 1, NOW(), NOW())
|
|
ON CONFLICT (slug) DO NOTHING;
|
|
|
|
-- Insert default permissions
|
|
INSERT INTO permissions (id, code, name, description, created_at) VALUES
|
|
(gen_random_uuid(), 'users.read', 'Read Users', 'View user information'),
|
|
(gen_random_uuid(), 'users.write', 'Write Users', 'Create and modify users'),
|
|
(gen_random_uuid(), 'roles.read', 'Read Roles', 'View role information'),
|
|
(gen_random_uuid(), 'roles.write', 'Write Roles', 'Create and modify roles'),
|
|
(gen_random_uuid(), 'services.read', 'Read Services', 'View API services'),
|
|
(gen_random_uuid(), 'services.write', 'Write Services', 'Create and modify services'),
|
|
(gen_random_uuid(), 'databases.read', 'Read Databases', 'View database connections'),
|
|
(gen_random_uuid(), 'databases.write', 'Write Databases', 'Create and modify databases'),
|
|
(gen_random_uuid(), 'keys.read', 'Read Keys', 'View API keys'),
|
|
(gen_random_uuid(), 'keys.write', 'Write Keys', 'Create and modify API keys'),
|
|
(gen_random_uuid(), 'analytics.read', 'Read Analytics', 'View analytics data')
|
|
ON CONFLICT (code) DO NOTHING;
|
|
|
|
-- Create indexes for better performance
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_access_hash ON sessions(access_token_hash);
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_refresh_hash ON sessions(refresh_token_hash);
|
|
CREATE INDEX IF NOT EXISTS idx_sessions_expires ON sessions(access_expires_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash);
|
|
CREATE INDEX IF NOT EXISTS idx_api_keys_prefix ON api_keys(key_prefix);
|
|
CREATE INDEX IF NOT EXISTS idx_api_keys_enabled ON api_keys(enabled);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_usage_counters_key_service_month ON usage_counters(api_key_id, service_id, period_month);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_incident_events_service ON incident_events(service_id);
|
|
CREATE INDEX IF NOT EXISTS idx_incident_events_key ON incident_events(api_key_id);
|
|
CREATE INDEX IF NOT EXISTS idx_incident_events_occurred ON incident_events(occurred_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_metrics_timeseries_metric ON metrics_timeseries(metric);
|
|
CREATE INDEX IF NOT EXISTS idx_metrics_timeseries_occurred ON metrics_timeseries(occurred_at);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_audit_log_actor ON audit_log(actor_user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_audit_log_occurred ON audit_log(occurred_at);
|