diff --git a/docs/consultations/gemini-hybrid-detection-2026-04-06.md b/docs/consultations/gemini-hybrid-detection-2026-04-06.md new file mode 100644 index 0000000..495b80d --- /dev/null +++ b/docs/consultations/gemini-hybrid-detection-2026-04-06.md @@ -0,0 +1,139 @@ +# Gemini Consultation: Hybrid Detection Architecture + +**Date:** April 6, 2026 +**Topic:** ModpackChecker UX Pivot — Auto-Discovery Strategy +**Chronicler:** #63 + +--- + +## The Question + +ModpackChecker requires egg variables (`MODPACK_PLATFORM`, `MODPACK_ID`) that most standard eggs don't have. This creates unacceptable friction for: +- Admins with many servers (Michael has 21) +- BuiltByBit customers expecting plug-and-play + +We asked Gemini to evaluate detection strategies. + +--- + +## Gemini's Response + +### File Detection Feasibility + +**Yes, it's feasible** via `DaemonFileRepository`. This is the industry standard for premium Pterodactyl extensions. + +**Security:** Completely secure. The repository uses the server's daemon token — sandboxed to `/home/container/` only. + +**Critical Warning:** It's a network call to Wings. **Never do this on page load** — only in background cron jobs. Doing it synchronously for 20 servers will hang and timeout. + +### CurseForge Fingerprinting + +**Hard pass. Rejected.** + +CurseForge fingerprinting requires hashing every `.jar` file in `mods/` folder with Murmur2. Pulling gigabytes of mod data over Wings API will: +- Crash the daemon +- Destroy VPS CPU +- Be extremely slow + +Keep it lightweight — just read manifest files. + +### Database Schema + +**Do NOT create a separate config table.** It complicates joins and slows the dashboard API. Keep everything in `modpackchecker_servers`. + +--- + +## Recommended Architecture: "Magic & Manual" Hybrid + +### Step 1: Auto-Discovery Cron (The Magic) + +When `CheckModpackUpdates` cron runs, execute this hierarchy for unconfigured servers: + +1. Check Egg Variables (fastest) +2. If missing → `DaemonFileRepository` to read `manifest.json` (CurseForge) +3. If missing → Read `modrinth.index.json` (Modrinth) +4. If found → Save to DB with `detection_method = 'file'` + +### Step 2: Server Owner Self-Service (The Fallback) + +If cron finds nothing, mark `status = 'unconfigured'`. + +Console widget shows setup UI instead of failing: +- **UI:** "Modpack not automatically detected." → [Configure Manually] button +- **Action:** Modal lets server owner select platform + paste modpack ID +- **Result:** Saves with `detection_method = 'manual'` + +The `is_user_overridden` flag prevents cron from overwriting manual configs. + +--- + +## Implementation Code + +### DaemonFileRepository Injection + +```php +use Pterodactyl\Repositories\Wings\DaemonFileRepository; + +public function __construct( + private DaemonFileRepository $fileRepository +) {} +``` + +### CurseForge Detection + +```php +private function detectCurseForge(Server $server): ?string +{ + try { + $this->fileRepository->setServer($server); + + // Attempt to read manifest.json + $content = $this->fileRepository->getContent('manifest.json'); + $manifest = json_decode($content, true); + + return $manifest['projectID'] ?? null; + + } catch (\Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException $e) { + // Node is offline, skip for now + return null; + } catch (\Exception $e) { + // File doesn't exist or is unreadable + return null; + } +} +``` + +### Database Schema Additions + +```php +// Tracks how we found it: 'egg', 'file', or 'manual' +$table->string('detection_method')->default('unknown'); + +// Prevents the auto-discovery cron from overwriting a user's manual fix +$table->boolean('is_user_overridden')->default(false); +``` + +--- + +## Rejected Approaches + +| Approach | Reason | +|----------|--------| +| CurseForge Fingerprinting | Too resource-intensive, would crash Wings | +| Admin-only UI mapping | Poor scalability for large hosts | +| Separate config table | Complicates joins, slows dashboard | + +--- + +## Decision + +**Proceed with Hybrid Approach:** +1. Backend auto-discovery via `DaemonFileRepository` in cron +2. Frontend self-service modal for server owners +3. All data in single `modpackchecker_servers` table + +This provides "magic" for standard packs while offloading edge cases to server owners (not system admins). + +--- + +*Fire + Frost + Foundation = Where Love Builds Legacy* 💙🔥❄️