From 085e60e748da0848348181069991a69052198010 Mon Sep 17 00:00:00 2001 From: "Claude (Chronicler #52)" Date: Wed, 1 Apr 2026 15:28:31 +0000 Subject: [PATCH] feat: Add tier change functionality to Players module WHAT WAS DONE: - Added tier change dropdown in Players Actions column - Created POST route /admin/players/:discord_id/tier - Implemented database tier update with MRR recalculation - Added audit log entry for tier changes - htmx reload of table after tier change WHY: - Trinity needs ability to manually adjust subscriber tiers - Customer service: upgrades, downgrades, support cases - Accountability via audit logging - Last missing feature in Players module HOW IT WORKS: - Dropdown shows all tiers (except Admin 1000) - On change, htmx POSTs to tier change endpoint - Route updates subscriptions table (tier_level + mrr_value) - Audit log records who made the change - After success, table reloads to show updated tier FEATURES: - Real-time tier changes without page refresh - Automatic MRR recalculation - Audit trail for compliance - Skips Admin tier (reserved for Trinity) - Shows current tier as selected in dropdown IMPACT: - Trinity can now manage all subscriber tiers manually - Critical for customer support scenarios - Completes Players module functionality - Ready for soft launch customer service TODO: - Discord role sync integration (marked in code) - This requires bot API endpoint to be built FILES MODIFIED: - services/arbiter-3.0/src/views/admin/players/_table_body.ejs - services/arbiter-3.0/src/routes/admin/players.js TESTED: - Not yet deployed - needs testing on Command Center Signed-off-by: Claude (Chronicler #52) --- .../arbiter-3.0/src/routes/admin/players.js | 37 +++++++++++++++++++ .../src/views/admin/players/_table_body.ejs | 15 +++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/services/arbiter-3.0/src/routes/admin/players.js b/services/arbiter-3.0/src/routes/admin/players.js index 51bb3f4..2cc5217 100644 --- a/services/arbiter-3.0/src/routes/admin/players.js +++ b/services/arbiter-3.0/src/routes/admin/players.js @@ -32,4 +32,41 @@ router.get('/table', async (req, res) => { res.render('admin/players/_table_body', { players, TIER_INFO, page, search }); }); +// POST endpoint for tier changes +router.post('/:discord_id/tier', async (req, res) => { + const { discord_id } = req.params; + const { tier_level } = req.body; + + try { + // Validate tier exists + if (!TIER_INFO[tier_level]) { + return res.status(400).send('Invalid tier'); + } + + // Update tier in database + const tierInfo = TIER_INFO[tier_level]; + await db.query(` + UPDATE subscriptions + SET tier_level = $1, mrr_value = $2, updated_at = NOW() + WHERE discord_id = $3 + `, [tier_level, tierInfo.price, discord_id]); + + // TODO: Sync Discord roles via bot + // This will be implemented when Discord bot integration is ready + + // Create audit log entry + await db.query(` + INSERT INTO admin_audit_log (admin_discord_id, action, target_discord_id, details) + VALUES ($1, 'tier_change', $2, $3) + `, [req.user.id, discord_id, `Changed tier to ${tierInfo.name}`]); + + // Return success (htmx will handle UI update) + res.send('OK'); + + } catch (error) { + console.error('Tier change error:', error); + res.status(500).send('Error updating tier'); + } +}); + 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 ae1c24c..f234dae 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,7 +28,20 @@ - (Coming Soon) +
+ +
<% }) %>