# Task #90: Arbiter 2.x - Unified Access Manager **Status:** OPEN **Priority:** Tier 1 - Soft Launch Blocker **Estimated Time:** 20-30 hours (5 phases) **Created:** March 31, 2026 **Architecture Validated By:** Gemini AI --- ## Overview Complete rewrite merging Arbiter (Discord role management) + Whitelist Manager (server access control) into single Node.js application with PostgreSQL backend. **Goal:** Subscription-driven Minecraft server whitelist access - user subscribes → links Minecraft account → automatically whitelisted on all servers. --- ## Quick Links - **Implementation Guide:** `IMPLEMENTATION-GUIDE.md` (complete technical spec with code examples) - **Architecture Decision:** `../../reference/gemini-consultations/2026-03-31-arbiter-whitelist-architecture.md` - **Implementation Details:** `../../reference/gemini-consultations/2026-03-31-arbiter-implementation-details.md` - **Main Task:** `../../core/tasks.md#90` --- ## The Flow 1. User subscribes via Paymenter (any tier, even $1 Awakened) 2. Paymenter webhook → Arbiter assigns Discord role 3. User runs `/link ` in Discord 4. Arbiter validates via Mojang API, gets UUID 5. Stores in PostgreSQL: discord_id, minecraft_username, minecraft_uuid 6. Master whitelist auto-syncs to all whitelisted servers 7. User can now join any Minecraft server --- ## Why Rewrite? **Current Whitelist Manager is broken:** - Hardcoded server name keywords (fails when servers change) - WebSocket console commands (unreliable, returns "UNKNOWN") - No subscription integration - No master whitelist concept - Manual-only operation **Current Arbiter doesn't:** - Store Minecraft usernames - Communicate with Whitelist Manager - Handle subscription-driven whitelist access --- ## Architecture Decisions All validated by Gemini AI consultation (March 31, 2026): ✅ **Single unified app** - Arbiter 2.x replaces both services ✅ **PostgreSQL** - Concurrent write safety at 500-user scale ✅ **Discord `/link` slash command** - Mojang API validation ✅ **Pterodactyl File Management API** - Replaces WebSocket console ✅ **Hybrid sync** - Event-driven push + hourly cron reconciliation ✅ **UUIDs with dashes** - Minecraft 1.8+ requirement --- ## Implementation Phases ### Phase 1: Database Migration - [ ] Provision PostgreSQL 15+ - [ ] Execute schema creation - [ ] Apply indexes for 500-user scale - [ ] Migrate legacy SQLite data ### Phase 2: Core Functions - [ ] pg connection pool - [ ] Mojang API validation + UUID formatting - [ ] Pterodactyl Application API (auto-discovery) - [ ] Pterodactyl Client API (file write, commands) ### Phase 3: Discord Integration - [ ] `/link` slash command registration - [ ] UUID validation flow - [ ] Auto-DM new subscribers - [ ] Paymenter webhook updates ### Phase 4: Sync System - [ ] Event-driven immediate sync - [ ] node-cron hourly reconciliation - [ ] Sequential batch processing - [ ] Sync logging to database ### Phase 5: Admin Panel - [ ] server_sync_log dashboard - [ ] Manual "Force Sync" trigger - [ ] Linked accounts view - [ ] Production deployment --- ## Critical Gotchas From Gemini consultation - these will break production if missed: 1. **Content-Type: text/plain** for Panel file write (NOT application/json) 2. **Mojang UUIDs without dashes**, Minecraft needs **WITH dashes** 3. **HTTP 412 = server offline**, NOT an error (file saved for next boot) 4. **Sequential processing** prevents Panel API rate limiting 5. **Application API** for discovery, **Client API** for file operations --- ## Database Schema ```sql CREATE TABLE users ( discord_id VARCHAR(255) PRIMARY KEY, minecraft_username VARCHAR(255) UNIQUE, minecraft_uuid VARCHAR(255) UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE subscriptions ( id SERIAL PRIMARY KEY, discord_id VARCHAR(255) REFERENCES users(discord_id), tier_level INT NOT NULL, status VARCHAR(50) NOT NULL, -- active, grace_period, cancelled stripe_customer_id VARCHAR(255) ); CREATE TABLE server_sync_log ( server_identifier VARCHAR(50) PRIMARY KEY, last_successful_sync TIMESTAMP, last_error TEXT, is_online BOOLEAN DEFAULT true ); CREATE INDEX idx_users_discord_id ON users(discord_id); CREATE INDEX idx_subscriptions_status ON subscriptions(status); ``` --- ## Success Criteria - User subscribes → links account → auto-whitelisted within 5 minutes - Master whitelist = database (single source of truth) - All servers sync from master (hourly reconciliation) - Server discovery is automatic (no hardcoded names) - Works reliably for remote RV operations - Handles 500 subscribers by September 2027 --- ## What Gets Retired Once Arbiter 2.x is deployed: - ❌ Old Whitelist Manager (Python Flask on Billing VPS) - ❌ Old Arbiter 1.x (if not already migrated) - ✅ Update all documentation to reference unified system --- ## Dependencies - PostgreSQL 15+ - Node.js 20 LTS - Pterodactyl Panel v1.12.1 (Client + Application API keys) - Mojang API (public, no auth) - Discord Bot with slash command permissions --- **Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️