Looking to hire Laravel developers? Try LaraJobs

laravel-sweep maintained by anjan-talukdar

Description
A powerful, multi-database, storage-agnostic data purging and sequence reset library for Laravel.
Author
Anjan Talukdar
Last update
2026/11/02 09:11 (dev-main)
License
Links
Downloads
1

Comments
comments powered by Disqus

Laravel Sweep 🧹

Latest Version on Packagist Total Downloads Software License PHP Version Laravel Version

Sweep is an open-source, multi-database, storage-agnostic data purging and sequence reset library for Laravel applications.

It empowers developers, staging environments, QA teams, and CI/CD pipelines to selectively or completely sweep away user, tenant, and transactional records—along with associated physical storage files and S3 media—while strictly safeguarding master reference tables and system assets.


🌟 Why Sweep?

  • Multi-Database Native: Built-in specialized drivers for MySQL, PostgreSQL, and SQLite. Handles foreign key constraints and resets table auto-increment sequences (AUTO_INCREMENT = 1, pg_get_serial_sequence with setval, or sqlite_sequence).
  • Spatie Media Library & S3 Agnostic: Automatically discovers eligible media models and cleanly deletes media files from Amazon S3, Local, R2, or MinIO via Spatie Media Library, with strict protection for catalog/system templates.
  • Master Table Whitelist: Hardcoded and configurable protection ensuring tables like countries, states, migrations, roles, permissions, and reference catalogs are never accidentally dropped or truncated.
  • Granular Domain Groups: Organize tables child-first into logical business domains (e.g., chat, billing, events, users). The all group is automatically synthesized.
  • Rich Dry-Run Previews: Full --dry-run inspection table reporting exact row counts and media assets before touching any data.
  • Headless & Interactive: Works interactively via Laravel Prompts multiselect(), or non-interactively in CI/CD using --force.
  • Programmatic API: Use the Sweep facade directly inside PHPUnit / Pest tests, seeders, or admin dashboards.

📦 Installation

Install Sweep via Composer:

composer require anjan-talukdar/laravel-sweep

Publish the configuration file:

php artisan vendor:publish --tag=sweep-config

This will create config/sweep.php in your application.


⚙️ Configuration

config/sweep.php lets you define your domain groups, master safeguards, and storage cleaner rules:

return [
    /*
    |--------------------------------------------------------------------------
    | Default Command Name
    |--------------------------------------------------------------------------
    | The Artisan command registered by Sweep. Default is 'sweep'.
    */
    'command_name' => env('SWEEP_COMMAND', 'sweep'),

    /*
    |--------------------------------------------------------------------------
    | Universal Master & Reference Tables (NEVER Swept)
    |--------------------------------------------------------------------------
    | These tables can NEVER be truncated or deleted, regardless of input.
    */
    'protected_tables' => [
        'migrations',
        'countries', 'states', 'cities',
        'roles', 'permissions', 'role_has_permissions',
        'system_settings', 'plans', 'plan_features',
    ],

    /*
    |--------------------------------------------------------------------------
    | Protected Spatie Media Models
    |--------------------------------------------------------------------------
    | Media records for these model classes will NEVER be deleted from S3/disk.
    */
    'protected_media_models' => [
        'App\Models\SystemTemplate',
        'App\Models\BrandAsset',
    ],

    /*
    |--------------------------------------------------------------------------
    | Functional Domain Groups
    |--------------------------------------------------------------------------
    | Map tables child-first to satisfy foreign keys.
    */
    'groups' => [
        'chat' => [
            'label' => 'Chat Messages & Conversations',
            'tables' => [
                'messages',
                'conversations',
            ],
        ],

        'billing' => [
            'label' => 'Subscriptions, Invoices & Usages',
            'tables' => [
                'invoice_items',
                'invoices',
                'payments',
                'subscriptions',
            ],
        ],

        'users' => [
            'label' => 'Users, Sessions & Tokens',
            'tables' => [
                'sessions',
                'password_reset_tokens',
                'model_has_roles',
                'users',
            ],
            'media_models' => [
                \App\Models\User::class, // Purges user avatars on S3/local
            ],
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Physical Storage Paths (Local / S3 / R2)
    |--------------------------------------------------------------------------
    */
    'storage_paths' => [
        'temp' => [
            ['disk' => 'local', 'path' => 'temp-exports'],
            ['disk' => 's3', 'path' => 'temporary-uploads'],
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Post-Purge Lifecycle Hooks
    |--------------------------------------------------------------------------
    */
    'after_cleaning' => [
        // App\Actions\ResetTenantCaches::class,
    ],
];

🚀 CLI Usage

Interactive Selection

Run without arguments to select domain groups via an interactive multi-select menu:

php artisan sweep

Specific Domain Groups

Target one or multiple groups (comma-separated):

php artisan sweep --group=chat,billing

Dry-Run Simulation (Preview Without Modifying)

Simulate cleanup and view an inspection table with row counts:

php artisan sweep --group=all --dry-run

Sample output:

+---------+--------------------+-------------------+-------------------------------+
| Group   | Target Table       | Records to Purge  | Planned Action                |
+---------+--------------------+-------------------+-------------------------------+
| chat    | messages           | 14,250            | Delete & Reset Sequence -> 1  |
| chat    | conversations      | 820               | Delete & Reset Sequence -> 1  |
| users   | sessions           | 3,100             | Delete & Reset Sequence -> 1  |
| users   | users              | 412               | Delete & Reset Sequence -> 1  |
+---------+--------------------+-------------------+-------------------------------+
Total records eligible for purge: 18,582
Eligible Spatie Media records (and physical disk/S3 files): 412
[DRY RUN COMPLETE] Zero database rows or disk files were modified.

Keep Storage (Preserve S3 / Local Files)

Purge database records and reset primary key sequences, but leave S3/local media intact:

php artisan sweep --group=all --keep-storage

Headless & CI/CD Execution

Bypass interactive prompts (required when running in production):

php artisan sweep --group=all --force

💻 Programmatic API (Facade)

You can call Sweep directly from PHP inside test suites, seeders, or controllers:

use AnjanTalukdar\Sweep\Facades\Sweep;

// Run sweep for specific groups
Sweep::run(groups: ['chat', 'billing'], keepStorage: false);

// Run dry-run simulation and inspect results
$report = Sweep::dryRun(groups: ['all']);

echo "Total records eligible: " . $report->totalRecords;
echo "Eligible Spatie media files: " . $report->eligibleMediaCount;

foreach ($report->tables as $item) {
    echo "{$item['table']}: {$item['count']} rows\n";
}

🗄️ Multi-Database Engine Handling

Database Engine Foreign Key Handling Sequence / Auto-Increment Reset
PostgreSQL Transactional child-first delete; or TRUNCATE TABLE "..." RESTART IDENTITY CASCADE on full wipe. Resolves sequence via pg_get_serial_sequence(?, 'id') and executes SELECT setval(seq, 1, false).
MySQL / MariaDB Sets SET FOREIGN_KEY_CHECKS = 0; before deletes and restores SET FOREIGN_KEY_CHECKS = 1;. Executes ALTER TABLE \table` AUTO_INCREMENT = 1;`.
SQLite Sets PRAGMA foreign_keys = OFF; before deletes and restores PRAGMA foreign_keys = ON;. Executes DELETE FROM sqlite_sequence WHERE name = ?;.

🔔 Events

Sweep dispatches framework events throughout its lifecycle:

  • AnjanTalukdar\Sweep\Events\SweepStarting: Dispatched before operations start (includes $selectedGroups and $dryRun flag).
  • AnjanTalukdar\Sweep\Events\TableSwept: Dispatched after each database table is purged.
  • AnjanTalukdar\Sweep\Events\SweepCompleted: Dispatched when the sweep operation finishes.

🧪 Testing

composer test

📄 License

Laravel Sweep is open-sourced software licensed under the MIT license.