Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Deletable Laravel Package

f9webltd/laravel-deletable

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Soft Deletes Alignment: The package integrates seamlessly with Laravel’s built-in SoftDeletes trait, enabling soft deletion (logical deletion via deleted_at timestamp) while adding customizable restrictions (e.g., business rules, foreign key constraints, or role-based permissions).
  • Trait-Based Design: Leverages Laravel’s Eloquent traits, minimizing boilerplate and adhering to SOLID principles. The Deletable trait can be composed with other traits (e.g., SoftDeletes, Timestamps) without conflicts.
  • Event-Driven Hooks: Supports pre-deletion validation via deleting() and deleting:failed events, allowing for custom logic (e.g., audit logs, cascading checks) before execution.
  • Query Scope Integration: Provides a DeletableScope to filter soft-deleted records in queries, useful for audit trails or restored data retrieval.

Integration Feasibility

  • Minimal Setup: Requires zero configuration for basic usage (e.g., use Deletable; in a model). Advanced features (e.g., custom validation) demand ~5–10 lines of code per model.
  • Laravel Ecosystem Synergy:
    • Works with Laravel Nova/Panel for UI integration (e.g., soft-delete buttons).
    • Compatible with Laravel Scout for search indexing of soft-deleted records.
    • Plays well with Laravel Policies for authorization.
  • Database Agnostic: Functions across MySQL, PostgreSQL, SQLite, and SQL Server (via deleted_at column).

Technical Risk

  • Soft Delete vs. Hard Delete Ambiguity:
    • Risk: Developers might confuse soft deletes (handled by this package) with hard deletes (e.g., Model::forceDelete()).
    • Mitigation: Document explicitly in model contracts (e.g., @method bool forceDelete()) and enforce via Policies.
  • Performance Overhead:
    • Risk: Soft deletes may bloat tables over time, impacting query performance.
    • Mitigation: Implement archival strategies (e.g., deleted_at + is_archived flags) or database partitioning for large datasets.
  • Migration Conflicts:
    • Risk: Adding deleted_at to existing tables may require schema migrations in legacy systems.
    • Mitigation: Use Laravel migrations with nullable timestamps and backfill via a seed job.
  • Testing Complexity:
    • Risk: Soft-deleted records complicate unit/integration tests (e.g., mocking deleted_at).
    • Mitigation: Use repository patterns or test doubles to isolate deletion logic.

Key Questions

  1. Business Requirements:
    • Are hard deletes ever required, or is soft deletion sufficient?
    • What are the retention policies for soft-deleted data (e.g., auto-purge after 30 days)?
  2. Authorization:
    • Should deletion restrictions be role-based (e.g., admins only) or data-specific (e.g., "cannot delete orders with payments")?
  3. Auditability:
    • Do we need to log deletion events (e.g., to a deletion_audit table)?
  4. UI/UX:
    • How should soft-deleted items be displayed/managed in the admin interface (e.g., "Trash" bin)?
  5. Performance:
    • What is the expected scale of soft-deleted records? Are indexes needed on deleted_at?
  6. Fallbacks:
    • Should forceDelete() be disabled entirely or restricted (e.g., via Policies)?

Integration Approach

Stack Fit

  • Laravel Core: Native integration with Eloquent, Events, and Policies.
  • PHP 8.2+: Leverages named arguments, readonly properties, and enums (if used in custom validation).
  • Database: Requires deleted_at column (timestamp, nullable), compatible with all major RDBMS.
  • Frontend: Works with Livewire, Inertia.js, or API-based UIs (e.g., React/Vue) for soft-delete toggles.
  • Testing: Compatible with Pest, PHPUnit, and Laravel Dusk (for UI testing).

Migration Path

  1. Assessment Phase:
    • Audit models to identify deletion-sensitive entities (e.g., Order, User, Invoice).
    • Define restriction rules (e.g., "Cannot delete orders with status=paid").
  2. Implementation:
    • Step 1: Add use Deletable; to target models.
    • Step 2: Run migrations to add deleted_at columns:
      Schema::table('orders', function (Blueprint $table) {
          $table->softDeletes();
      });
      
    • Step 3: Implement custom validation in deleting():
      protected static function bootDeletable()
      {
          static::deleting(function (Model $model) {
              if ($model->hasPaidPayments()) {
                  throw new \Exception("Cannot delete paid orders.");
              }
          });
      }
      
    • Step 4: Update Policies to restrict forceDelete():
      public function delete(User $user, Model $model)
      {
          return $user->isAdmin();
      }
      
  3. UI/UX:
    • Replace "Delete" buttons with soft-delete toggles (e.g., "Mark as Deleted").
    • Add a trash bin route (e.g., /admin/orders/trash) to list/restore soft-deleted records.

Compatibility

  • Laravel Versions: Tested on 11.x, 12.x, 13.x (follows Laravel’s active support).
  • Package Conflicts: None reported; designed for isolation via traits.
  • Third-Party Integrations:
    • Laravel Nova: Use the nova-soft-deletes package for UI support.
    • Laravel Scout: Soft-deleted records can be excluded/included via withoutGlobalScopes().
    • Laravel Cashier: Works with soft-deleted User models (e.g., for subscriptions).

Sequencing

  1. Phase 1: Pilot with low-risk models (e.g., Log, Draft).
  2. Phase 2: Roll out to core business models (e.g., Order, Invoice).
  3. Phase 3: Integrate with UI layers (e.g., Nova, custom admin panels).
  4. Phase 4: Implement audit logging and retention policies.

Operational Impact

Maintenance

  • Proactive:
    • Monitor deleted_at table growth via database metrics (e.g., pg_stat_user_tables).
    • Schedule cleanup jobs for archival/purging:
      // app/Console/Commands/PurgeSoftDeletes.php
      public function handle()
      {
          Model::where('deleted_at', '<', now()->subDays(30))->forceDelete();
      }
      
  • Reactive:
    • Log deletion failures (e.g., deleting:failed events) for debugging.
    • Backup strategy: Ensure soft-deleted data is recoverable before purging.

Support

  • Common Issues:
    • "Record not found" after soft delete: Verify withoutGlobalScopes(SoftDeletes::class) is used in queries.
    • Permission errors: Confirm Policies are updated for forceDelete().
  • Documentation:
    • Maintain a runbook for:
      • Restoring soft-deleted records (Model::withTrashed()->find($id)->restore()).
      • Handling orphaned soft-deleted records (e.g., due to foreign key constraints).
  • Training:
    • Educate devs on soft vs. hard deletes and custom validation patterns.

Scaling

  • Performance:
    • Index deleted_at for large tables:
      Schema::table('orders', function (Blueprint $table) {
          $table->index('deleted_at');
      });
      
    • Partition tables by deleted_at in PostgreSQL/MySQL for >1M soft-deleted records.
  • Concurrency:
    • Soft deletes are atomic (no race conditions), but custom validation may need locks:
      $model->newQuery()->where('id', $model->id)->lockForUpdate()->get();
      
  • Distributed Systems:
    • In multi-tenant apps, ensure deleted_at is tenant-aware (e.g., `tenant
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui