Files
firefrost-services/services/arbiter-3.0/migrations/094_global_restart_scheduler.sql
Claude (Chronicler #61) 5e8201fd22 feat: Task #94 Global Restart Scheduler
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>
2026-04-05 09:58:52 +00:00

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;