fix(data): migrate WOs from ghost tenants into psauto company

One-time data migration that moves work orders created with wrong
company_id (Octane singleton race condition) back into psauto.
Only moves WOs from companies that have zero users (ghost/test tenants),
so legitimate separate companies are not affected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-06 11:02:39 +00:00
parent c2f87a468f
commit 2323f61d43
@@ -0,0 +1,52 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
/**
* One-time data fix: work orders created with wrong company_id due to
* FrankenPHP/Octane singleton race condition on TenantManager.
*
* Moves all WOs that don't belong to the 'psauto' company into it,
* but only if the source company has no users (i.e. it's a ghost/test
* tenant, not a real separate company with its own data).
*/
return new class extends Migration
{
public function up(): void
{
$psauto = DB::table('companies')->where('slug', 'psauto')->first();
if (! $psauto) {
return; // psauto doesn't exist on this environment — skip
}
// Find companies that have WOs but are NOT psauto
$otherCompanyIds = DB::table('work_orders')
->whereNull('deleted_at')
->where('company_id', '!=', $psauto->id)
->pluck('company_id')
->unique();
foreach ($otherCompanyIds as $companyId) {
// Only move if that company has no users (ghost/test tenant)
$userCount = DB::table('users')->where('company_id', $companyId)->count();
if ($userCount > 0) {
continue; // Real company with users — leave its WOs alone
}
$moved = DB::table('work_orders')
->whereNull('deleted_at')
->where('company_id', $companyId)
->update(['company_id' => $psauto->id]);
\Illuminate\Support\Facades\Log::info(
"Migration fix_work_orders_company_id: moved {$moved} WOs from company_id={$companyId} to psauto company_id={$psauto->id}"
);
}
}
public function down(): void
{
// Not reversible — data migration only
}
};