Complete implementation of staggered restart scheduler for Trinity Console. Database: - global_restart_config: Node-wide settings (TX1 @ 04:00 UTC, NC1 @ 04:30 UTC) - server_restart_schedules: Per-server state with sort order - sync_logs: Audit trail for all sync operations Backend: - src/utils/scheduler.js: Stagger calculation with date-fns - src/lib/ptero-sync.js: Pterodactyl API integration (create/update/delete/audit) - src/routes/admin/scheduler.js: All CRUD + import + sync + audit routes Frontend: - Drag-and-drop server ordering (SortableJS) - Per-node config cards with base time + interval - Audit modal to detect and nuke rogue schedules - Skip toggle for maintenance mode - Visual sync status indicators Features: - Import servers from Pterodactyl discovery - Recalculate effective times on reorder - Rate-limited API calls (200ms delay) - [Trinity] Daily Restart naming convention Signed-off-by: Claude (Chronicler #61) <claude@firefrostgaming.com>
58 lines
2.5 KiB
SQL
58 lines
2.5 KiB
SQL
-- Task #94: Global Restart Scheduler
|
|
-- Migration for arbiter_db
|
|
-- Run: psql -U arbiter -d arbiter_db -f 094_global_restart_scheduler.sql
|
|
|
|
-- 1. Configuration for Node-wide Stagger Logic
|
|
CREATE TABLE IF NOT EXISTS global_restart_config (
|
|
id SERIAL PRIMARY KEY,
|
|
node VARCHAR(10) UNIQUE NOT NULL, -- 'TX1', 'NC1'
|
|
base_time TIME NOT NULL, -- e.g., '04:00:00' (UTC)
|
|
interval_minutes INT DEFAULT 5, -- Stagger gap
|
|
is_enabled BOOLEAN DEFAULT true, -- Global master switch per node
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_by VARCHAR(50) -- Discord Username
|
|
);
|
|
|
|
-- 2. Individual Server Execution State
|
|
CREATE TABLE IF NOT EXISTS server_restart_schedules (
|
|
id SERIAL PRIMARY KEY,
|
|
server_id VARCHAR(50) UNIQUE NOT NULL, -- Pterodactyl 8-char short ID
|
|
server_name VARCHAR(100) NOT NULL,
|
|
node VARCHAR(10) NOT NULL,
|
|
sort_order INT NOT NULL DEFAULT 0, -- Manual boot order
|
|
effective_time TIME, -- Calculated: base + (sort * interval)
|
|
ptero_schedule_id INT DEFAULT NULL, -- ID of schedule on Pterodactyl
|
|
skip_restart BOOLEAN DEFAULT false, -- Individual "Maintenance Mode"
|
|
sync_status VARCHAR(20) DEFAULT 'PENDING', -- 'SUCCESS', 'PENDING', 'FAILED'
|
|
last_error TEXT DEFAULT NULL, -- API error capture
|
|
last_synced_at TIMESTAMP NULL,
|
|
|
|
CONSTRAINT fk_node_config
|
|
FOREIGN KEY (node)
|
|
REFERENCES global_restart_config(node)
|
|
ON UPDATE CASCADE
|
|
);
|
|
|
|
-- 3. Audit Trail for Sync Operations
|
|
CREATE TABLE IF NOT EXISTS sync_logs (
|
|
id SERIAL PRIMARY KEY,
|
|
server_id VARCHAR(50) NOT NULL,
|
|
action VARCHAR(255) NOT NULL, -- e.g., 'Deleted Rogue Schedule', 'Created Schedule'
|
|
status VARCHAR(20) NOT NULL, -- 'SUCCESS', 'FAILED'
|
|
error_message TEXT DEFAULT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- 4. Performance Indexes
|
|
CREATE INDEX IF NOT EXISTS idx_server_node_order ON server_restart_schedules (node, sort_order);
|
|
CREATE INDEX IF NOT EXISTS idx_sync_status ON server_restart_schedules (sync_status);
|
|
CREATE INDEX IF NOT EXISTS idx_sync_logs_server ON sync_logs (server_id);
|
|
CREATE INDEX IF NOT EXISTS idx_sync_logs_created ON sync_logs (created_at);
|
|
|
|
-- 5. Initial Seed Data
|
|
INSERT INTO global_restart_config (node, base_time, interval_minutes, updated_by)
|
|
VALUES
|
|
('TX1', '04:00:00', 5, 'The Wizard'),
|
|
('NC1', '04:30:00', 5, 'The Wizard')
|
|
ON CONFLICT (node) DO NOTHING;
|