186 lines
9.5 KiB
SQL
186 lines
9.5 KiB
SQL
-- Electric Cherry schema. Idempotent — safe to run at every boot via migrate.ts.
|
|
-- The old betas/beta_scripts/beta_deploys tables are dropped in-code before this
|
|
-- runs (see dropLegacyBetaTables in db/index.ts); the new script-centric model
|
|
-- lives here.
|
|
|
|
PRAGMA journal_mode = WAL;
|
|
PRAGMA foreign_keys = ON;
|
|
|
|
CREATE TABLE IF NOT EXISTS servers (
|
|
name TEXT PRIMARY KEY,
|
|
komodo_type TEXT NOT NULL DEFAULT 'deployment', -- deployment|stack|container
|
|
komodo_name TEXT NOT NULL,
|
|
komodo_server TEXT,
|
|
game_port INTEGER, -- UDP RCON port; lazy-filled from Komodo
|
|
rcon_host TEXT, -- optional per-server override of RCON_HOST
|
|
game TEXT, -- 't5' etc.; static per-server (no map rotation)
|
|
map TEXT, -- 'zombie_theater' etc.; static per-server
|
|
last_players INTEGER,
|
|
last_checked_at TEXT,
|
|
last_map TEXT, -- from RCON getstatus mapname
|
|
last_gametype TEXT, -- from RCON getstatus g_gametype
|
|
last_roster TEXT, -- JSON array of RconPlayer
|
|
last_seen_at TEXT, -- ISO ts of last successful RCON reply
|
|
last_error TEXT, -- last RCON failure reason (cleared on success)
|
|
last_reply_snippet TEXT, -- hex+ASCII of last bad-reply UDP payload
|
|
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
|
);
|
|
|
|
-- One row per script (a logical thing, e.g. "HUD tweaks"). Name is unique and
|
|
-- doubles as the slug in URLs.
|
|
CREATE TABLE IF NOT EXISTS scripts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL UNIQUE,
|
|
target_rel_path TEXT NOT NULL, -- 'maps/mp_kino/hud.gsc' or 'hud.gsc'
|
|
scope_type TEXT, -- NULL | 'game' | 'map'
|
|
scope_value TEXT, -- NULL | 't5' | 'zombie_theater'
|
|
current_version_id INTEGER, -- FK → script_versions(id) after first promote
|
|
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_scripts_scope ON scripts(scope_type, scope_value);
|
|
|
|
CREATE TABLE IF NOT EXISTS script_versions (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
script_id INTEGER NOT NULL REFERENCES scripts(id) ON DELETE CASCADE,
|
|
version INTEGER NOT NULL,
|
|
sha256 TEXT NOT NULL,
|
|
size INTEGER NOT NULL,
|
|
content BLOB NOT NULL,
|
|
notes TEXT,
|
|
state TEXT NOT NULL DEFAULT 'untested', -- 'untested' | 'tested' | 'test-failed'
|
|
uploaded_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
|
UNIQUE(script_id, version)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_script_versions_script ON script_versions(script_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS server_scripts (
|
|
server TEXT NOT NULL REFERENCES servers(name) ON DELETE CASCADE,
|
|
rel_path TEXT NOT NULL,
|
|
script_version_id INTEGER REFERENCES script_versions(id) ON DELETE SET NULL,
|
|
sha256 TEXT NOT NULL,
|
|
size INTEGER NOT NULL,
|
|
updated_at TEXT NOT NULL,
|
|
source TEXT, -- 'beta:<id>' | 'promote:<id>' | 'rollback:<id>'
|
|
PRIMARY KEY (server, rel_path)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_server_scripts_server ON server_scripts(server);
|
|
|
|
CREATE TABLE IF NOT EXISTS betas (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
-- DEPRECATED: multi-script betas are represented by beta_scripts. These
|
|
-- three columns are populated from the first bundled script to satisfy
|
|
-- NOT NULL on legacy schemas; the fleet code doesn't read them anymore.
|
|
script_id INTEGER NOT NULL REFERENCES scripts(id) ON DELETE CASCADE,
|
|
script_version_id INTEGER NOT NULL REFERENCES script_versions(id) ON DELETE CASCADE,
|
|
trigger_kind TEXT NOT NULL,
|
|
wait_for_health INTEGER NOT NULL DEFAULT 1,
|
|
wait_for_match INTEGER NOT NULL DEFAULT 0,
|
|
state TEXT NOT NULL, -- 'running' | 'ready-promote' | 'promoted' | 'rolled-back'
|
|
opened_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
|
closed_at TEXT,
|
|
notes TEXT
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_betas_state ON betas(state);
|
|
CREATE INDEX IF NOT EXISTS idx_betas_script ON betas(script_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS beta_servers (
|
|
beta_id INTEGER NOT NULL REFERENCES betas(id) ON DELETE CASCADE,
|
|
server TEXT NOT NULL REFERENCES servers(name),
|
|
had_original INTEGER NOT NULL, -- deprecated; see beta_server_scripts
|
|
prior_version_id INTEGER REFERENCES script_versions(id), -- deprecated; see beta_server_scripts
|
|
stage TEXT NOT NULL, -- 'deploying'|'awaiting-empty'|'restarting'|'awaiting-health'|'awaiting-match'|'ready'|'failed'
|
|
error TEXT,
|
|
deployed_at TEXT,
|
|
restarted_at TEXT,
|
|
healthy_at TEXT,
|
|
match_seen_at TEXT,
|
|
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
|
|
PRIMARY KEY (beta_id, server)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_beta_servers_stage ON beta_servers(stage);
|
|
|
|
-- Many-to-many: which scripts (and pinned versions) are bundled into a beta.
|
|
-- Replaces the deprecated betas.script_id / betas.script_version_id columns.
|
|
CREATE TABLE IF NOT EXISTS beta_scripts (
|
|
beta_id INTEGER NOT NULL REFERENCES betas(id) ON DELETE CASCADE,
|
|
script_id INTEGER NOT NULL REFERENCES scripts(id) ON DELETE CASCADE,
|
|
script_version_id INTEGER NOT NULL REFERENCES script_versions(id) ON DELETE CASCADE,
|
|
PRIMARY KEY (beta_id, script_id)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_beta_scripts_beta ON beta_scripts(beta_id);
|
|
CREATE INDEX IF NOT EXISTS idx_beta_scripts_script ON beta_scripts(script_id);
|
|
|
|
-- Per (beta, server, script) prior-file state. A server row in beta_servers
|
|
-- covers restart progress; this table covers what each script's target
|
|
-- looked like on that server before the beta wrote its -beta.gsc.
|
|
CREATE TABLE IF NOT EXISTS beta_server_scripts (
|
|
beta_id INTEGER NOT NULL REFERENCES betas(id) ON DELETE CASCADE,
|
|
server TEXT NOT NULL REFERENCES servers(name),
|
|
script_id INTEGER NOT NULL REFERENCES scripts(id) ON DELETE CASCADE,
|
|
had_original INTEGER NOT NULL,
|
|
prior_version_id INTEGER REFERENCES script_versions(id),
|
|
PRIMARY KEY (beta_id, server, script_id)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_beta_server_scripts_beta ON beta_server_scripts(beta_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS deployments (
|
|
id TEXT PRIMARY KEY,
|
|
action TEXT NOT NULL, -- 'drift' | 'promote' | 'rollback'
|
|
started_at TEXT NOT NULL,
|
|
finished_at TEXT,
|
|
triggered_by TEXT,
|
|
script_id INTEGER REFERENCES scripts(id), -- promote/rollback only
|
|
script_version_id INTEGER REFERENCES script_versions(id), -- the version this deployment lands / restores
|
|
prior_version_id INTEGER REFERENCES script_versions(id), -- current_version_id before this promote
|
|
beta_id INTEGER REFERENCES betas(id), -- promote only
|
|
rolled_back_by TEXT REFERENCES deployments(id) -- set on the promote row when a rollback reverses it
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_deployments_started ON deployments(started_at DESC);
|
|
|
|
CREATE TABLE IF NOT EXISTS deployment_servers (
|
|
deployment_id TEXT NOT NULL REFERENCES deployments(id) ON DELETE CASCADE,
|
|
server TEXT NOT NULL REFERENCES servers(name),
|
|
files_changed INTEGER NOT NULL,
|
|
restart_state TEXT NOT NULL, -- pending | done | failed | manual | held
|
|
players INTEGER,
|
|
checked_at TEXT,
|
|
restarted_at TEXT,
|
|
attempts INTEGER NOT NULL DEFAULT 0,
|
|
error TEXT,
|
|
PRIMARY KEY (deployment_id, server)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_deployment_servers_state ON deployment_servers(restart_state);
|
|
|
|
CREATE TABLE IF NOT EXISTS deployment_files (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
deployment_id TEXT NOT NULL REFERENCES deployments(id) ON DELETE CASCADE,
|
|
server TEXT NOT NULL,
|
|
verb TEXT NOT NULL, -- added | updated | removed
|
|
rel_path TEXT NOT NULL,
|
|
sha256_before TEXT,
|
|
sha256_after TEXT,
|
|
content_before BLOB,
|
|
content_after BLOB
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_deployment_files_dep ON deployment_files(deployment_id);
|
|
|
|
-- Per-script rows on aggregate promote/rollback deployments. For legacy
|
|
-- single-script deployments this may also be backfilled from the deprecated
|
|
-- deployments.script_id / script_version_id / prior_version_id columns.
|
|
CREATE TABLE IF NOT EXISTS deployment_scripts (
|
|
deployment_id TEXT NOT NULL REFERENCES deployments(id) ON DELETE CASCADE,
|
|
script_id INTEGER NOT NULL REFERENCES scripts(id) ON DELETE CASCADE,
|
|
script_version_id INTEGER NOT NULL REFERENCES script_versions(id) ON DELETE CASCADE,
|
|
prior_version_id INTEGER REFERENCES script_versions(id),
|
|
PRIMARY KEY (deployment_id, script_id)
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_deployment_scripts_dep ON deployment_scripts(deployment_id);
|
|
|
|
CREATE TABLE IF NOT EXISTS settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT NOT NULL
|
|
);
|