Skip to content

feat(provisioning): robust server creation + reconciliation safeguards#1316

Open
simbabimba-dev wants to merge 5 commits intoCtrlpanel-gg:developmentfrom
simbabimba-dev:development
Open

feat(provisioning): robust server creation + reconciliation safeguards#1316
simbabimba-dev wants to merge 5 commits intoCtrlpanel-gg:developmentfrom
simbabimba-dev:development

Conversation

@simbabimba-dev
Copy link
Collaborator

Problem

Server provisioning was previously handled as a single-step process with no clear state tracking or recovery path. Failures during API calls or database operations could lead to inconsistent states, such as users being charged without receiving a server or servers being created without proper tracking.

Solution

  • Introduce explicit server lifecycle states (provisioning, active, failed, pending_reconciliation)
  • Implement a dedicated service to handle server creation, credit reservation, and failure recovery
  • Add a reconciliation job to resolve uncertain or partial failures
  • Introduce atomic credit handling to prevent race conditions and ensure safe refunds
  • Improve verification of remote server state via external ID lookup

Features

  • Servers are created with a tracked provisioning lifecycle
  • Users are only charged when provisioning is confirmed or safely handled
  • Failed or uncertain provisioning attempts are automatically reconciled
  • Remote server state is verified to prevent orphaned or duplicate servers
  • Credit operations are atomic and protected against race conditions

… safe credit handling with atomic credit ops and recovery safeguards
@simbabimba-dev simbabimba-dev marked this pull request as ready for review March 22, 2026 17:03
Copilot AI review requested due to automatic review settings March 22, 2026 17:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a more resilient server provisioning flow by adding explicit server lifecycle state tracking, atomic credit reservation/refunds, and asynchronous reconciliation to recover from partial/uncertain failures during Pterodactyl provisioning.

Changes:

  • Add servers.status and model status constants to track provisioning lifecycle (provisioning/active/failed/pending_reconciliation).
  • Refactor server creation to reserve credits atomically, persist provisioning state, and schedule post-create + reconciliation jobs.
  • Add Pterodactyl external ID lookup support and expose server status via API resource.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
database/migrations/2026_03_22_191634_add_provisioning_status_to_servers_table.php Adds status column (default provisioning) to support lifecycle tracking.
app/Services/ServerCreationService.php Implements the new provisioning flow with cache locking, credit reservation, and reconciliation scheduling.
app/Services/CreditService.php Centralizes atomic credit reserve/refund operations.
app/Models/Server.php Adds lifecycle status constants and makes status mass-assignable.
app/Jobs/ReconcileServerCreationJob.php Reconciles uncertain provisioning outcomes and refunds on confirmed remote absence.
app/Jobs/PostServerCreationJob.php Emits ServerCreatedEvent asynchronously once a server is confirmed active.
app/Http/Resources/ServerResource.php Exposes status in API responses.
app/Http/Controllers/ServerController.php Switches web server creation to the new ServerCreationService.
app/Http/Controllers/Api/ServerController.php Uses the new creation service and removes direct charging/event emission.
app/Classes/PterodactylClient.php Adds getServerByExternalId() for remote verification during reconciliation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

app/Http/Controllers/Api/ServerController.php:106

  • This endpoint returns HTTP 401 for any exception during creation, including validation/insufficient credits/provisioning failures. 401 is specifically for authentication failures, so API clients will mis-handle these errors. Consider mapping expected failures to 4xx (e.g., 409 for lock/concurrent provisioning, 422 for business-rule violations like insufficient credits) and unexpected exceptions to 500.
        try {
            $server = $this->serverCreationService->handle($user, $product, $data);

            return ServerResource::make($server->fresh());
        } catch (Exception $e) {
            return response()->json([
                'message' => $e->getMessage()
            ], 401);
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@simbabimba-dev simbabimba-dev added this to the V1.2 milestone Mar 22, 2026
@1day2die
Copy link
Collaborator

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants