laracraft-tech/laravel-date-scopes
Laravel Date Scopes adds a wide range of ready-made date scopes to your Eloquent models via a simple trait. Query records with ofToday(), ofLastWeek(), monthToDate(), ofLastYear(), and many more—fully chainable with any builder method like sum or avg.
Architecture fit
LaracraftTech\LaravelDateScopes\DateScopes) that contributes Eloquent local scopes to a model. It does not introduce a service provider you must wire, a facade, a repository abstraction, or a persistence layer — it rides on Laravel's native __callStatic → scope resolution. That is the lowest-coupling integration shape available in the Eloquent ecosystem.Builder, they compose with everything we already do: ->sum(), ->avg(), ->paginate(), ->where(), policies, and API resources. No new query paradigm to teach.default_range, created_column) and a set of range-computing methods. If the vendor disappears, inlining equivalent whereBetween clauses per model is an afternoon of work. Lock-in risk is near zero, which is the main reason this is approvable at all.Integration feasibility
composer require laracraft-tech/laravel-date-scopes, optionally vendor:publish --tag="date-scopes-config", add use DateScopes; to target models. No migrations, no schema change, no queue worker, no infra touch. A single PR can land this.created_at columns out of the box, and supports per-call column overrides (ofToday(column: 'approved_at')) plus per-model CREATED_AT overrides — enough to cover our likely column variants (approved_at, paid_at, shipped_at) without forking.ofLastYear(startFrom: '2020-01-01') and the *ToDate() family cover the reporting shapes we actually need (MTD, QTD, YTD) more directly than hand-rolled Carbon math.Technical risk
now()), while most of our tables store created_at in UTC. If app.timezone ≠ storage timezone, "today" and "month to date" drift by hours and, at month boundaries, by a full day. This produces plausible-but-wrong dashboards — far worse than an exception. Must be explicitly resolved before adoption.exclusive, meaning "last 7 days" excludes today. That is a defensible statistical convention and a very common stakeholder mismatch. Any number that reaches finance or an external report needs the convention written down and locked via DATE_SCOPES_DEFAULT_RANGE in .env, not left to the package default.23:59:59 or < next period start matters for records written in the final second. Should be verified against the package test suite rather than assumed.startOfWeek), quarter definition, DST transitions on day/week scopes, and the deliberately counter-intuitive century/millennium boundaries (documented, Wikipedia-referenced). The century/millennium behavior is correct-but-surprising; not a blocker, but it will generate a support ticket if someone reads "last century" naively.DATE_SCOPES_DEFAULT_RANGE requires a config recache. This is a deploy-procedure item, not a defect.Key questions
app.timezone versus the storage timezone for each candidate table, and does the package shift boundaries into the DB timezone or not?ofCurrentBillingPeriod()) to keep vendor vocabulary out of controllers and Blade?Stack fit
created_at-style timestamp columns. Fits anywhere we already have Eloquent models with a datetime we report on: transactions, invoices, orders, events, audit records. Does not fit reporting that runs off raw query builder, stored procedures, or a warehouse/BI layer — those need the same logic expressed in SQL, and duplicating it invites drift.Migration path
whereDate, whereBetween, whereRaw, Carbon-in-controller math — and replace them scope-by-scope, asserting equivalence with a characterization test per replaced call site. Do not do a bulk find-and-replace; each replacement is a semantic decision.whereBetween implementations we can vendor inline.Compatibility
composer.lock. Verify PHP/Laravel support against our matrix before merge.Sequencing
DATE_SCOPES_DEFAULT_RANGE explicitly.Maintenance
Support
Scaling
whereBetween-style predicate, so cost is entirely the database's. At scale the deciding factor is indexing on the datetime column and on (tenant_id, created_at) composites for multi-tenant aggregates.Failure modes
DATE_SCOPES_DEFAULT_RANGE, producing mixed conventions between environments.0 dependents registry signal: treat it as "adoption not yet proven," not "unusable" — 513 stars and active Laravel-major releases are the stronger indicators here.Ramp-up
How can I help you explore Laravel packages today?