-- Corrosion Platform — Initial Schema -- All tables scoped by license_id for multi-tenant isolation -- Enable UUID extension CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; ----------------------------------------------------------- -- USERS & AUTH ----------------------------------------------------------- CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), email VARCHAR(255) NOT NULL UNIQUE, username VARCHAR(50) NOT NULL UNIQUE, password_hash TEXT NOT NULL, totp_secret TEXT, totp_enabled BOOLEAN NOT NULL DEFAULT false, backup_codes TEXT[], email_verified BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), last_login_at TIMESTAMPTZ ); CREATE INDEX idx_users_email ON users(email); ----------------------------------------------------------- -- LICENSES ----------------------------------------------------------- CREATE TABLE licenses ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_key VARCHAR(64) NOT NULL UNIQUE, status VARCHAR(20) NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'suspended', 'expired', 'revoked')), owner_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, server_name VARCHAR(100), subdomain VARCHAR(63) UNIQUE, custom_domain VARCHAR(255) UNIQUE, modules_enabled TEXT[] DEFAULT '{}', webstore_active BOOLEAN NOT NULL DEFAULT false, webstore_subscription_id VARCHAR(100), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), expires_at TIMESTAMPTZ ); CREATE INDEX idx_licenses_key ON licenses(license_key); CREATE INDEX idx_licenses_owner ON licenses(owner_user_id); CREATE INDEX idx_licenses_subdomain ON licenses(subdomain); ----------------------------------------------------------- -- TEAM & RBAC ----------------------------------------------------------- CREATE TABLE roles ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID REFERENCES licenses(id) ON DELETE CASCADE, role_name VARCHAR(50) NOT NULL, is_system_default BOOLEAN NOT NULL DEFAULT false, is_cloned_from UUID REFERENCES roles(id) ON DELETE SET NULL, permissions JSONB NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_roles_license ON roles(license_id); CREATE TABLE team_members ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, role_id UUID NOT NULL REFERENCES roles(id) ON DELETE RESTRICT, invited_by UUID NOT NULL REFERENCES users(id), accepted_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(license_id, user_id) ); CREATE INDEX idx_team_license ON team_members(license_id); CREATE INDEX idx_team_user ON team_members(user_id); ----------------------------------------------------------- -- SERVER CONNECTION & CONFIG ----------------------------------------------------------- CREATE TABLE server_connections ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE, connection_type VARCHAR(20) NOT NULL CHECK (connection_type IN ('amp', 'pterodactyl', 'bare_metal')), panel_api_endpoint TEXT, panel_api_key_encrypted TEXT, panel_server_identifier VARCHAR(255), companion_agent_token VARCHAR(128), companion_last_seen TIMESTAMPTZ, plugin_last_seen TIMESTAMPTZ, server_ip VARCHAR(45), server_port INTEGER, game_port INTEGER, connection_status VARCHAR(20) NOT NULL DEFAULT 'offline' CHECK (connection_status IN ('connected', 'degraded', 'offline')), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_server_conn_license ON server_connections(license_id); CREATE TABLE server_config ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE, server_name VARCHAR(255) NOT NULL DEFAULT '', max_players INTEGER, world_size INTEGER, current_seed INTEGER, current_map_id UUID, server_description TEXT, server_url TEXT, server_header_image TEXT, tags TEXT[] DEFAULT '{}', auto_restart_enabled BOOLEAN NOT NULL DEFAULT false, auto_restart_cron VARCHAR(100), auto_restart_timezone VARCHAR(50), crash_recovery_enabled BOOLEAN NOT NULL DEFAULT true, crash_recovery_max_attempts INTEGER NOT NULL DEFAULT 3, crash_recovery_cooldown_minutes INTEGER NOT NULL DEFAULT 10, force_wipe_eligible BOOLEAN NOT NULL DEFAULT true, auto_update_on_force_wipe BOOLEAN NOT NULL DEFAULT true, config_overrides JSONB DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_server_config_license ON server_config(license_id); ----------------------------------------------------------- -- GAME ADMINS (in-game SteamID-based) ----------------------------------------------------------- CREATE TABLE game_admins ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, steam_id VARCHAR(20) NOT NULL, display_name VARCHAR(100) NOT NULL DEFAULT '', admin_level VARCHAR(20) NOT NULL DEFAULT 'admin' CHECK (admin_level IN ('owner', 'admin', 'moderator')), permissions JSONB DEFAULT '{}', added_by UUID NOT NULL REFERENCES users(id), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(license_id, steam_id) ); CREATE INDEX idx_game_admins_license ON game_admins(license_id); ----------------------------------------------------------- -- WIPE PROFILES & SCHEDULES ----------------------------------------------------------- CREATE TABLE wipe_profiles ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, profile_name VARCHAR(100) NOT NULL, description TEXT, pre_wipe_config JSONB NOT NULL DEFAULT '{ "enabled": true, "backup_before_wipe": true, "countdown_warnings": [30, 15, 5, 1], "countdown_unit": "minutes", "countdown_messages": {}, "kick_players_before_wipe": true, "kick_message": "Server is wiping. Be back shortly!", "run_final_save": true, "discord_pre_announce": true, "pushbullet_notify": false, "custom_commands_before": [] }', post_wipe_config JSONB NOT NULL DEFAULT '{ "enabled": true, "verify_server_started": true, "verify_correct_map": true, "verify_plugins_loaded": true, "verify_player_slots_open": true, "max_restart_attempts": 3, "health_check_timeout_seconds": 120, "discord_post_announce": true, "pushbullet_notify": false, "rollback_on_failure": true, "post_wipe_commands": [] }', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_wipe_profiles_license ON wipe_profiles(license_id); CREATE TABLE wipe_schedules ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, wipe_profile_id UUID NOT NULL REFERENCES wipe_profiles(id) ON DELETE CASCADE, schedule_name VARCHAR(100) NOT NULL, wipe_type VARCHAR(20) NOT NULL CHECK (wipe_type IN ('map', 'blueprint', 'full')), cron_expression VARCHAR(100) NOT NULL, timezone VARCHAR(50) NOT NULL DEFAULT 'America/New_York', wipe_blueprints BOOLEAN NOT NULL DEFAULT false, is_active BOOLEAN NOT NULL DEFAULT true, next_scheduled_run TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_wipe_schedules_license ON wipe_schedules(license_id); CREATE INDEX idx_wipe_schedules_next_run ON wipe_schedules(next_scheduled_run) WHERE is_active = true; ----------------------------------------------------------- -- MAP LIBRARY & ROTATION ----------------------------------------------------------- CREATE TABLE map_library ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, filename VARCHAR(255) NOT NULL, display_name VARCHAR(255) NOT NULL, storage_path TEXT NOT NULL, file_size_bytes BIGINT NOT NULL DEFAULT 0, map_type VARCHAR(20) NOT NULL DEFAULT 'custom' CHECK (map_type IN ('custom', 'procedural')), seed INTEGER, world_size INTEGER, thumbnail_path TEXT, checksum VARCHAR(64) NOT NULL, uploaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_map_library_license ON map_library(license_id); -- FK for server_config.current_map_id (deferred because map_library created after server_config) ALTER TABLE server_config ADD CONSTRAINT fk_server_config_map FOREIGN KEY (current_map_id) REFERENCES map_library(id) ON DELETE SET NULL; CREATE TABLE map_rotations ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, map_id UUID NOT NULL REFERENCES map_library(id) ON DELETE CASCADE, rotation_order INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT true, UNIQUE(license_id, rotation_order) ); CREATE INDEX idx_map_rotations_license ON map_rotations(license_id); ----------------------------------------------------------- -- PLUGIN REGISTRY ----------------------------------------------------------- CREATE TABLE plugin_registry ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, plugin_name VARCHAR(255) NOT NULL, plugin_version VARCHAR(50), source VARCHAR(20) NOT NULL DEFAULT 'manual' CHECK (source IN ('umod', 'corrosion_module', 'manual')), umod_slug VARCHAR(255), is_installed BOOLEAN NOT NULL DEFAULT false, is_loaded BOOLEAN NOT NULL DEFAULT false, config_json JSONB, data_path TEXT, wipe_on_map BOOLEAN NOT NULL DEFAULT false, wipe_on_bp BOOLEAN NOT NULL DEFAULT false, wipe_on_full BOOLEAN NOT NULL DEFAULT false, never_wipe BOOLEAN NOT NULL DEFAULT false, installed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(license_id, plugin_name) ); CREATE INDEX idx_plugin_registry_license ON plugin_registry(license_id); ----------------------------------------------------------- -- WIPE HISTORY ----------------------------------------------------------- CREATE TABLE wipe_history ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, wipe_schedule_id UUID REFERENCES wipe_schedules(id) ON DELETE SET NULL, wipe_profile_id UUID NOT NULL REFERENCES wipe_profiles(id), wipe_type VARCHAR(20) NOT NULL, trigger_type VARCHAR(20) NOT NULL CHECK (trigger_type IN ('scheduled', 'manual', 'force_wipe')), status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'pre_wipe', 'wiping', 'post_wipe', 'success', 'failed', 'rolled_back')), started_at TIMESTAMPTZ, completed_at TIMESTAMPTZ, map_used VARCHAR(255), plugins_wiped TEXT[], plugins_preserved TEXT[], backup_reference TEXT, error_message TEXT, execution_log JSONB DEFAULT '[]', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_wipe_history_license ON wipe_history(license_id); CREATE INDEX idx_wipe_history_created ON wipe_history(created_at DESC); ----------------------------------------------------------- -- SCHEDULED TASKS (restarts, announcements, etc.) ----------------------------------------------------------- CREATE TABLE scheduled_tasks ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, task_type VARCHAR(30) NOT NULL CHECK (task_type IN ('restart', 'announcement', 'command', 'plugin_reload')), task_name VARCHAR(100) NOT NULL, cron_expression VARCHAR(100) NOT NULL, timezone VARCHAR(50) NOT NULL DEFAULT 'America/New_York', task_config JSONB NOT NULL DEFAULT '{}', is_active BOOLEAN NOT NULL DEFAULT true, next_run TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_scheduled_tasks_license ON scheduled_tasks(license_id); ----------------------------------------------------------- -- NOTIFICATIONS ----------------------------------------------------------- CREATE TABLE notifications_config ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE, discord_webhook_url TEXT, discord_enabled BOOLEAN NOT NULL DEFAULT false, pushbullet_api_key TEXT, pushbullet_enabled BOOLEAN NOT NULL DEFAULT false, email_alerts_enabled BOOLEAN NOT NULL DEFAULT true, notify_wipe_start BOOLEAN NOT NULL DEFAULT true, notify_wipe_complete BOOLEAN NOT NULL DEFAULT true, notify_wipe_failed BOOLEAN NOT NULL DEFAULT true, notify_server_crash BOOLEAN NOT NULL DEFAULT true, notify_server_offline BOOLEAN NOT NULL DEFAULT true, notify_store_purchase BOOLEAN NOT NULL DEFAULT true, notify_player_report BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); ----------------------------------------------------------- -- CHAT LOGS & PLAYER ACTIONS ----------------------------------------------------------- CREATE TABLE chat_logs ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, steam_id VARCHAR(20) NOT NULL, player_name VARCHAR(100) NOT NULL, channel VARCHAR(20) NOT NULL DEFAULT 'global' CHECK (channel IN ('global', 'team', 'server')), message TEXT NOT NULL, flagged BOOLEAN NOT NULL DEFAULT false, flagged_by UUID REFERENCES users(id), flag_reason TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_chat_logs_license ON chat_logs(license_id); CREATE INDEX idx_chat_logs_created ON chat_logs(created_at DESC); CREATE INDEX idx_chat_logs_steam ON chat_logs(license_id, steam_id); CREATE TABLE player_actions ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, steam_id VARCHAR(20) NOT NULL, player_name VARCHAR(100) NOT NULL, action_type VARCHAR(20) NOT NULL CHECK (action_type IN ('kick', 'ban', 'unban', 'warn', 'note')), reason TEXT, duration_minutes INTEGER, performed_by UUID NOT NULL REFERENCES users(id), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_player_actions_license ON player_actions(license_id); CREATE INDEX idx_player_actions_steam ON player_actions(license_id, steam_id); ----------------------------------------------------------- -- SERVER STATS (time-series) ----------------------------------------------------------- CREATE TABLE server_stats ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, player_count INTEGER NOT NULL DEFAULT 0, max_players INTEGER NOT NULL DEFAULT 0, fps DOUBLE PRECISION NOT NULL DEFAULT 0, entity_count INTEGER NOT NULL DEFAULT 0, uptime_seconds INTEGER NOT NULL DEFAULT 0, memory_usage_mb INTEGER NOT NULL DEFAULT 0, recorded_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_server_stats_license_time ON server_stats(license_id, recorded_at DESC); CREATE TABLE server_stats_hourly ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, hour TIMESTAMPTZ NOT NULL, avg_players DOUBLE PRECISION NOT NULL DEFAULT 0, max_players INTEGER NOT NULL DEFAULT 0, avg_fps DOUBLE PRECISION NOT NULL DEFAULT 0, min_fps DOUBLE PRECISION NOT NULL DEFAULT 0, avg_entities INTEGER NOT NULL DEFAULT 0, uptime_percentage DOUBLE PRECISION NOT NULL DEFAULT 0, UNIQUE(license_id, hour) ); CREATE INDEX idx_stats_hourly_license ON server_stats_hourly(license_id, hour DESC); ----------------------------------------------------------- -- PUBLIC SITE CONFIG ----------------------------------------------------------- CREATE TABLE public_site_config ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE, site_enabled BOOLEAN NOT NULL DEFAULT true, show_on_status_page BOOLEAN NOT NULL DEFAULT false, steam_connect_url VARCHAR(255), motd TEXT, public_mods TEXT[] DEFAULT '{}', header_image_url TEXT, theme_color VARCHAR(7) DEFAULT '#ef4444', custom_css TEXT, discord_invite_url TEXT, show_player_count BOOLEAN NOT NULL DEFAULT true, show_wipe_schedule BOOLEAN NOT NULL DEFAULT true, show_wipe_countdown BOOLEAN NOT NULL DEFAULT true, show_mod_list BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); ----------------------------------------------------------- -- WEBSTORE ----------------------------------------------------------- CREATE TABLE webstore_config ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL UNIQUE REFERENCES licenses(id) ON DELETE CASCADE, is_active BOOLEAN NOT NULL DEFAULT false, paypal_client_id TEXT, paypal_secret TEXT, paypal_mode VARCHAR(10) NOT NULL DEFAULT 'sandbox' CHECK (paypal_mode IN ('sandbox', 'live')), store_name VARCHAR(100), store_description TEXT, currency VARCHAR(3) NOT NULL DEFAULT 'USD', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE webstore_categories ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, category_name VARCHAR(100) NOT NULL, display_order INTEGER NOT NULL DEFAULT 0, is_active BOOLEAN NOT NULL DEFAULT true ); CREATE INDEX idx_webstore_cats_license ON webstore_categories(license_id); CREATE TABLE webstore_items ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, category_id UUID NOT NULL REFERENCES webstore_categories(id) ON DELETE CASCADE, item_name VARCHAR(100) NOT NULL, description TEXT, price DECIMAL(10,2) NOT NULL, image_url TEXT, item_type VARCHAR(20) NOT NULL DEFAULT 'kit' CHECK (item_type IN ('kit', 'rank', 'currency', 'custom_command')), delivery_config JSONB NOT NULL DEFAULT '{"commands": []}', is_active BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_webstore_items_license ON webstore_items(license_id); CREATE INDEX idx_webstore_items_category ON webstore_items(category_id); CREATE TABLE webstore_transactions ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, item_id UUID NOT NULL REFERENCES webstore_items(id), buyer_steam_id VARCHAR(20) NOT NULL, buyer_name VARCHAR(100), amount DECIMAL(10,2) NOT NULL, currency VARCHAR(3) NOT NULL DEFAULT 'USD', paypal_transaction_id VARCHAR(100), status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'paid', 'delivered', 'failed', 'refunded')), delivered_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_webstore_txn_license ON webstore_transactions(license_id); CREATE INDEX idx_webstore_txn_status ON webstore_transactions(license_id, status); ----------------------------------------------------------- -- MIGRATION EXPORTS ----------------------------------------------------------- CREATE TABLE migration_exports ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, export_type VARCHAR(20) NOT NULL DEFAULT 'full' CHECK (export_type IN ('full', 'config_only', 'store_only')), storage_path TEXT NOT NULL, file_size_bytes BIGINT NOT NULL DEFAULT 0, created_by UUID NOT NULL REFERENCES users(id), expires_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); ----------------------------------------------------------- -- PLATFORM CHANGELOG ----------------------------------------------------------- CREATE TABLE platform_changelog ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), version VARCHAR(20) NOT NULL, title VARCHAR(200) NOT NULL, body TEXT NOT NULL, category VARCHAR(20) NOT NULL DEFAULT 'feature' CHECK (category IN ('feature', 'bugfix', 'module', 'security')), published_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); ----------------------------------------------------------- -- MODULE STORE ----------------------------------------------------------- CREATE TABLE module_store ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), module_slug VARCHAR(50) NOT NULL UNIQUE, module_name VARCHAR(100) NOT NULL, description TEXT, long_description TEXT, price DECIMAL(10,2) NOT NULL DEFAULT 0, price_type VARCHAR(20) NOT NULL DEFAULT 'one_time' CHECK (price_type IN ('one_time', 'monthly')), monthly_price DECIMAL(10,2), version VARCHAR(20) NOT NULL DEFAULT '1.0.0', download_path TEXT, thumbnail_url TEXT, screenshots TEXT[] DEFAULT '{}', category VARCHAR(50), is_active BOOLEAN NOT NULL DEFAULT true, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); ----------------------------------------------------------- -- DEFAULT SYSTEM ROLES ----------------------------------------------------------- INSERT INTO roles (id, license_id, role_name, is_system_default, permissions) VALUES (uuid_generate_v4(), NULL, 'Owner', true, '{ "server.*": true, "wipe.*": true, "plugins.*": true, "players.*": true, "team.*": true, "billing.*": true, "store.*": true, "settings.*": true, "public_site.*": true }'), (uuid_generate_v4(), NULL, 'Head Admin', true, '{ "server.*": true, "wipe.*": true, "plugins.*": true, "players.*": true, "team.view": true, "team.invite": true, "store.*": true, "settings.server": true, "public_site.*": true }'), (uuid_generate_v4(), NULL, 'Moderator', true, '{ "server.view": true, "server.console": true, "players.kick": true, "players.ban": true, "players.chat_log": true, "wipe.view": true, "store.view": true }'), (uuid_generate_v4(), NULL, 'Viewer', true, '{ "server.view": true, "players.view": true, "wipe.view": true, "store.view": true }');