Skip to content

v1.3.0

Latest

Choose a tag to compare

@fzengin19 fzengin19 released this 13 May 09:29
8585601

Critical fix

Closes a P0 data-loss vector: foreign keys subscriptions.plan_id, licenses.plan_id, licenses.user_id, and subscription_items.plan_id were declared ON DELETE CASCADE. A single DELETE FROM plans WHERE … (or User::delete()) physically wiped every dependent row — softDeletes traits did NOT protect because InnoDB / SQLite enforce FK actions below Eloquent.

What changed

  • New idempotent migration 2026_05_13_090000_fix_cascade_delete_protection.php swaps the four foreign keys to RESTRICT and adds plans.deleted_at.
  • Plan model gains SoftDeletes. $plan->delete() archives; $plan->forceDelete() is blocked by the new FKs while dependents exist.
  • Subscription::plan(), License::plan(), SubscriptionItem::plan() chain ->withTrashed() so historical billing keeps resolving archived plans.

BREAKING

User::delete() no longer cascades to licenses. Apps that relied on a hard user-delete to clean up licenses now receive QueryException from the new RESTRICT constraint. Cancel/archive the licenses first. Full rationale in CHANGELOG.md v1.3.0 BREAKING section.

Upgrade

```bash
composer update fzengin19/laravel-subscription-guard
php artisan migrate
```

Tests

282 passed / 932 assertions. PHPStan level 5 clean. CI matrix green across PHP 8.3/8.4 × Laravel 11/12/13 × Ubuntu/Windows.

See CHANGELOG.md and docs/plans/2026-05-13-cascade-delete-protection-plan.md for full detail.