Files
firefrost-services/services/modpack-version-checker/blueprint-extension/README.md
Claude (Chronicler #63) e36b20d06e docs(modpackchecker): Comprehensive developer documentation
Added professional-grade documentation throughout the codebase so any
developer can pick up this project and understand it immediately.

PHILOSOPHY:
'Hand someone the repo and say: here's what we built, here's WHY we built
it this way, here's where it's going. Make it better.' — Michael

NEW FILES:
- blueprint-extension/README.md
  - Complete developer onboarding guide (400+ lines)
  - Architecture diagram showing cron → cache → badge flow
  - Installation steps, configuration, usage
  - API reference with example responses
  - Troubleshooting guide
  - Design decisions with rationale

ENHANCED DOCUMENTATION:

ModpackAPIController.php:
- 60-line file header explaining purpose, architecture, critical decisions
- Detailed docblocks on every method
- Explains WHY dashboard reads cache-only (rate limits)
- Documents all four platform APIs with links
- Example request/response for each endpoint

CheckModpackUpdates.php:
- 50-line file header with usage examples
- Recommended cron schedule
- Example console output
- Documents rate limiting strategy
- Explains relationship to dashboard badges

UpdateBadge.tsx:
- 50-line file header explaining the 'dumb badge' architecture
- Detailed comments on global cache pattern
- Documents the fetch-once deduplication strategy
- Explains render conditions and why each exists
- Brand color documentation (Fire/Frost)
- Accessibility notes (aria-label)

WHAT A NEW DEVELOPER NOW KNOWS:
1. The 'why' behind every architectural decision
2. How the cron → cache → badge flow prevents rate limits
3. Which methods call external APIs vs read cache
4. How to add a new platform
5. How to troubleshoot common issues
6. The relationship between all components

This codebase is now ready to hand to a contractor with the words:
'This was made great. Make it awesome.'

Signed-off-by: Claude (Chronicler #63) <claude@firefrostgaming.com>
2026-04-06 09:05:48 +00:00

12 KiB
Raw Blame History

ModpackChecker — Pterodactyl Blueprint Extension

Version: 1.0.0
Author: Firefrost Gaming
License: Proprietary (Commercial product for BuiltByBit)

A Pterodactyl Panel extension that checks modpack versions across CurseForge, Modrinth, FTB, and Technic platforms. Shows update status on the dashboard and provides manual version checks from the server console.


Table of Contents

  1. Features
  2. Architecture Overview
  3. File Structure
  4. Installation
  5. Configuration
  6. Usage
  7. Development
  8. API Reference
  9. Troubleshooting
  10. Design Decisions

Features

Dashboard Badge

  • Shows a colored dot next to each server name on the dashboard
  • 🟠 Orange (Fire #FF6B35): Update available
  • 🟢 Teal (Frost #4ECDC4): Up to date
  • Hover for version details tooltip
  • Single API call per page load (cached globally)

Console Widget

  • "Check for Updates" button on each server's console page
  • Real-time version check against platform API
  • Shows modpack name, current version, and latest version

Admin Panel

  • Configure CurseForge API key
  • View extension status
  • (Future: Rate limit settings, notification preferences)

Supported Platforms

Platform ID Type API Key Required
CurseForge Numeric project ID Yes
Modrinth Project ID or slug No
FTB Numeric modpack ID No
Technic URL slug No

Architecture Overview

┌─────────────────────────────────────────────────────────────────────────────┐
│                           MODPACK VERSION CHECKER                            │
│                            Architecture Diagram                              │
└─────────────────────────────────────────────────────────────────────────────┘

                    ┌─────────────────────────────────────┐
                    │     CRON JOB (runs every 4-6 hrs)   │
                    │     php artisan modpackchecker:check │
                    │                                     │
                    │  • Finds servers with MODPACK_*     │
                    │  • Calls platform APIs one by one   │
                    │  • 2-second delay between calls     │
                    │  • Stores results in database       │
                    └──────────────────┬──────────────────┘
                                       │
                                       ▼
                    ┌─────────────────────────────────────┐
                    │         DATABASE CACHE              │
                    │     modpackchecker_servers table    │
                    │                                     │
                    │  • server_id, server_uuid           │
                    │  • platform, modpack_id             │
                    │  • current_version, latest_version  │
                    │  • update_available (boolean)       │
                    │  • last_checked timestamp           │
                    └──────────────────┬──────────────────┘
                                       │
                    ┌──────────────────┴──────────────────┐
                    │                                     │
                    ▼                                     ▼
    ┌───────────────────────────┐       ┌───────────────────────────┐
    │    DASHBOARD BADGE        │       │    CONSOLE WIDGET         │
    │    (UpdateBadge.tsx)      │       │    (wrapper.tsx)          │
    │                           │       │                           │
    │  • Reads from cache ONLY  │       │  • Manual "Check" button  │
    │  • Never calls external   │       │  • LIVE API call          │
    │  • One API call per page  │       │  • Single server only     │
    │  • Shows 🟠 or 🟢 dot     │       │  • Shows full details     │
    └───────────────────────────┘       └───────────────────────────┘

Why This Architecture?

The Problem: A panel with 50 servers and 20 active users could generate thousands of API calls per day if each dashboard view triggered live checks.

The Solution:

  1. Cron job handles external API calls with rate limiting
  2. Dashboard reads from local cache only
  3. Console provides on-demand checks for specific servers

This was validated by Gemini AI during architectural review.


File Structure

blueprint-extension/
├── README.md                    # This file
├── conf.yml                     # Blueprint configuration
├── build.sh                     # Injection script (runs during blueprint -build)
│
├── Controllers/
│   └── ModpackAPIController.php # API endpoints (manualCheck, getStatus)
│
├── admin/
│   ├── controller.php           # Admin panel logic
│   └── view.blade.php           # Admin panel UI
│
├── console/
│   └── CheckModpackUpdates.php  # Laravel cron command
│
├── database/
│   └── migrations/
│       └── 2024_XX_XX_create_modpackchecker_servers_table.php
│
├── routes/
│   └── client.php               # API route definitions
│
└── views/
    ├── server/
    │   └── wrapper.tsx          # Console "Check for Updates" widget
    └── dashboard/
        └── UpdateBadge.tsx      # Dashboard status dot component

Installation

Prerequisites

  • Pterodactyl Panel v1.11+
  • Blueprint Framework (beta-2026-01 or newer)
  • PHP 8.1+
  • Node.js 18+

Steps

  1. Copy extension to Blueprint directory:

    cp -r blueprint-extension /var/www/pterodactyl/.blueprint/extensions/modpackchecker
    chown -R www-data:www-data /var/www/pterodactyl/.blueprint/extensions/modpackchecker
    
  2. Build the extension:

    cd /var/www/pterodactyl
    blueprint -build
    
  3. Compile frontend assets:

    export NODE_OPTIONS=--openssl-legacy-provider
    yarn build:production
    
  4. Run database migration:

    php artisan migrate
    
  5. Restart PHP-FPM:

    systemctl restart php8.3-fpm
    
  6. Set up cron job:

    # Add to /etc/crontab or crontab -e
    0 */6 * * * www-data cd /var/www/pterodactyl && php artisan modpackchecker:check >> /dev/null 2>&1
    

Configuration

Server Egg Variables

For modpack detection, set these variables in your server's egg:

Variable Description Example
MODPACK_PLATFORM Platform name modrinth, curseforge, ftb, technic
MODPACK_ID Platform-specific ID adrenaserver (Modrinth slug)
MODPACK_CURRENT_VERSION Installed version 1.7.0

CurseForge API Key

CurseForge requires an API key. To configure:

  1. Apply for API access at https://docs.curseforge.com/
  2. Go to Admin Panel → Extensions → ModpackChecker
  3. Enter your API key and save

Usage

Dashboard Badge

No action needed — badges appear automatically for servers that:

  • Have MODPACK_PLATFORM egg variable set
  • Have been checked by the cron job at least once

Manual Check

  1. Go to any server's console page
  2. Click "Check for Updates" button
  3. View results showing modpack name and version status

Cron Command

Run manually for testing:

cd /var/www/pterodactyl
php artisan modpackchecker:check

Output:

Starting modpack update check...
Found 12 servers with modpack configuration
Checking: ATM9 Server (a1b2c3d4-...)
  🟠 UPDATE AVAILABLE: All The Mods 9 - 0.2.60
Checking: Vanilla+ (e5f6g7h8-...)
  🟢 Up to date: Vanilla+ - 1.2.0
Modpack update check complete!

Development

Local Development

  1. Enable Blueprint developer mode in admin panel
  2. Make changes in .blueprint/dev/ or .blueprint/extensions/modpackchecker/
  3. Run blueprint -build after changes
  4. Run yarn build:production for frontend changes

Testing API Endpoints

# Manual check (requires auth token)
curl -X POST "https://panel.example.com/api/client/servers/{uuid}/ext/modpackchecker/check" \
  -H "Authorization: Bearer {token}"

# Get all statuses (requires auth token)
curl "https://panel.example.com/api/client/extensions/modpackchecker/status" \
  -H "Authorization: Bearer {token}"

Adding a New Platform

  1. Add check method to ModpackAPIController.php (e.g., checkNewPlatform())
  2. Add to the match() statement in checkVersion()
  3. Add same method to CheckModpackUpdates.php
  4. Update this README

API Reference

POST /api/client/servers/{server}/ext/modpackchecker/check

Manual version check for a specific server. Makes live API call.

Response:

{
    "success": true,
    "platform": "modrinth",
    "modpack_id": "adrenaserver",
    "modpack_name": "Adrenaserver",
    "latest_version": "1.7.0+1.21.1.fabric",
    "status": "checked"
}

GET /api/client/extensions/modpackchecker/status

Get cached status for all servers accessible to the authenticated user.

Response:

{
    "a1b2c3d4-...": {
        "update_available": true,
        "modpack_name": "All The Mods 9",
        "current_version": "0.2.51",
        "latest_version": "0.2.60"
    },
    "e5f6g7h8-...": {
        "update_available": false,
        "modpack_name": "Adrenaserver",
        "current_version": "1.7.0",
        "latest_version": "1.7.0"
    }
}

Troubleshooting

Badge not showing

  1. Check server has MODPACK_PLATFORM variable set
  2. Run cron command manually: php artisan modpackchecker:check
  3. Check modpackchecker_servers table for entries

"CurseForge API key not configured"

  1. Go to Admin → Extensions → ModpackChecker
  2. Enter your CurseForge API key
  3. Key must have mod read permissions

500 errors on check

  1. Check PHP error log: tail -f /var/log/php8.3-fpm.log
  2. Verify controller namespace: Pterodactyl\BlueprintFramework\Extensions\modpackchecker\Controllers
  3. Restart PHP-FPM: systemctl restart php8.3-fpm

Build.sh not running

  1. Ensure file is executable: chmod +x build.sh
  2. Check Blueprint version supports build scripts
  3. Run manually from panel root: bash .blueprint/extensions/modpackchecker/build.sh

Design Decisions

Why cache instead of live checks?

Rate limits. CurseForge allows ~1000 requests/day for personal keys. A busy panel could exhaust that in hours without caching.

Why 2-second sleep in cron?

Prevents burst traffic to APIs. 50 servers × 2 seconds = ~2 minute runtime, which is acceptable for a background job.

Why inline styles in React?

The component is injected into Pterodactyl's build. Adding CSS classes would require modifying their build pipeline. Inline styles are self-contained.

Why separate console widget and dashboard badge?

Different use cases:

  • Dashboard: Quick overview, needs to be fast → cached
  • Console: User wants current info → live API call is acceptable

Credits

Development Team:

  • Architecture design: Gemini AI
  • Implementation: Chroniclers #52, #62, #63 (Claude instances)
  • Project Lead: Michael "Frostystyle" Krause

Part of Firefrost Gaming
Fire + Frost + Foundation = Where Love Builds Legacy 🔥❄️💙