diff --git a/services/arbiter-3.0/migrations/140_server_version_history.sql b/services/arbiter-3.0/migrations/140_server_version_history.sql new file mode 100644 index 0000000..afa30fa --- /dev/null +++ b/services/arbiter-3.0/migrations/140_server_version_history.sql @@ -0,0 +1,18 @@ +-- Migration 140: Server version history tracking +-- Chronicler #88 | April 14, 2026 + +-- Add current_version to server_config for quick display +ALTER TABLE server_config ADD COLUMN IF NOT EXISTS current_version VARCHAR(64); + +-- Version history table +CREATE TABLE IF NOT EXISTS server_version_history ( + id SERIAL PRIMARY KEY, + server_identifier VARCHAR(36) NOT NULL, + version VARCHAR(64) NOT NULL, + updated_by_id VARCHAR(32) NOT NULL, + updated_by_username VARCHAR(64) NOT NULL, + updated_at TIMESTAMP DEFAULT NOW() +); + +CREATE INDEX IF NOT EXISTS idx_svh_server ON server_version_history(server_identifier); +CREATE INDEX IF NOT EXISTS idx_svh_updated ON server_version_history(updated_at DESC); diff --git a/services/arbiter-3.0/src/routes/admin/servers.js b/services/arbiter-3.0/src/routes/admin/servers.js index 4c99813..3ea38e0 100644 --- a/services/arbiter-3.0/src/routes/admin/servers.js +++ b/services/arbiter-3.0/src/routes/admin/servers.js @@ -603,4 +603,63 @@ router.post('/:identifier/provision-subdomain', async (req, res) => { } }); +// POST /admin/servers/:identifier/set-version +// Set the installed modpack version for a server +router.post('/:identifier/set-version', async (req, res) => { + const { identifier } = req.params; + const { version } = req.body; + + if (!version || !version.trim()) { + return res.status(400).send('❌ Version cannot be empty'); + } + + const cleanVersion = version.trim(); + const userId = req.user?.id || 'unknown'; + const username = req.user?.username || 'Unknown'; + + try { + // Update current version on server_config + await db.query( + 'UPDATE server_config SET current_version = $1, updated_at = NOW() WHERE server_identifier = $2', + [cleanVersion, identifier] + ); + + // Insert into history + await db.query( + 'INSERT INTO server_version_history (server_identifier, version, updated_by_id, updated_by_username) VALUES ($1, $2, $3, $4)', + [identifier, cleanVersion, userId, username] + ); + + serverCache.lastFetch = 0; + console.log(`[VERSION] ${identifier} → ${cleanVersion} by ${username}`); + + res.send(`✅ Version set to ${cleanVersion}`); + } catch (err) { + console.error('[set-version]', err); + res.status(500).send('❌ Failed to update version'); + } +}); + +// GET /admin/servers/:identifier/version-history +// Returns version history partial for a server +router.get('/:identifier/version-history', async (req, res) => { + const { identifier } = req.params; + + try { + const result = await db.query( + 'SELECT version, updated_by_username, updated_at FROM server_version_history WHERE server_identifier = $1 ORDER BY updated_at DESC LIMIT 10', + [identifier] + ); + + res.render('admin/servers/_version_history', { + history: result.rows, + identifier, + layout: false + }); + } catch (err) { + console.error('[version-history]', err); + res.status(500).send('❌ Failed to load history'); + } +}); + module.exports = router; diff --git a/services/arbiter-3.0/src/views/admin/servers/_server_card.ejs b/services/arbiter-3.0/src/views/admin/servers/_server_card.ejs index 44cb9b2..968f78f 100644 --- a/services/arbiter-3.0/src/views/admin/servers/_server_card.ejs +++ b/services/arbiter-3.0/src/views/admin/servers/_server_card.ejs @@ -187,4 +187,44 @@ title="Restart">🔄 + + +
+
📦 Installed Version
+
+ + <%= (config && config.current_version) ? config.current_version : 'Not set' %> + + +
+ +
+ diff --git a/services/arbiter-3.0/src/views/admin/servers/_version_history.ejs b/services/arbiter-3.0/src/views/admin/servers/_version_history.ejs new file mode 100644 index 0000000..9d634fa --- /dev/null +++ b/services/arbiter-3.0/src/views/admin/servers/_version_history.ejs @@ -0,0 +1,23 @@ + +<% if (history.length === 0) { %> +

No version history yet.

+<% } else { %> + + + + + + + + + + <% history.forEach(function(h) { %> + + + + + + <% }); %> + +
VersionByWhen
<%= h.version %><%= h.updated_by_username %><%= new Date(h.updated_at).toLocaleDateString() %>
+<% } %> diff --git a/services/arbiter-3.0/src/views/admin/servers/index.ejs b/services/arbiter-3.0/src/views/admin/servers/index.ejs index fb3a085..164bcc6 100644 --- a/services/arbiter-3.0/src/views/admin/servers/index.ejs +++ b/services/arbiter-3.0/src/views/admin/servers/index.ejs @@ -32,3 +32,38 @@ + +