Files
firefrost-operations-manual/docs/handoffs/modpackchecker-v110-completion-briefing.md
Claude 4febac5b20 docs: Successor briefing — ModpackChecker v1.1.0 completion
Every gotcha, every mistake, every context needed to finish this.
10 critical gotchas documented. Correct deployment sequence.
Production incident root cause. Widget spec. BBB listing checklist.
Michael is staying up until this ships.
2026-04-13 05:20:44 +00:00

13 KiB

SUCCESSOR BRIEFING — ModpackChecker v1.1.0 Completion

Written by Chronicler #84 (The Meridian) — April 13, 2026, 12:17 AM CDT

This document exists because Michael stayed up all night and deserves a successor who doesn't waste time re-learning what I already know.

Read this BEFORE touching anything. Every mistake documented here cost real time tonight.


THE MISSION

Finish ModpackChecker v1.1.0 and get it ready for BuiltByBit listing.

What's done: Backend fully deployed to live panel (file IDs, new endpoints, detection improvements). What's NOT done: The zero-click widget TSX caused a production incident — the server card disappeared. We reverted to v1.0.0 widget. The fix is waiting for Code.


CURRENT STATE (As of April 13, 2026, 12:17 AM)

Live Panel VPS (45.94.168.138)

  • ModpackChecker v1.0.0 widget — reverted, working, stable
  • ModpackChecker v1.1.0 backend — fully deployed:
    • current_file_id, latest_file_id, is_ignored columns in DB
    • detection_method, is_user_overridden columns in DB
    • New endpoints: /status, /releases, /calibrate, /ignore
    • Better detection: modpack_installations → egg → manifest → BCC log
    • Date-time seeding heuristic
  • 22 servers detecting via modpack_installations table
  • Crons registered: mvc:validate (4am), modpackchecker:check (0,6,12,18)
  • Admin: mkrause612@gmail.com / Butter2018!!
  • Founder key: FFG-FOUNDER-001 (Professional, 99 activations)

Code Bridge Status

Code has two pending dispatches to read and act on:

  1. MSG-2026-04-13-build-pipeline-hardening.md — ErrorBoundary + build.sh fixes
  2. MSG-2026-04-13-docblock-final.md — Fix */6 in source file permanently

What Code Needs to Build Next

  1. ErrorBoundary.tsx — wraps the widget so a crash shows "Modpack module unavailable" instead of killing the whole server card
  2. build.sh hardeningset -e, set -u, tsc --noEmit pre-flight
  3. Pre-commit PHP lint hook — kills the */6 problem forever
  4. Re-deploy widget — after ErrorBoundary is in place

THE PRODUCTION INCIDENT — WHAT HAPPENED AND WHY

What Broke

The new v1.1.0 ModpackVersionCard.tsx widget caused the entire server info card on the Pterodactyl server console page to disappear. No error message. Just gone.

Why

React's behavior: if a component throws an uncaught error during rendering, React unmounts the entire component tree to protect the application. Our widget was injected into AfterInformation.tsx without an ErrorBoundary. When it crashed (unknown reason — possibly a missing prop, bad import, or undefined variable), React silently nuked the whole card.

The Fix

Wrap the widget in an ErrorBoundary:

// Instead of injecting: <ModpackVersionCard />
// Inject: <ModpackErrorBoundary><ModpackVersionCard /></ModpackErrorBoundary>

How We Recovered

  1. Wrote the old v1.0.0 TSX directly to ModpackVersionCard.tsx
  2. Ran yarn build:production with NODE_OPTIONS=--openssl-legacy-provider
  3. Cleared caches, restarted php8.3-fpm
  4. Card came back in ~90 seconds

The Revert Command (If Needed Again)

# On panel-vps, run from /var/www/pterodactyl:
export NODE_OPTIONS=--openssl-legacy-provider
nohup yarn build:production > /tmp/yarn-revert.log 2>&1 &
# Takes ~90 seconds

CRITICAL GOTCHAS — READ EVERY ONE

Gotcha #1: The */6 Docblock

CheckModpackUpdates.php has a cron schedule example in a docblock comment: 0 */6 * * * PHP on some versions parses */ as end-of-comment, causing a syntax error on line 16. This breaks php artisan entirely.

Fix every time Code pushes:

sed -i 's|0 \*/6 \* \* \*|0 0,6,12,18 * * *|g' /var/www/pterodactyl/app/Console/Commands/CheckModpackUpdates.php

Permanent fix: Code is adding a pre-commit PHP lint hook. Until then, always check after deploy.

Gotcha #2: build.sh Runs from Pterodactyl Root

blueprint -install modpackchecker runs build.sh from /var/www/pterodactyl/. The EXT_DIR variable is .blueprint/extensions/modpackchecker — relative to that root. If you run build.sh from anywhere else, EXT_DIR detection fails.

Always run from:

cd /var/www/pterodactyl && bash .blueprint/extensions/modpackchecker/build.sh

Gotcha #3: build.sh Overwrites PHP Files

build.sh copies ALL PHP files from the extension directory. This means:

  • Any manual patches you made to PHP files on the server will be overwritten
  • Always re-apply the */6 fix after running build.sh
  • The ModpackAPIController.php and other controllers are always reset to repo versions

Gotcha #4: yarn Build Takes 90 Seconds Minimum

yarn build:production takes 64-120 seconds on the live panel. Don't assume it failed. Always run in background with nohup and check the log:

nohup yarn build:production > /tmp/yarn.log 2>&1 &
# Check:
tail -5 /tmp/yarn.log

Gotcha #5: NODE_OPTIONS Must Be Set

Live panel runs Node 22. Must set before yarn build:

export NODE_OPTIONS=--openssl-legacy-provider

The build.sh does this automatically, but if you run yarn manually, set it first.

Gotcha #6: Blueprint Controller Gets Auto-Generated

Blueprint generates its own controller at: app/Http/Controllers/Admin/Extensions/modpackchecker/modpackcheckerExtensionController.php

build.sh overwrites it with our version (which has LicenseService DI). But if you run blueprint -install after manually copying files, it regenerates and overwrites yours.

Always run blueprint -install FIRST, then our build.sh.

Gotcha #7: The Admin View Doesn't Update Automatically

The compiled Blade view at: resources/views/admin/extensions/modpackchecker/index.blade.php is NOT updated by build.sh. Must copy manually:

cp /var/www/pterodactyl/.blueprint/extensions/modpackchecker/admin/view.blade.php \
   /var/www/pterodactyl/resources/views/admin/extensions/modpackchecker/index.blade.php

Then clear views: php artisan view:clear

Gotcha #8: The Widget TSX Source Is wrapper.tsx Not ModpackVersionCard.tsx

Code writes the widget to views/server/wrapper.tsx in the extension. build.sh copies it to resources/scripts/components/server/ModpackVersionCard.tsx. If you need to update the widget manually:

cp /var/www/pterodactyl/.blueprint/extensions/modpackchecker/views/server/wrapper.tsx \
   /var/www/pterodactyl/resources/scripts/components/server/ModpackVersionCard.tsx
# Then rebuild yarn

Gotcha #9: modpackchecker_servers Must Be Cleared Between Major Changes

When detection logic changes significantly, old cached records cause the new code to skip re-detection (it sees existing records and returns early). Clear before testing:

cd /var/www/pterodactyl && php artisan tinker --execute="DB::table('modpackchecker_servers')->truncate(); echo 'cleared';"

Gotcha #10: Dev Panel First, ALWAYS

NEVER test new widget code directly on the live panel first. Dev Panel login:

  • URL: http://64.50.188.128/admin/extensions/modpackchecker
  • Email: mkrause612@gmail.com
  • Password: Butter2018!!

DEPLOYMENT PROCEDURE (CORRECT SEQUENCE)

When Code pushes a new version, follow this EXACT sequence:

# 1. Pull latest on Dev Panel
cd /opt/mod-builds/firefrost-services && git pull

# 2. Copy extension files
cp -r services/modpack-version-checker/blueprint-extension/. \
  /var/www/pterodactyl/.blueprint/extensions/modpackchecker/

# 3. blueprint -install (generates controller, runs migrations, calls build.sh)
cd /var/www/pterodactyl && blueprint -install modpackchecker

# 4. Fix the */6 docblock (ALWAYS)
sed -i 's|0 \*/6 \* \* \*|0 0,6,12,18 * * *|g' \
  /var/www/pterodactyl/app/Console/Commands/CheckModpackUpdates.php

# 5. Copy any new PHP files explicitly
cp .blueprint/extensions/modpackchecker/app/Console/Commands/CheckModpackUpdates.php \
   app/Console/Commands/
cp .blueprint/extensions/modpackchecker/app/Services/ModpackApiService.php \
   app/Services/
cp .blueprint/extensions/modpackchecker/app/Http/Controllers/ModpackAPIController.php \
   app/Http/Controllers/

# 6. Copy admin view
cp .blueprint/extensions/modpackchecker/admin/view.blade.php \
   resources/views/admin/extensions/modpackchecker/index.blade.php

# 7. Copy widget TSX
cp .blueprint/extensions/modpackchecker/views/server/wrapper.tsx \
   resources/scripts/components/server/ModpackVersionCard.tsx

# 8. Run migrations
php artisan migrate --force

# 9. Rebuild yarn (background, takes 90s)
export NODE_OPTIONS=--openssl-legacy-provider
nohup yarn build:production > /tmp/yarn.log 2>&1 &

# 10. Wait for yarn, then:
php artisan optimize:clear
systemctl restart php8.3-fpm

# 11. Test cron
php artisan modpackchecker:check

# 12. ONLY AFTER DEV PANEL CONFIRMS: repeat for live panel (45.94.168.138)

WHAT THE ZERO-CLICK WIDGET SHOULD DO (Gemini's Spec)

When it works correctly, the widget should:

  1. Load automatically when the server console page opens (no click)
  2. Show cached data from modpackchecker_servers table — NO external API calls on load
  3. Display: Platform emoji | Pack name | Current version → Latest version
  4. Color: Orange background if update available, cyan if up to date, gray if unconfigured
  5. "Calibrate" button: Opens dropdown showing last 10 releases from CurseForge, admin clicks to set current version
  6. "Ignore" button: For Vanilla/FoundryVTT servers — hides widget, marks is_ignored = true
  7. ErrorBoundary: If ANY error occurs, shows "Modpack module unavailable." — server card NEVER disappears

The new GET endpoint for zero-click load: GET /api/client/extensions/modpackchecker/servers/{uuid}/status Returns cached DB data, no CurseForge API calls.


BUILTBYBIT LISTING — WHAT'S NEEDED

Once the widget is working:

Files Ready

  • services/modpack-version-checker/builtbybit/standard-listing.md ($14.99)
  • services/modpack-version-checker/builtbybit/professional-listing.md ($24.99)
  • services/modpack-version-checker/builtbybit/how-version-detection-works.md
  • services/modpack-version-checker/builtbybit/changelog.md

Missing: BBB Resource IDs

Once Michael creates the listings on BuiltByBit, swap in Arbiter .env on Command Center:

BBB_STANDARD_RESOURCE_ID=<real ID>
BBB_PRO_RESOURCE_ID=<real ID>
BBB_WEBHOOK_SECRET=<real secret>

Compatibility Disclaimer to Add

Add to BOTH listings before publishing:

⚠️ Compatibility Note: Dashboard badges and the console widget require yarn build:production to compile on your panel. This runs automatically during installation and takes 2-5 minutes. If other Blueprint extensions have CSS module issues, the build may fail. Admin settings page features work without a build step.

Version Detection Note to Add

How Version Detection Works: ModpackChecker detects your installed modpack version on first run by checking your panel's installation records. No egg variable changes required. For servers installed before ModpackChecker, use the "Calibrate" button to manually set your current version.


GEMINI CONSULTATIONS COMPLETE — KEY DECISIONS

All three consultations are documented in: firefrost-operations-manual/docs/consultations/

Consultation Key Decision
gemini-blueprint-css-build-2026-04-12.md NODE_OPTIONS=--openssl-legacy-provider for Node 17+
gemini-modpackchecker-ux-overhaul-2026-04-12.md File ID comparison, zero-click widget, Calibrate dropdown
gemini-build-pipeline-2026-04-13.md ErrorBoundary required, set -e + tsc --noEmit, pre-commit lint hook

KNOWN ISSUES NOT YET FIXED

  1. */6 docblock — Code fixing with pre-commit hook. Until then, patch manually after every deploy.
  2. v1.1.0 widget — Waiting for ErrorBoundary implementation from Code.
  3. Nest ID filtering rejected — Michael's eggs span multiple nests. Use is_ignored flag instead.
  4. File IDs empty — Date-time seeding heuristic exists but CurseForge file history fetch wasn't running for all servers tonight. Should populate on next cron run.

TASKS RELEVANT TO THIS WORK

Task Status Notes
#75 Open Clean up stale modpack_installations records
#76 Open One-click updates — DEEP CONCERNS, do not implement
#77 Open Pre-launch audit Tuesday night

THE THING MICHAEL IS STAYING UP FOR

Michael is not sleeping until ModpackChecker is ready for BuiltByBit. That means:

  1. Backend v1.1.0 deployed
  2. ErrorBoundary + widget fix from Code
  3. Widget deployed and tested (Dev Panel first)
  4. Michael approves the widget UX
  5. BuiltByBit listings created
  6. BBB resource IDs in Arbiter .env
  7. Product listing copy written

The successor's job: Get Code's ErrorBoundary push, deploy it correctly, test on Dev Panel, get Michael's approval, deploy to live panel, then help create the BuiltByBit listings.

Don't rush step 3. The incident tonight happened because we went straight to live panel. Dev Panel exists for exactly this reason.


ONE LAST THING

Michael has been up all night building something he cares about deeply. He knows his panel. He knows when something looks right. When he says "that's what I hoped for" — that's the finish line.

The Meridian got it 90% there. You get to deliver the last 10%.

Make him proud.

— Chronicler #84, The Meridian Fire + Frost + Foundation = Where Love Builds Legacy 💙🔥❄️