php-tenant/Jobs/ProcessAccountDeletion.php
Snider d0ad2737cb refactor: rename namespace from Core\Mod\Tenant to Core\Tenant
Simplifies the namespace hierarchy by removing the intermediate Mod
segment. Updates all 118 files including models, services, controllers,
middleware, tests, and composer.json autoload configuration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 16:30:46 +00:00

130 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace Core\Tenant\Jobs;
use Core\Tenant\Models\AccountDeletionRequest;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
/**
* Process a single account deletion request.
*
* This job handles the actual deletion of a user account and all
* associated data. It's designed to be run either via queue dispatch
* or by the scheduled ProcessAccountDeletions command.
*/
class ProcessAccountDeletion implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The number of times the job may be attempted.
*/
public int $tries = 3;
/**
* The number of seconds to wait before retrying the job.
*/
public int $backoff = 60;
/**
* Create a new job instance.
*/
public function __construct(
public AccountDeletionRequest $deletionRequest
) {}
/**
* Execute the job.
*/
public function handle(): void
{
// Reload to ensure we have fresh data (may have been deleted)
$request = AccountDeletionRequest::find($this->deletionRequest->id);
if (! $request) {
Log::info('Skipping account deletion - request no longer exists', [
'deletion_request_id' => $this->deletionRequest->id,
]);
return;
}
// Verify the request is still valid for deletion
if (! $request->isActive()) {
Log::info('Skipping account deletion - request no longer active', [
'deletion_request_id' => $request->id,
]);
return;
}
$user = $request->user;
if (! $user) {
Log::warning('User not found for deletion request', [
'deletion_request_id' => $request->id,
]);
$request->complete();
return;
}
// Update local reference
$this->deletionRequest = $request;
$userId = $user->id;
DB::transaction(function () use ($user) {
// Mark request as completed
$this->deletionRequest->complete();
// Delete all workspaces owned by the user
if (method_exists($user, 'ownedWorkspaces')) {
$user->ownedWorkspaces()->each(function ($workspace) {
$workspace->delete();
});
}
// Hard delete user account
$user->forceDelete();
});
Log::info('Account deleted successfully', [
'user_id' => $userId,
'deletion_request_id' => $this->deletionRequest->id,
'via' => 'job',
]);
}
/**
* Handle a job failure.
*/
public function failed(\Throwable $exception): void
{
Log::error('Failed to process account deletion', [
'deletion_request_id' => $this->deletionRequest->id,
'error' => $exception->getMessage(),
]);
}
/**
* Get the tags that should be assigned to the job.
*
* @return array<int, string>
*/
public function tags(): array
{
return [
'account-deletion',
'user:'.$this->deletionRequest->user_id,
];
}
}