Product Decisions This Supports
- Content lifecycle modeling (build vs. buy): Standardizes the "draft → scheduled → published → expired" vocabulary that otherwise gets reinvented per model. A PM can treat publishing states as a platform primitive rather than a per-feature decision.
- Time-based merchandising roadmap: Schedule windows, expiry, highlights, and limits map directly to campaign embargoes, seasonal promotions, featured placements, and time-boxed catalog visibility — cheap to ship without new infrastructure.
- Feature sequencing: Because states, PHP-side checks, mutators, and transition events share one implementation, PMs can promise "publish later," "auto-expire," and "featured now" as small increments rather than separate epics.
- Consistency across surfaces: Matching query scopes (
publishedWithin, createdThisWeek) and in-PHP checks reduce the classic mismatch where admin UI says published but the storefront query disagrees — fewer QA cycles and support tickets.
- Compliance and retention: Expiry scopes give a declarative hook for time-limited content exposure, useful when legal/marketing require content to stop surfacing on a date.
- Low-cost experimentation: Adopting it keeps state logic out of controllers/jobs, so changing a publishing rule is a config-level decision, not a migration project.
When to Consider This Package
Consider it when:
- Two or more Eloquent models need published/scheduled/draft semantics, active flags, or schedule windows — the second model is where the boilerplate cost becomes real.
- Requirements include date-driven visibility (embargo, expiry, "new this week," "published within N days") rather than a single boolean.
- The team already runs PHP 8.2+ and Laravel 11 or 12 and wants convention over a bespoke trait.
- You want transition events available for notifications, cache invalidation, or search indexing without writing them per model.
- You need a v1.0.0-stable dependency with a small surface area and no external services.
Look elsewhere when:
- Only one model needs a single
is_active boolean — plain Eloquent is cheaper than a dependency.
- You need an actual workflow engine: multi-step approvals, role-gated transitions, audit trails, or state-machine guarantees. A dedicated state-machine package is the better fit.
- Requirements are content versioning, editorial review, or localization workflows — that is a CMS domain, not a scoping library.
- You are on Laravel 10 or earlier, or PHP below 8.2.
- You cannot tolerate a young, single-maintainer package in the critical path without pinning and internal test coverage.
Risk note: v1.0.0 is the first stable release. Pin the version, keep the trait usage behind your own base model or service, and add feature tests asserting your expected scope semantics so any future major bump is a controlled upgrade rather than a scramble.
How to Pitch It (Stakeholders)
For executives: This is a small, free, open-source composer dependency that replaces hand-written publishing and scheduling logic with a consistent, tested one. It lets us ship "publish later," "auto-expire," "featured now," and "new this week" as small increments across multiple product surfaces, with less custom code to maintain and fewer bugs where the admin and the storefront disagree about whether something is live. Cost is a line in composer.json; there is no new service, no vendor contract, and no migration.
For engineering: Declarative state and date scopes for Eloquent — published/scheduled/draft, active flags, schedule windows, expiry, highlights, limits, composites — plus matching in-PHP checks, mutators, period scopes (createdThisWeek, publishedWithin), default states, and transition events. Requires PHP 8.2+ and Laravel 11/12. Stable v1.0.0, so the API is committed; it is thin and trait-based, with no infrastructure footprint. We should pin the version and wrap usage in our own base model so we retain the option to swap it out if the package stalls.