Product Decisions This Supports
- Content visibility gating: Any feature where a record is "live" or "not live" — CMS articles, product listings, job posts, events, promotions, tenant storefronts — needs one authoritative definition of online. This package turns that definition into a reusable Eloquent scope instead of duplicating
where('is_online', true) (or a date-window clause) across a dozen controllers, API resources, and admin filters.
- Scheduled publish/unpublish roadmaps: If your roadmap includes "publish at a future date" or "auto-expire," a scope-based approach keeps the read-side filter in one place, so adding time-window logic later is a one-file change rather than a search-and-replace across the codebase.
- Build vs. buy: The honest answer is build — the logic is a few lines. The real decision this package informs is standardize vs. drift. If three teams each write their own
scopeOnline, you get subtly different semantics (does it check deleted_at? timezone? status enum vs boolean?) and inconsistent customer-facing behaviour. Adopting or copying a shared convention is the product decision; the package is just the carrier.
- Admin & support tooling: A single named scope lets internal tools ("show only online items," moderation queues, preview modes) reuse production semantics instead of approximating them, which reduces "why can't support see this record?" tickets.
- API contract consistency: Public API responses and listing endpoints inherit the same visibility rule as the web UI, lowering the risk of leaking unpublished content — a compliance and trust issue, not just a bug.
- Delivery velocity on small teams: Low-ceremony adoption means the cost of trying it is measured in minutes, so it fits sprint-level decisions rather than architecture-review decisions.
When to Consider This Package
Consider it when:
- You have multiple models needing the same "online" semantics, and inconsistency between them is a real (or already observed) defect source.
- Your definition is simple and stable — a boolean flag, a status column, or a publish/expire date window.
- The team already leans on Eloquent local scopes and expects
Model::online()->get() to read naturally.
- You want a named, greppable concept in the domain language ("online") that product and engineering share.
- You're comfortable treating it as a vendored snippet: MIT-licensed, small enough to copy into
app/Models/Concerns and own outright if maintenance stops.
Look elsewhere — or write it yourself — when:
- Complex visibility rules are needed: per-user or per-role visibility, per-market/territory availability, entitlement checks, approval workflows, or preview tokens. These belong in a policy/query-object layer, not a scope.
- Performance is the constraint. A scope is a query fragment; it won't solve missing composite indexes on
(is_online, published_at), and naive use inside eager loads can produce surprising SQL. Verify with EXPLAIN before assuming the package helps.
- Maintenance risk matters. With zero stars, zero dependents, and a single maintainer, there is no community signal, no security-response process, and no guarantee of Laravel-major upgrades. Do not adopt this as a transitive dependency of a critical path without a fork plan.
- You need soft-delete / multi-tenancy / global-scope interaction guarantees. Those interactions (global scopes stacking,
withoutGlobalScope, tenancy scoping) are exactly where tiny packages break quietly. Confirm behaviour under test before rollout.
- Your organisation requires provenance. Zero adoption means no external audit trail; expect a security review to ask "who else uses this?" and have no answer.
How to Pitch It (Stakeholders)
For executives (one line): A small, free (MIT) utility that gives the codebase a single, consistent definition of when content is "live," reducing the class of bugs where something is published in one place and hidden in another — at effectively zero licensing cost and a few hours of integration.
For engineering leadership: It is a thin, low-risk convenience layer over Eloquent scopes. The strategic value is convention, not code volume — the logic is small enough that we should be prepared to fork and own it (vendor it into the app) rather than depend on it long-term. Recommend adopting the pattern, pinning the version, and adding a test that asserts our online semantics, so a future swap is a one-file change.
Framing the risk honestly: Adoption metrics are essentially zero (0 stars, 0 dependents, single maintainer). That is acceptable for a five-line scope and unacceptable for infrastructure. Treat it as a reference implementation to copy, not a dependency to trust — that framing removes the maintenance objection while preserving the consistency benefit, and it keeps the decision reversible, which is the property that matters most at this size.