sbamtr/laravel-query-enrich
A Laravel package that adds expressive query enrichment helpers, letting you append computed values, relationships, and metadata to Eloquent results cleanly while reducing boilerplate and keeping data shaping close to your queries.
Architecture fit
Builder (and/or Model), not an infrastructure component. It does not add a service, a queue, a schema change, or a runtime dependency beyond Composer. Blast radius is therefore small and reversible.DBFunction, case->when, and passing subqueries as arguments. This is not a thin selectRaw wrapper — it is a small SQL-expression DSL (functions, conditional CASE expressions, subquery composition) that renders into the query builder. That is still a convenience layer, but it is a larger convenience layer with more of its own semantics to learn and to break.DBFunction, case, when) increases collision candidates slightly.Integration feasibility
composer require, MIT license, no dependents to inherit. The absence of dependents (0) remains a double-edged signal, though 1.4.0 shows external contributors exercising the code, which is mild positive evidence of real-world use.illuminate/* and PHP require constraints — the package may now support a wider range than our pinned version, which is fine, or may have dropped an older major, which is not.laravel-shift. Treat the latter as a signal that the maintainer has wired up ecosystem-standard tooling, not as independent human review.Technical risk
DBFunction arguments, case->when conditions, Enum coercion, and — critically — subquery arguments (fixed in PR #13). Subquery handling in query builders is historically where parameter binding gets lost in favour of string concatenation. Read that diff specifically, not just the README.exists condition. Good that it was found and fixed; notable that it shipped broken. Any expression this package renders must be validated on both our production engine and our test engine, because the package evidently does not guarantee parity across all three of MySQL/Postgres/SQLite.getCountForPagination re-derives selects) change across Laravel majors. A package that now composes subqueries and functions into SELECT has more surface exposed to that rewriting than a pure selectRaw helper.isNull as a case->when parameter) and PR #13 (subquery arguments) change how arguments are interpreted. Nothing here reads as breaking, but a 1.3.x call site could behave differently under 1.4.0. Pin exactly, and diff behavior rather than assuming patch-level safety.Key questions
DBFunction and subquery argument paths touched by PR #13? Show me the code path.exists fix in PR #14 suggests SQLite is the primary test target.case->when and Enum changes in 1.4.0 alter behavior for existing 1.3.x call sites, or are they strictly additive?paginate(), withCount(), and toBase() — now including cases where a subquery is passed to DBFunction?Stack fit
case->when API is the most interesting addition for us: conditional aggregation and derived buckets are exactly the queries teams otherwise write as raw strings. Route those through the package or keep them native — but pick one convention, don't mix.Migration path
QueryEnricher service, or a small EnrichesQueries trait we own) so upstream calls appear in exactly one file. That file is the entire removal cost. This matters more now that the API surface is wider — more surface means more places for call sites to sprinkle.selectRaw/CASE later is a one-day task.Compatibility
1.4.0, no caret range) for the pilot, as before. Given the behavioral changes in PRs #9 and #13, do not float across 1.3.x → 1.4.0 without re-running characterization tests.require block rather than trusting the changelog headline.exists defect.Sequencing
DBFunction, case->when, Enum coercion, and subquery arguments (1 day, up from 0.5 — the surface grew).case->when and one subquery-argument case; assert identical results versus the current native implementation (0.5–1 day).Maintenance
Support
Scaling
SELECT interact badly with covering indexes. Subquery arguments to DBFunction are especially prone to per-row execution if they land in a WHERE or SELECT on a high-volume table. Any enriched query touching a large table needs an EXPLAIN review, same as hand-written SQL — and now more so than before.Failure modes
exists, PR #14). Assume it can happen again.Ramp-up
DBFunction, case->when, Enum coercion, and subquery arguments are four distinct concepts with their own rules.selectRaw, and where the wrapper lives. The wider 1.4.0 API makes this note more necessary, not less — without it the package will be sprinkled ad hoc and the containment strategy quietly evaporates.Recommendation
Adopt conditionally — unchanged in direction, modestly improved in confidence. Pilot 1.4.0 specifically (not a 1.3.x floor) on a bounded set of read queries behind an internal wrapper, gated on an injection audit that explicitly covers the subquery and DBFunction argument paths, and on a two-engine verification of rendered expressions. Do not standardize, and do not adopt at all if the audit finds string interpolation of non-constant values.
How can I help you explore Laravel packages today?