Product Decisions This Supports
- Whether to ship accountability metadata in v1. Userstamps (
created_by, updated_by, deleted_by) is one of the cheapest trust features you can add to an admin surface. The decision it informs: do we answer "who created/changed this record?" on day one, or retrofit it after the first support escalation. Retrofitting means backfilling history you never captured — usually impossible.
- Build vs. buy vs. copy. This package is ~1 trait and a handful of Eloquent event hooks. The realistic build estimate is well under a sprint-day. That makes it a pattern decision, not a procurement decision — the PM question is "do we standardise attribution as an internal convention across all models," not "which vendor do we license."
- Scope of the audit story: attribution vs. change history. Userstamps answers who, not what. If a customer or auditor needs field-level before/after diffs, retention windows, or tamper evidence, this package is the wrong shape and the roadmap item is materially larger (event-sourced or dedicated audit-log table). Deciding this early prevents a half-built audit feature that satisfies nobody.
- Support and incident-response cost model. "Who changed this record?" and "who soft-deleted this account?" are recurring support tickets. Attributions convert a manual archaeology exercise into a query. That's a measurable deflection on support load and a direct input to whether you staff first-line support or push it to engineering.
- Compliance and procurement readiness. SOC 2 / ISO 27001 questionnaires and enterprise security reviews ask about change attribution and access accountability. Having an answer materially shortens sales cycles for mid-market and enterprise deals. This is a checkbox item worth solving cheaply and early.
- Multi-tenant and delegated-admin design. Attribution fields underpin "tenant A owns this record" and "which admin impersonated whom" — both prerequisites for delegating admin access to customers without losing accountability.
- Soft-delete recovery policy. Capturing
deleted_by determines whether you can offer customer-facing restore, and who is authorised to trigger it.
When to Consider This Package
Consider it (specifically, the approach) when:
- You are on Laravel with Eloquent models and want
created_by / updated_by / deleted_by populated automatically from the authenticated user, with zero call-site changes.
- Attribution is sufficient — you need who, not a full diff, and you do not need immutable or tamper-evident storage.
- You have a single, well-defined auth guard and can accept that writes from queues, console commands, seeders, and scheduled jobs have no authenticated user (you will need a fallback, e.g. a system user ID, or those columns stay null).
- You want a documented internal convention rather than each team inventing its own column names and observers.
Look elsewhere — or write it in-house — when:
- Maintenance posture matters. This repository is archived, has 33 stars and zero dependents, and no release cadence. Adding an archived Composer dependency to a maintained application is a supply-chain and security-review liability that no PM should sign off on. The trait is small enough to vendor into your own
app/Models/Concerns directory with tests, which is the sane version of "adopting" it.
- You need field-level change history, retention/erasure policy, actor impersonation records, or append-only guarantees — evaluate Laravel Auditing or a purpose-built audit table instead.
- You have non-Eloquent writes (raw query builder, bulk upserts, external services writing directly) — a trait-based hook cannot cover those, and you will get silent gaps.
- You need multi-guard attribution, polymorphic actors, or API-client attribution alongside human users.
- You are on a current Laravel major and cannot verify compatibility; archived packages routinely break on framework upgrades.
How to Pitch It (Stakeholders)
For executives: This is a low-cost hygiene feature, not a product bet. Attribution — knowing which user created, modified, or deleted a record — is a standard expectation in B2B software and a frequent line item in enterprise security questionnaires. Cost is roughly a day of engineering, not a licence or a vendor contract. The package itself is archived and unsuitable as a dependency; what we adopt is the pattern, implemented and owned internally. Recommend: implement an internal userstamps convention across core models this quarter, and scope a separate, larger decision if we need full change history for compliance.
For engineering: A single trait applied to models, hooking Eloquent's creating / updating / deleting events to stamp the authenticated user's ID, with corresponding belongsTo relations for loading. Do not add the archived package as a dependency — vendor a ~50-line trait into a shared concerns namespace and write it ourselves. Two things to get right up front: (1) a resolved "system" actor for queued jobs, console commands, and seeders so writes outside a request context don't silently produce nulls or throw; (2) a decision on whether these columns are nullable and whether unknown actors are tolerated. Add the columns to migrations in the same PR, add feature tests covering create/update/soft-delete/restore, and document the convention so new models adopt it by default.