From 4c7a7a08325845a6f5c48bdcd89721b6abec0b05 Mon Sep 17 00:00:00 2001 From: "Claude (Chronicler #57)" Date: Fri, 3 Apr 2026 18:07:39 +0000 Subject: [PATCH] feat: add HTMX endpoint stubs for all admin modules Templates use HTMX to load data dynamically via AJAX Added 5 endpoint stubs (will implement with real data): 1. /admin/servers/matrix - Server status grid 2. /admin/players/table - Player list 3. /admin/grace/list - Grace period users (WORKING with real DB query) 4. /admin/audit/feed - Recent webhook events 5. /admin/roles/mismatches - Discord role diagnostics Grace endpoint COMPLETE - queries PostgreSQL and shows users in grace period Others return 'Coming Soon' placeholders TESTING: - Grace Period page should show real data - Other pages show 'Coming Soon' instead of loading spinner Signed-off-by: Claude (Chronicler #57) --- services/arbiter-3.0/src/routes/admin.js | 101 +++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/services/arbiter-3.0/src/routes/admin.js b/services/arbiter-3.0/src/routes/admin.js index 96b59ba..41cbb12 100644 --- a/services/arbiter-3.0/src/routes/admin.js +++ b/services/arbiter-3.0/src/routes/admin.js @@ -136,3 +136,104 @@ router.post('/mappings', isAdmin, express.json(), (req, res) => { }); module.exports = router; + +// ========================================== +// HTMX API ENDPOINTS (Return HTML fragments) +// ========================================== + +// Servers Matrix Endpoint +router.get('/servers/matrix', isAdmin, async (req, res) => { + // TODO: Query server status from Pterodactyl API + res.send(` +
+

Server Matrix Coming Soon

+

Will display real-time status of all 13 Minecraft servers

+
+ `); +}); + +// Players Table Endpoint +router.get('/players/table', isAdmin, async (req, res) => { + // TODO: Query subscriptions with Discord user data + res.send(` +
+

Player Database Coming Soon

+

Will display all subscribers with search/filter

+
+ `); +}); + +// Grace Period List Endpoint +router.get('/grace/list', isAdmin, async (req, res) => { + const { Pool } = require('pg'); + const pool = new Pool({ + host: '127.0.0.1', + user: 'arbiter', + password: 'FireFrost2026!Arbiter', + database: 'arbiter_db' + }); + + try { + const result = await pool.query(` + SELECT discord_id, tier_level, grace_period_started_at, grace_period_ends_at + FROM subscriptions + WHERE status = 'grace_period' + ORDER BY grace_period_ends_at ASC + `); + + if (result.rows.length === 0) { + res.send(` +
+

✅ No users in grace period!

+

All subscribers are current on payments

+
+ `); + } else { + let html = '
'; + result.rows.forEach(row => { + const endsAt = new Date(row.grace_period_ends_at); + const hoursLeft = Math.round((endsAt - new Date()) / (1000 * 60 * 60)); + html += ` +
+
+
+
Discord ID: ${row.discord_id}
+
Tier ${row.tier_level}
+
+
+
${hoursLeft}h remaining
+
${endsAt.toLocaleString()}
+
+
+
+ `; + }); + html += '
'; + res.send(html); + } + } catch (error) { + res.send(`
Error: ${error.message}
`); + } +}); + +// Audit Log Feed Endpoint +router.get('/audit/feed', isAdmin, async (req, res) => { + // TODO: Query webhook_events_processed table + res.send(` +
+

Audit Log Coming Soon

+

Will display recent webhook events and role changes

+
+ `); +}); + +// Role Mismatches Diagnostic Endpoint +router.get('/roles/mismatches', isAdmin, async (req, res) => { + // TODO: Compare Discord roles vs database subscriptions + res.send(` +
+

Role Diagnostics Coming Soon

+

Will scan Discord server and compare with database

+
+ `); +});