From aeeaa14865211ec79b14656ad2fc27b1c3a64a93 Mon Sep 17 00:00:00 2001 From: "Claude (Chronicler #52)" Date: Wed, 1 Apr 2026 15:33:06 +0000 Subject: [PATCH] feat: Add Admin tier to dropdown and staff tracking WHAT WAS DONE: - Added Admin tier (1000) back to tier dropdown - Added is_staff toggle checkbox in Actions column - Created POST route /admin/players/:discord_id/staff - Updated query to include is_staff from users table - Both tier and staff status tracked separately WHY: - Trinity needs ability to assign Admin tier to team members - Staff can also be subscribers - need to track both - Example: Moderator who also pays for Elemental tier - Separate tracking prevents conflating employment and subscription HOW IT WORKS: - Tier dropdown shows ALL tiers including Admin - Staff checkbox toggles is_staff on users table - Both changes create separate audit log entries - Staff flag independent of subscription tier DATABASE REQUIREMENT: - Requires migration: ALTER TABLE users ADD COLUMN is_staff BOOLEAN DEFAULT FALSE; - Must be run before deploying this code FEATURES: - Admin tier assignable via dropdown - Staff toggle with visual checkbox - Both tracked in audit log separately - Tier + Staff shown side-by-side in Actions column IMPACT: - Can now hire staff and track their employment - Staff can also be subscribers without conflict - Clear separation of concerns - Ready for team expansion FILES MODIFIED: - services/arbiter-3.0/src/views/admin/players/_table_body.ejs - services/arbiter-3.0/src/routes/admin/players.js DEPLOYMENT STEPS: 1. Run database migration (ADD is_staff column) 2. Deploy code files 3. Restart arbiter-3 service Signed-off-by: Claude (Chronicler #52) --- .../arbiter-3.0/src/routes/admin/players.js | 32 ++++++++++++++- .../src/views/admin/players/_table_body.ejs | 41 ++++++++++++------- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/services/arbiter-3.0/src/routes/admin/players.js b/services/arbiter-3.0/src/routes/admin/players.js index 2cc5217..378bf1b 100644 --- a/services/arbiter-3.0/src/routes/admin/players.js +++ b/services/arbiter-3.0/src/routes/admin/players.js @@ -17,7 +17,7 @@ router.get('/table', async (req, res) => { // Basic search implementation let query = ` - SELECT u.discord_id, u.minecraft_username, u.minecraft_uuid, + SELECT u.discord_id, u.minecraft_username, u.minecraft_uuid, u.is_staff, s.tier_level, s.status, s.updated_at FROM users u LEFT JOIN subscriptions s ON u.discord_id = s.discord_id @@ -69,4 +69,34 @@ router.post('/:discord_id/tier', async (req, res) => { } }); +// POST endpoint for staff toggle +router.post('/:discord_id/staff', async (req, res) => { + const { discord_id } = req.params; + + try { + // Toggle staff status + await db.query(` + UPDATE users + SET is_staff = NOT COALESCE(is_staff, FALSE) + WHERE discord_id = $1 + `, [discord_id]); + + // Get new status for audit log + const { rows } = await db.query(`SELECT is_staff FROM users WHERE discord_id = $1`, [discord_id]); + const newStatus = rows[0]?.is_staff ? 'Staff' : 'Non-Staff'; + + // Create audit log entry + await db.query(` + INSERT INTO admin_audit_log (admin_discord_id, action, target_discord_id, details) + VALUES ($1, 'staff_toggle', $2, $3) + `, [req.user.id, discord_id, `Changed to ${newStatus}`]); + + res.send('OK'); + + } catch (error) { + console.error('Staff toggle error:', error); + res.status(500).send('Error updating staff status'); + } +}); + module.exports = router; diff --git a/services/arbiter-3.0/src/views/admin/players/_table_body.ejs b/services/arbiter-3.0/src/views/admin/players/_table_body.ejs index f234dae..f08930b 100644 --- a/services/arbiter-3.0/src/views/admin/players/_table_body.ejs +++ b/services/arbiter-3.0/src/views/admin/players/_table_body.ejs @@ -28,20 +28,33 @@ -
- -
+
+ +
+ +
+ + + +
<% }) %>