createnl/expires
A Laravel package for adding expiration to Eloquent models. Attach expiry dates to records, automatically scope out or clean up expired entries, and keep outdated data under control with simple, configurable traits and queries.
Architecture fit The package remains a conventional Laravel/PHP library — no evidence of service-provider-level changes, framework version constraint shifts, or new infrastructure dependencies in 0.3. It continues to fit the standard Composer-installed package model our application already assumes. The release is primarily an API-surface and correctness change rather than an architectural one, so it does not require revisiting how the package sits in our layering (controllers → services → package).
Integration feasibility
Straightforward mechanically, but not a drop-in. The headline change — return types moving from bool to Model — is a breaking API change for every existing call site. Eloquent models are truthy, so naive if ($result) checks keep working, but strict comparisons (=== true, !== false), is_bool() guards, and any method signature that declares : bool or accepts a bool will fail — the latter with a TypeError at runtime, not at install time. Feasibility therefore depends on how densely we consume the affected methods; this is a same-day change if call sites are few and tested, and a multi-day change if the package is used broadly across services.
Technical risk
addOnlyExpired fix changes outcomes for existing data. Bug fixes in expiry logic mean records previously skipped may now be processed, or vice versa. Any production dataset that has accumulated under the buggy behaviour will behave differently on first run after upgrade.Key questions
addOnlyExpired bug, and does the fix alter behaviour for already-stored records?Stack fit
No framework-version or PHP-version signal in the release notes, so compatibility with our current Laravel and PHP baselines is unconfirmed and must be verified against composer.json constraints before scheduling. Nothing suggests a mismatch, but nothing confirms parity either.
Migration path Adopt incrementally, not wholesale. Sequence: (1) pin the new version in a single non-production environment; (2) enumerate every call site of the changed methods via static search; (3) classify each as truthiness-safe, strict-comparison-unsafe, or signature-unsafe; (4) convert strict comparisons to explicit null/instance checks rather than relying on model truthiness, which will be clearer and more durable; (5) land the upgrade behind tests that assert on the returned model, not just on success/failure.
Compatibility
Two independent compatibility surfaces. First, runtime compatibility — the return type change is source-compatible for loose checks and source-incompatible for strict ones, and binary-incompatible for any typed signatures. Second, data compatibility — the addOnlyExpired fix implies behavioural drift against existing rows. Treat the data surface as the riskier of the two, because it fails quietly rather than loudly.
Sequencing
Do not bundle this with unrelated dependency work. Land the pinned upgrade and the call-site fixes as one atomic change with its own rollback point, verify addOnlyExpired behaviour against a representative staging dataset before touching production, and only then allow further consumption of the new methods. Defer adoption of the added methods to a follow-up so that the breaking change and the new feature are separately attributable if something regresses.
Maintenance The return-type change is a one-time migration cost, but it also resets our assumptions about API stability. Budget for reviewing each subsequent release rather than accepting minor bumps automatically. The unspecified new methods add surface we now own the upgrade risk on.
Support Expect a short tail of incidents from call sites that were not caught by static search — dynamic dispatch, package-adjacent code, or boolean logic buried in conditionals. The README was updated, which helps onboarding, but no dedicated upgrade guide is evidenced; internal documentation of the new return contract should be written by us, not assumed from upstream.
Scaling
No scaling implications from this release. Return values do not change query volume, memory profile, or concurrency behaviour. The only scaling-adjacent concern is volume-dependent: the addOnlyExpired fix will process a backlog in whatever volume accumulated during the bug's lifetime, so a first production run after upgrade may be materially heavier than steady state. Throttle or dry-run that first execution.
Failure modes
=== true / === false comparisons that now never match — silent, the highest-risk failure mode here.addOnlyExpired fix against historical data — silent, potentially destructive.Ramp-up
Low for engineers already familiar with the package; the mental model shift is small but must be explicit — "these methods return the affected record, not a success flag." Allocate a short internal briefing or ADR note covering the new contract, the pinned version policy, and the staging-first verification of addOnlyExpired. New contributors are the main exposure: a README-level change is easy to miss, and loose truthiness checks will let incorrect assumptions compile and pass review.
How can I help you explore Laravel packages today?