Product Decisions This Supports
- Storage-cost and data-hygiene decisions. An "orphan sweeper" exists to find and remove files that no longer have a parent database record. That directly supports decisions like: do we pay down storage spend, do we enforce retention/PII deletion (GDPR/CCPA), and do we need a cleanup job before a compliance audit. Quantify: current bucket size, % of files with no referencing row, monthly storage growth.
- Build vs. buy for cleanup plumbing. Building this in-house means writing a detection query, a deletion command, a dry-run mode, and cron/schedule wiring — plus ongoing maintenance as schemas change. This package now auto-schedules the sweeper at install time, which collapses that work to near-zero and shifts the decision from "should we build a sweeper" to "should we accept this package's sweeper semantics."
- Operational ownership decision (new in v1.1.2). Auto-scheduling during install changes deployment behavior: the package registers a recurring job on the app's scheduler. PM decision: is the Laravel scheduler the right owner of this job in our topology, or do we run cleanup externally (cron, queue worker, data platform job)? Requires answers on single-node vs. multi-node (
onOneServer), environment gating (don't sweep dev/staging buckets by accident), retention/grace window, and dry-run-before-delete.
- Feature/roadmap input on deletion paths. "Document raw-delete cleanup" is the package acknowledging that Eloquent events don't fire for raw SQL deletes, mass deletes, FK cascades, or deletes performed by external systems. For the PM this reframes the sweeper as a safety net, not a substitute for correct deletion handling — it informs roadmap items on soft deletes, cascade policies, and third-party integrations that mutate our data.
- Use-case fit. Strongest where users upload files, records get deleted by admin tooling or bulk scripts, and failed queued jobs leave files behind. Weakest where deletions must be immediate and user-visible (a sweeper is eventually consistent by nature).
- Risk posture. v1.1.2 is a minor release: one feature (install-time scheduling) and one chore (deployment script removed from the repo). No breaking changes, no deprecations. Adoption risk is low, but the destructive nature of a sweeper means the configuration risk is not low.
When to Consider This Package
Consider it when:
- You store files (local or object storage) that are keyed to database records, and records are deleted through paths that don't reliably delete the file — admin panels, bulk operations, raw queries, cascades, imports, or external services.
- You already run
schedule:run in production (or are willing to), so an auto-registered scheduled command has a home.
- You have a measurable orphan problem or a compliance/retention obligation that makes leftover files a liability, not just a cost.
- You want the cleanup behavior to be a documented, repeatable part of the deploy rather than a one-off script someone wrote in 2023.
- You can tolerate eventual consistency: orphans are removed on a schedule, not synchronously with the delete.
Look elsewhere or defer when:
- You need guaranteed, immediate deletion at delete time — this is a sweeper, not a transactional cleanup hook.
- Your files aren't DB-referenced at all (pure log/export buckets), where object-storage lifecycle rules are the cheaper, more appropriate tool.
- You can't verify the sweep query against your schema's polymorphic/soft-delete/cascade semantics, or there's no dry-run mode to validate before enabling destructive deletes.
- Your deployment doesn't use the Laravel scheduler and you don't want a package injecting schedule entries at install time.
- You have a multi-tenant or multi-bucket setup with per-tenant retention rules that a generic sweeper can't express.
- You can't get a rollback story: if the sweeper over-deletes, is there a backup/versioning window on the bucket?
How to Pitch It (Stakeholders)
For executives: This package automates cleanup of files that no longer belong to any record — the storage equivalent of uncollected garbage. Left alone, those files inflate cloud storage bills and, more importantly, become a compliance exposure when they contain customer data we were supposed to delete. v1.1.2 makes setup essentially free: installing the package registers a recurring cleanup job automatically, and the docs now cover the messy cases where records are deleted outside the normal application path. It's a small, low-lock-in dependency with no breaking changes in this release; the main thing we owe it is a short configuration review before it runs against production storage.
For engineering: Treat the sweeper as a backstop for deletion paths we don't control — raw SQL, bulk deletes, FK cascades, failed jobs — not as a replacement for deleting files when we delete records. Before enabling: confirm the sweep is registered on exactly one node in multi-node deployments, gate it per environment so it can't touch non-production buckets, set an explicit grace/retention window so recently-uploaded-but-not-yet-linked files aren't collected, and run a dry-run pass in staging to size the actual orphan set. The removal of the deployment script from the repo in v1.1.2 is packaging hygiene; no functional impact.
Assessment caveat: This is a first-pass assessment derived from the v1.1.2 release notes only; no repository, source review, or usage data was available. Confirm the package's sweep detection logic, dry-run support, soft-delete handling, and scheduler registration behavior against the actual source before committing to adoption.