Describe the bug
#1301 exposed an issue. When PlayerService::delete() is called for a user who has been the target of espionage or attack missions, the deletion fails with:
SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row:
a foreign key constraint fails (laravel.espionage_reports, CONSTRAINT espionage_reports_planet_user_id_foreign
FOREIGN KEY (planet_user_id) REFERENCES users (id))
Both espionage_reports and battle_reports store the target player's user ID in a planet_user_id column with a foreign key to users.id. Neither table defines ON DELETE CASCADE, so deleting a user that has incoming espionage or battle reports fails at the database level. PlayerService::delete() never cleans up these records.
The ogamex:dev:seed-users command calls PlayerService::delete() on existing test users before re-creating them. This matters because the PR preview re-deployment workflow stops the stack without the -v flag. The database volume survives between deployments. When a new commit is pushed to a PR, the stack is stopped and restarted, migrations run, and then ogamex:dev:seed-users tries to delete the users left over from the previous deployment. If the preview has been actively used (espionage probes, attacks), residual espionage_reports or battle_reports rows block the deletion.
The final teardown on PR close uses -v, which wipes the volume entirely, so that path is unaffected. This only breaks on re-deployments of an already-used preview.
To prevent this in the future, we should add the following to PlayerService::delete() in app/Services/PlayerService.php, before the user is deleted:
// Delete espionage reports where this player was the target.
EspionageReport::where('planet_user_id', $this->getId())->delete();
// Delete battle reports where this player was the target.
BattleReport::where('planet_user_id', $this->getId())->delete();
Describe the bug
#1301 exposed an issue. When
PlayerService::delete()is called for a user who has been the target of espionage or attack missions, the deletion fails with:Both
espionage_reportsandbattle_reportsstore the target player's user ID in aplanet_user_idcolumn with a foreign key tousers.id. Neither table definesON DELETE CASCADE, so deleting a user that has incoming espionage or battle reports fails at the database level.PlayerService::delete()never cleans up these records.The
ogamex:dev:seed-userscommand callsPlayerService::delete()on existing test users before re-creating them. This matters because the PR preview re-deployment workflow stops the stack without the-vflag. The database volume survives between deployments. When a new commit is pushed to a PR, the stack is stopped and restarted, migrations run, and thenogamex:dev:seed-userstries to delete the users left over from the previous deployment. If the preview has been actively used (espionage probes, attacks), residualespionage_reportsorbattle_reportsrows block the deletion.The final teardown on PR close uses
-v, which wipes the volume entirely, so that path is unaffected. This only breaks on re-deployments of an already-used preview.To prevent this in the future, we should add the following to
PlayerService::delete()inapp/Services/PlayerService.php, before the user is deleted: