kikwik/doctrine-entity-logger-bundle
A Symfony bundle that automatically logs Doctrine entity changes—creates, updates, and deletes—to give you a reliable audit trail. It hooks into Doctrine events and stores a history of modifications, making it easy to track who changed what and when.
Package context. This is a Laravel/PHP audit-logging package. v0.2.0 changes the activation model from presumably broad/implicit logging to an explicit opt-in: a log record is written only for entities whose Eloquent model class carries the LoggableEntity attribute. Note the evidence base here is a single line of release notes plus an empty prior assessment; treat the specifics below as hypotheses to validate in a spike, not confirmed facts. What is confirmed is that the gating condition changed, and that the failure mode is silent.
Architecture fit. Attribute-driven opt-in is idiomatic for modern Laravel: PHP 8 attributes, model-level declaration, discoverable via reflection at boot or listener time. It keeps policy next to the domain model, avoids a central allowlist file drifting from reality, and composes cleanly with booted() hooks, model events, and queued listeners. For a package that intercepts persistence events across the whole model layer, an opt-in attribute is the correct architectural direction — it bounds blast radius and makes audit scope reviewable in code review rather than in config.
Integration feasibility. Low technical effort, moderate governance effort. The mechanics are one attribute per model plus a cache clear. The hard part is enumerating which models should be logged and getting sign-off, because the package will no longer tell you what it is missing.
Technical risk.
composer update, with no exception, warning, or failed health check. This is the dominant risk and it is an audit-integrity risk, not merely a bug.0.x line, a behavior change of this magnitude is permitted by convention but still breaks consumers. Pin the version and treat this as a breaking upgrade in your changelog regardless of what the maintainer calls it.php artisan cache:clear / optimize:clear on deploy), and whether it is evaluated at boot time (fatal on console/queue workers with partial class maps) or at event time.Key questions for the maintainer or spike.
update()/insert() paths that bypass model events?Stack fit. Requires PHP 8.0+ for attribute syntax and a Laravel version whose model-event and service-provider lifecycle the package targets. Confirm composer.json constraints against your current Laravel/PHP matrix before anything else; this is a five-minute check that gates the rest.
Migration path. Do not upgrade in place on faith.
#[LoggableEntity] to the audit-required models on the current version (a no-op if the attribute is unknown to v0.1.x, otherwise harmless), merge, deploy. Then upgrade the package in a separate PR, so any regression has one candidate cause.Compatibility. Treat v0.2.0 as breaking. Pin the exact version in composer.json rather than a caret constraint, and note the exclusion list in-code (a comment or a dedicated NotLoggable marker) so future engineers do not re-add logging by accident.
Sequencing. Dev → staging with parity checks → one bounded production context (lowest-risk domain, ideally one with an existing downstream consumer of the audit data so gaps surface fast) → remaining contexts. Keep the upgrade revertible by version pin alone, with no data migration to unwind.
Maintenance. Pre-1.0 with a small, still-settling API. Budget for one upgrade review per minor release and assume further breaking changes. The package's footprint in your codebase is deliberately tiny (attributes on models), which makes it cheap to fork or replace if maintenance stalls — a meaningful mitigant at this maturity level.
Support. The recurring support cost is not the package, it is human memory. Engineers adding a new audit-relevant model will not know the attribute exists. Mitigate structurally rather than with documentation: add a CI check (PHPArkitect, a PHPStan custom rule, or a Pest architecture test) asserting that models in your audited namespaces carry #[LoggableEntity], and add it to the PR template. Treat "attribute present" as a reviewable invariant, not a convention.
Scaling. Opt-in gating reduces write volume and index pressure — a genuine win, since audit tables are classic unbounded-growth offenders. Confirm the package still writes asynchronously when configured to; if gating moved work to boot time, watch per-request overhead on models touched in hot loops. The countervailing cost is coverage: you are trading log volume for audit completeness, and that trade must be an explicit decision, not a side effect of forgetting an attribute.
Failure modes, ranked by severity.
query()->update(), insert()) bypassing model events entirely — a pre-existing limitation, but gating makes coverage assumptions more visible and more likely to be questioned.Ramp-up. Low for engineers: one attribute, one line of documentation, roughly an hour to competence. The real ramp-up is organizational — a product/compliance decision about which entities are in audit scope, and who owns that list. Budget days for the policy sign-off and hours for the implementation; do not let the small code change imply a small decision.
How can I help you explore Laravel packages today?