laravel-enso/track-who
Laravel Enso Track Who automatically records which users created, updated, or deleted Eloquent models. It provides traits and relationships for creator, updater, and deleter auditing, making it easy to track accountability across your Laravel application.
Architecture fit. track-who addresses a narrow cross-cutting concern — stamping created_by / updated_by / deleted_by on Eloquent models — via traits that hook model events. That is idiomatic Laravel and composes cleanly with existing models without inheritance or middleware. The caveat is that it is a single, small component of the Laravel Enso admin ecosystem: column naming, deletion semantics, and auth resolution all assume Enso conventions. Adopting it standalone means importing a convention set without the rest of the suite, which is fine but reduces the package to "a trait plus a boot hook" in terms of delivered value.
Integration feasibility. Technically straightforward: composer require, add nullable FK columns, apply traits to models. The effective surface area is a handful of traits and observers, so the code is auditable in an hour. Feasibility is therefore high on engineering effort and low on dependency risk; the real question is governance — 29 stars and a low composite score indicate thin adoption signals and a small maintainer base, so the package behaves more like a vendored snippet than a supported dependency.
Technical risk. Low blast radius (it writes columns, it doesn't gate behavior), but three meaningful risks. First, silent degradation: in console commands, queued jobs, seeders, or unauthenticated requests the "who" is null, and nothing fails loudly. Second, coverage gaps: Eloquent mass updates and upsert bypass model events, so bulk jobs will produce unattributed rows and erode trust in the audit data. Third, lifecycle coupling with soft deletes — deleted_by only makes sense if you standardize on soft deletes, and force-deletes/restores need explicit handling.
Key questions. Are we already an Enso shop, or would this be a lone dependency? Do we need attribution only, or a real audit trail (immutable event log, before/after diffs, retention policy) — in which case this package is a component, not a solution? Which guards and identities matter (multi-guard, impersonation, service accounts, API tokens)? What is our policy for historical backfill and null attribution? And who forks it if it goes quiet?
Stack fit. Good fit for a conventional Laravel monolith on the same major version as the package's composer.json constraints — verify Laravel and PHP bounds before committing, since small ecosystem packages lag framework releases. Poor fit if we use UUID/ULID primary keys or non-Eloquent persistence, unless the traits resolve the key type from the model rather than assuming bigint.
Migration path. Add nullable, indexed created_by/updated_by/deleted_by columns (with FKs only if we're comfortable with the delete semantics), backfill historical rows as null or a designated system user, then apply traits model by model. Historical attribution is unrecoverable, so set expectations with stakeholders up front rather than attempting inference.
Compatibility. Check interaction with soft deletes, model caching, and any existing observers or global scopes; duplicate or conflicting attribution logic is the most common integration defect. If we already have an Auditable-style trait or a package like spatie/laravel-activitylog, decide which one owns the concern rather than running both.
Sequencing. (1) Spike: one low-risk model in staging, confirm attribution across web, queue, and CLI paths. (2) Decide build-vs-adopt — a ~40-line trait plus a test is a credible alternative and removes the supply-chain question. (3) Add columns and backfill. (4) Roll out per domain area, highest-value models first. (5) Add contract tests asserting attribution on create/update/delete and asserting the expected null behavior for unauthenticated contexts.
Maintenance. Near-zero runtime maintenance, but nonzero supply-chain maintenance: expect to pin, audit, and eventually fork or vendor. Budget a small recurring line item for dependency review rather than assuming passive safety. Track upstream activity; a dormant repo means we own the code de facto.
Support. Community-only, no SLA, sparse documentation. Internal runbook should document the column semantics, the null meaning, and the intended behavior in background contexts — that documentation is worth more than the package itself.
Scaling. Negligible performance impact: no extra writes or queries beyond the column value, no middleware. The scaling concern is data-governance, not throughput — these columns grow into a de facto audit dataset that people will query and join against, so index them and define retention before, not after, adoption.
Failure modes. Silent null attribution in jobs/commands/seeders; stale or wrong user identity in long-lived queue workers that cache auth state; missing attribution on bulk update()/upsert; incorrect or absent deleted_by when bypassing soft deletes; and misconfiguration (wrong guard, mismatched column names) that fails quietly. Each needs an explicit monitoring or test signal, because none of them throw.
Ramp-up. Hours for a Laravel developer to learn and apply; the cost is in deciding conventions, not in the API. If we adopt, expect most effort in policy (who is "who," what counts as null, how bulk operations are handled) and in the rollout across dozens of models — not in the code.
How can I help you explore Laravel packages today?