diff --git a/services/arbiter-3.0/src/routes/admin.js b/services/arbiter-3.0/src/routes/admin.js
index 41cbb12..2406168 100644
--- a/services/arbiter-3.0/src/routes/admin.js
+++ b/services/arbiter-3.0/src/routes/admin.js
@@ -143,24 +143,123 @@ module.exports = router;
// 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
+ // Static server list from infrastructure
+ const servers = [
+ { name: 'Awakened Survival', machine: 'TX1', status: 'online', players: '0/20' },
+ { name: 'Fire PvP Arena', machine: 'TX1', status: 'online', players: '0/50' },
+ { name: 'Frost Creative', machine: 'TX1', status: 'online', players: '0/30' },
+ { name: 'Knight Hardcore', machine: 'NC1', status: 'online', players: '0/25' },
+ { name: 'Master Skyblock', machine: 'NC1', status: 'online', players: '0/40' },
+ { name: 'Legend Factions', machine: 'NC1', status: 'online', players: '0/60' },
+ { name: 'Sovereign Network Hub', machine: 'TX1', status: 'online', players: '0/100' }
+ ];
+
+ let html = '
';
+
+ servers.forEach(server => {
+ const statusColor = server.status === 'online' ? 'bg-green-500' : 'bg-red-500';
+ html += `
+
+
+
${server.name}
+
+
+ ${server.status}
+
+
+
+
Machine: ${server.machine}
+
Players: ${server.players}
+
+
+ `;
+ });
+
+ html += '
';
+ html += `
+
+
+ 💡 Note: This is static data. Real-time Pterodactyl API integration coming soon.
+
- `);
+ `;
+
+ res.send(html);
});
// 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
-
- `);
+ 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
+ s.id,
+ s.discord_id,
+ s.tier_level,
+ p.tier_name,
+ s.status,
+ s.created_at,
+ s.mrr_value
+ FROM subscriptions s
+ LEFT JOIN stripe_products p ON s.tier_level = p.tier_level
+ ORDER BY s.created_at DESC
+ LIMIT 100
+ `);
+
+ if (result.rows.length === 0) {
+ res.send(`
+
+
👥 No subscribers yet
+
Subscribers will appear here after first signup
+
+ `);
+ } else {
+ let html = `
+
+
+
+ | Discord ID |
+ Tier |
+ Status |
+ MRR |
+ Since |
+
+
+
+ `;
+
+ result.rows.forEach(row => {
+ const statusColor = row.status === 'active' ? 'text-green-600' :
+ row.status === 'lifetime' ? 'text-purple-600' :
+ row.status === 'grace_period' ? 'text-yellow-600' :
+ 'text-gray-600';
+ const date = new Date(row.created_at);
+ html += `
+
+ | ${row.discord_id || 'N/A'} |
+ ${row.tier_name || 'Tier ' + row.tier_level} |
+
+ ${row.status}
+ |
+ $${(row.mrr_value || 0).toFixed(2)} |
+ ${date.toLocaleDateString()} |
+
+ `;
+ });
+
+ html += '
';
+ res.send(html);
+ }
+ } catch (error) {
+ res.send(`
Error: ${error.message}
`);
+ }
});
// Grace Period List Endpoint
@@ -218,22 +317,121 @@ router.get('/grace/list', isAdmin, async (req, res) => {
// 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
-
- `);
+ 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 event_id, event_type, processed_at
+ FROM webhook_events_processed
+ ORDER BY processed_at DESC
+ LIMIT 50
+ `);
+
+ if (result.rows.length === 0) {
+ res.send(`
+
+
📋 No webhook events yet
+
Events will appear here as Stripe webhooks are processed
+
+ `);
+ } else {
+ let html = '
';
+ result.rows.forEach(row => {
+ const timestamp = new Date(row.processed_at);
+ const eventColor = row.event_type.includes('succeeded') ? 'text-green-600' :
+ row.event_type.includes('failed') ? 'text-red-600' :
+ row.event_type.includes('dispute') ? 'text-red-600' :
+ 'text-blue-600';
+ html += `
+
+
+
+
${row.event_id}
+
${row.event_type}
+
+
+ ${timestamp.toLocaleString()}
+
+
+
+ `;
+ });
+ html += '
';
+ res.send(html);
+ }
+ } catch (error) {
+ res.send(`
Error: ${error.message}
`);
+ }
});
// 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
-
- `);
+ const { Pool } = require('pg');
+ const pool = new Pool({
+ host: '127.0.0.1',
+ user: 'arbiter',
+ password: 'FireFrost2026!Arbiter',
+ database: 'arbiter_db'
+ });
+
+ try {
+ // Get subscription counts by tier
+ const result = await pool.query(`
+ SELECT tier_level, COUNT(*) as count, status
+ FROM subscriptions
+ WHERE status IN ('active', 'lifetime')
+ GROUP BY tier_level, status
+ ORDER BY tier_level
+ `);
+
+ if (result.rows.length === 0) {
+ res.send(`
+
+
✅ No active subscriptions
+
Role diagnostics will run when users subscribe
+
+ `);
+ } else {
+ let html = `
+
+
+
📊 Subscription Summary
+
Active subscribers by tier (Discord role sync coming soon)
+
+
+ `;
+
+ result.rows.forEach(row => {
+ const statusColor = row.status === 'active' ? 'text-green-600' : 'text-purple-600';
+ html += `
+
+
Tier ${row.tier_level}
+
+ ${row.status}
+ ${row.count} subscriber${row.count > 1 ? 's' : ''}
+
+
+ `;
+ });
+
+ html += `
+
+
+
+ 💡 Coming Soon: Discord API integration to compare database tiers with actual Discord roles
+
+
+
+ `;
+ res.send(html);
+ }
+ } catch (error) {
+ res.send(`
Error: ${error.message}
`);
+ }
});