config and plugin

This commit is contained in:
2026-09-12 19:11:44 -04:00
parent 85bcb05a7d
commit 8c40bbeff1
19 changed files with 1685 additions and 86 deletions
+22 -1
View File
@@ -44,6 +44,10 @@ function migrateServers(handle: Database.Database): void {
// Additive columns on tables the script model owns. Same pattern as
// migrateServers — CREATE TABLE IF NOT EXISTS won't backfill columns onto
// pre-existing tables, so we introspect and ALTER as needed.
const SCRIPTS_COLUMNS: Array<{ name: string; ddl: string }> = [
{ name: 'kind', ddl: "ALTER TABLE scripts ADD COLUMN kind TEXT NOT NULL DEFAULT 'script'" }
];
const SCRIPT_VERSIONS_COLUMNS: Array<{ name: string; ddl: string }> = [
// state was added post-launch to make untested/tested/test-failed visible
// in the UI. Existing rows default to 'untested' — this is safe because
@@ -51,7 +55,16 @@ const SCRIPT_VERSIONS_COLUMNS: Array<{ name: string; ddl: string }> = [
// the authoritative "promoted" signal), and any version already gated
// through a ready-promote beta will be re-marked next time that state
// machine fires.
{ name: 'state', ddl: "ALTER TABLE script_versions ADD COLUMN state TEXT NOT NULL DEFAULT 'untested'" }
{ name: 'state', ddl: "ALTER TABLE script_versions ADD COLUMN state TEXT NOT NULL DEFAULT 'untested'" },
{ name: 'kind', ddl: "ALTER TABLE script_versions ADD COLUMN kind TEXT NOT NULL DEFAULT 'script'" }
];
const BETA_SCRIPTS_COLUMNS: Array<{ name: string; ddl: string }> = [
{ name: 'kind', ddl: "ALTER TABLE beta_scripts ADD COLUMN kind TEXT NOT NULL DEFAULT 'script'" }
];
const DEPLOYMENT_SCRIPTS_COLUMNS: Array<{ name: string; ddl: string }> = [
{ name: 'kind', ddl: "ALTER TABLE deployment_scripts ADD COLUMN kind TEXT NOT NULL DEFAULT 'script'" }
];
const DEPLOYMENTS_COLUMNS: Array<{ name: string; ddl: string }> = [
@@ -146,8 +159,16 @@ export function db(): Database.Database {
dropLegacyBetaTables(_db);
_db.exec(schemaSql);
migrateServers(_db);
migrateTable(_db, 'scripts', SCRIPTS_COLUMNS);
migrateTable(_db, 'script_versions', SCRIPT_VERSIONS_COLUMNS);
migrateTable(_db, 'beta_scripts', BETA_SCRIPTS_COLUMNS);
migrateTable(_db, 'deployment_scripts', DEPLOYMENT_SCRIPTS_COLUMNS);
migrateTable(_db, 'deployments', DEPLOYMENTS_COLUMNS);
_db.exec(
`CREATE UNIQUE INDEX IF NOT EXISTS idx_scripts_one_baseline_per_scope
ON scripts(scope_type, scope_value) WHERE kind = 'baseline'`
);
_db.exec(`CREATE INDEX IF NOT EXISTS idx_scripts_kind ON scripts(kind)`);
backfillMultiScriptJoins(_db);
return _db;
+16 -2
View File
@@ -26,8 +26,14 @@ CREATE TABLE IF NOT EXISTS servers (
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.
-- One row per artifact (a logical thing, e.g. "HUD tweaks"). Name is unique and
-- doubles as the slug in URLs. The `kind` column discriminates:
-- 'script' — GSC files deployed to runtime/plutonium/storage/t5/raw/scripts/sp
-- 'plugin' — .dll files deployed to runtime/plutonium/plugins
-- 'config' — cfg overlay (set K "V" lines) layered onto the baseline
-- 'baseline' — full dedicated_sp.cfg; exactly one per scope
-- Table + column names keep the "scripts" prefix for continuity; treat them
-- polymorphically at the app layer.
CREATE TABLE IF NOT EXISTS scripts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
@@ -35,9 +41,14 @@ CREATE TABLE IF NOT EXISTS scripts (
scope_type TEXT, -- NULL | 'game' | 'map'
scope_value TEXT, -- NULL | 't5' | 'zombie_theater'
current_version_id INTEGER, -- FK → script_versions(id) after first promote
kind TEXT NOT NULL DEFAULT 'script', -- 'script' | 'config' | 'plugin' | 'baseline'
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 INDEX IF NOT EXISTS idx_scripts_kind ON scripts(kind);
-- At most one baseline per (scope_type, scope_value). Partial unique index.
CREATE UNIQUE INDEX IF NOT EXISTS idx_scripts_one_baseline_per_scope
ON scripts(scope_type, scope_value) WHERE kind = 'baseline';
CREATE TABLE IF NOT EXISTS script_versions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -48,6 +59,7 @@ CREATE TABLE IF NOT EXISTS script_versions (
content BLOB NOT NULL,
notes TEXT,
state TEXT NOT NULL DEFAULT 'untested', -- 'untested' | 'tested' | 'test-failed'
kind TEXT NOT NULL DEFAULT 'script', -- denormalized from scripts.kind for join-free filtering
uploaded_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
UNIQUE(script_id, version)
);
@@ -105,6 +117,7 @@ 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,
kind TEXT NOT NULL DEFAULT 'script', -- denormalized from scripts.kind
PRIMARY KEY (beta_id, script_id)
);
CREATE INDEX IF NOT EXISTS idx_beta_scripts_beta ON beta_scripts(beta_id);
@@ -175,6 +188,7 @@ CREATE TABLE IF NOT EXISTS deployment_scripts (
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),
kind TEXT NOT NULL DEFAULT 'script', -- denormalized from scripts.kind
PRIMARY KEY (deployment_id, script_id)
);
CREATE INDEX IF NOT EXISTS idx_deployment_scripts_dep ON deployment_scripts(deployment_id);