refactor(modpackchecker): Batch 1 fixes from Gemini review

Routes (client.php):
- Removed redundant prefixing - Blueprint auto-prefixes with identifier
- Clean paths: /servers/{server}/check and /status
- Added clear comments documenting resulting URLs

Migration:
- Changed enum('status') to string('status') for future flexibility
- Added foreign key constraint: server_uuid -> servers.uuid with cascade delete
- Ensures 'RV-Ready' data integrity - no ghost data on server deletion

Build Script:
- Removed redundant PHP copy logic (Blueprint handles via requests.app)
- Fixed dead code that referenced wrong path for console command
- More targeted sed patterns for better stability
- Added author/version header

Reviewed by: Gemini AI (Architecture Consultant)
Signed-off-by: Claude (Chronicler #63) <claude@firefrostgaming.com>
This commit is contained in:
Claude (Chronicler #63)
2026-04-06 11:27:46 +00:00
parent 845d121fb2
commit 35315c2e81
3 changed files with 33 additions and 34 deletions

View File

@@ -1,9 +1,17 @@
#!/bin/bash #!/bin/bash
# build.sh - Executes automatically during blueprint -build # =============================================================================
# Phase 5: Console widget + Dashboard badge injection # MODPACK VERSION CHECKER - BUILD SCRIPT
# =============================================================================
#
# Executes automatically during `blueprint -build`
# Injects React components into Pterodactyl's frontend
#
# @author Firefrost Gaming / Frostystyle <dev@firefrostgaming.com>
# @version 1.0.0
# =============================================================================
echo "==========================================" echo "=========================================="
echo "ModpackChecker Build Script - Phase 5" echo "ModpackChecker Build Script v1.0.0"
echo "==========================================" echo "=========================================="
# Determine the extension source directory # Determine the extension source directory
@@ -20,7 +28,7 @@ fi
echo "Using extension directory: $EXT_DIR" echo "Using extension directory: $EXT_DIR"
# =========================================== # ===========================================
# 1. CONSOLE WIDGET (wrapper.tsx → ModpackVersionCard) # 1. CONSOLE WIDGET INJECTION
# =========================================== # ===========================================
echo "" echo ""
echo "--- Console Widget ---" echo "--- Console Widget ---"
@@ -35,20 +43,20 @@ fi
# Inject into ServerConsoleContainer.tsx # Inject into ServerConsoleContainer.tsx
if ! grep -q "ModpackVersionCard" resources/scripts/components/server/console/ServerConsoleContainer.tsx 2>/dev/null; then if ! grep -q "ModpackVersionCard" resources/scripts/components/server/console/ServerConsoleContainer.tsx 2>/dev/null; then
sed -i '1i import ModpackVersionCard from "@/components/server/ModpackVersionCard";' resources/scripts/components/server/console/ServerConsoleContainer.tsx sed -i '1i import ModpackVersionCard from "@/components/server/ModpackVersionCard";' resources/scripts/components/server/console/ServerConsoleContainer.tsx
sed -i '/<ServerDetailsBlock className/a \ <ModpackVersionCard />' resources/scripts/components/server/console/ServerConsoleContainer.tsx # Place after ServerDetailsBlock for consistent positioning
sed -i '/<ServerDetailsBlock/a \ <ModpackVersionCard />' resources/scripts/components/server/console/ServerConsoleContainer.tsx
echo "✓ Injected ModpackVersionCard into ServerConsoleContainer.tsx" echo "✓ Injected ModpackVersionCard into ServerConsoleContainer.tsx"
else else
echo "○ ModpackVersionCard already present in ServerConsoleContainer.tsx" echo "○ ModpackVersionCard already present in ServerConsoleContainer.tsx"
fi fi
# =========================================== # ===========================================
# 2. DASHBOARD BADGE (UpdateBadge.tsx) # 2. DASHBOARD BADGE INJECTION
# =========================================== # ===========================================
echo "" echo ""
echo "--- Dashboard Badge ---" echo "--- Dashboard Badge ---"
if [ -f "$EXT_DIR/views/dashboard/UpdateBadge.tsx" ]; then if [ -f "$EXT_DIR/views/dashboard/UpdateBadge.tsx" ]; then
# Ensure target directory exists
mkdir -p resources/scripts/components/dashboard mkdir -p resources/scripts/components/dashboard
cp "$EXT_DIR/views/dashboard/UpdateBadge.tsx" resources/scripts/components/dashboard/UpdateBadge.tsx cp "$EXT_DIR/views/dashboard/UpdateBadge.tsx" resources/scripts/components/dashboard/UpdateBadge.tsx
echo "✓ Copied UpdateBadge.tsx" echo "✓ Copied UpdateBadge.tsx"
@@ -58,30 +66,19 @@ fi
# Inject into ServerRow.tsx (dashboard server list) # Inject into ServerRow.tsx (dashboard server list)
if ! grep -q "UpdateBadge" resources/scripts/components/dashboard/ServerRow.tsx 2>/dev/null; then if ! grep -q "UpdateBadge" resources/scripts/components/dashboard/ServerRow.tsx 2>/dev/null; then
# Add import at top
sed -i '1i import UpdateBadge from "@/components/dashboard/UpdateBadge";' resources/scripts/components/dashboard/ServerRow.tsx sed -i '1i import UpdateBadge from "@/components/dashboard/UpdateBadge";' resources/scripts/components/dashboard/ServerRow.tsx
# Targeted replacement: append badge after server name
# Inject badge right after the server name sed -i 's|{server.name}</p>|{server.name}<UpdateBadge serverUuid={server.uuid} /></p>|' resources/scripts/components/dashboard/ServerRow.tsx
# The pattern looks for the server name paragraph and adds our badge inside it
sed -i 's|<p css={tw`text-lg break-words`}>{server.name}</p>|<p css={tw`text-lg break-words`}>{server.name}<UpdateBadge serverUuid={server.uuid} /></p>|' resources/scripts/components/dashboard/ServerRow.tsx
echo "✓ Injected UpdateBadge into ServerRow.tsx" echo "✓ Injected UpdateBadge into ServerRow.tsx"
else else
echo "○ UpdateBadge already present in ServerRow.tsx" echo "○ UpdateBadge already present in ServerRow.tsx"
fi fi
# =========================================== # ===========================================
# 3. CONSOLE COMMAND (CheckModpackUpdates.php) # NOTE: Console Command (CheckModpackUpdates.php)
# =========================================== # ===========================================
echo "" # The PHP console command is automatically merged by Blueprint via
echo "--- Console Command ---" # conf.yml's `requests.app: "app"` setting. No manual copy needed.
if [ -f "$EXT_DIR/console/CheckModpackUpdates.php" ]; then
cp "$EXT_DIR/console/CheckModpackUpdates.php" app/Console/Commands/CheckModpackUpdates.php
echo "✓ Copied CheckModpackUpdates.php to app/Console/Commands/"
else
echo "⚠ CheckModpackUpdates.php not found, skipping cron command"
fi
echo "" echo ""
echo "==========================================" echo "=========================================="

View File

@@ -11,24 +11,25 @@ return new class extends Migration
*/ */
public function up(): void public function up(): void
{ {
// Note: Blueprint extensions use the blueprint->dbGet/dbSet methods
// which store data in the existing settings table.
// This migration creates a table for per-server modpack tracking.
Schema::create('modpackchecker_servers', function (Blueprint $table) { Schema::create('modpackchecker_servers', function (Blueprint $table) {
$table->id(); $table->id();
// Use the string UUID to match Pterodactyl's server identification
$table->string('server_uuid')->unique(); $table->string('server_uuid')->unique();
$table->string('platform')->nullable(); // curseforge, modrinth, technic, ftb $table->string('platform')->nullable(); // curseforge, modrinth, technic, ftb
$table->string('modpack_id')->nullable(); $table->string('modpack_id')->nullable();
$table->string('modpack_name')->nullable(); $table->string('modpack_name')->nullable();
$table->string('current_version')->nullable(); $table->string('current_version')->nullable();
$table->string('latest_version')->nullable(); $table->string('latest_version')->nullable();
$table->enum('status', ['up_to_date', 'update_available', 'error', 'unknown'])->default('unknown'); // Flexible string status instead of Enum for future extensibility
$table->string('status')->default('unknown');
$table->timestamp('last_checked')->nullable(); $table->timestamp('last_checked')->nullable();
$table->text('error_message')->nullable(); $table->text('error_message')->nullable();
$table->timestamps(); $table->timestamps();
// Index for efficient lookups // Foreign key - cascade delete when server is removed
$table->foreign('server_uuid')->references('uuid')->on('servers')->onDelete('cascade');
// Indexes for efficient lookups
$table->index('status'); $table->index('status');
$table->index('last_checked'); $table->index('last_checked');
}); });

View File

@@ -8,12 +8,13 @@ use Pterodactyl\Http\Controllers\ModpackAPIController;
| ModpackChecker Client Routes | ModpackChecker Client Routes
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| |
| These routes are automatically wrapped in Pterodactyl's client auth | Blueprint auto-prefixes these with /api/client/extensions/modpackchecker/
| middleware. The {server} parameter is injected automatically. | So our paths here are relative to that prefix.
| |
*/ */
Route::post('/servers/{server}/ext/modpackchecker/check', [ModpackAPIController::class, 'manualCheck']); // Resulting URL: /api/client/extensions/modpackchecker/servers/{server}/check
Route::post('/servers/{server}/check', [ModpackAPIController::class, 'manualCheck']);
// Dashboard badge status endpoint - returns all servers' update status in one call // Resulting URL: /api/client/extensions/modpackchecker/status
Route::get('/extensions/modpackchecker/status', [ModpackAPIController::class, 'getStatus']); Route::get('/status', [ModpackAPIController::class, 'getStatus']);