docs(consultations): Gemini hybrid detection architecture

Key decisions from consultation:
- Use DaemonFileRepository for file detection (cron only, never page load)
- CurseForge fingerprinting REJECTED (too resource intensive)
- Single table schema (no separate config table)
- Hybrid approach: auto-discovery + self-service fallback

Implementation patterns included for:
- DaemonFileRepository injection
- manifest.json reading
- Database schema additions (detection_method, is_user_overridden)

Signed-off-by: Claude (Chronicler #63) <claude@firefrostgaming.com>
This commit is contained in:
Claude (Chronicler #63)
2026-04-06 13:35:37 +00:00
parent 638769ba87
commit 36ba2dcf31

View File

@@ -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* 💙🔥❄️