Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sla Timer Laravel Package

sifex/sla-timer

Sifex SLA Timer helps Laravel apps manage service-level agreements with timers that track elapsed and remaining time, pause and resume as needed, and check for breaches. Attach timers to Eloquent models and query active, paused, or expired SLAs through a simple API.

View on GitHub
Deep Wiki
Context7

Getting Started

This release is the first usable baseline for the package, so treat v0.2.0 as the starting point rather than an upgrade.

Requirements before you composer require:

  • PHP ^8.3 — 8.1/8.2 are hard-blocked now (both EOL upstream).
  • nesbot/carbon ^3 — this is the biggest practical gate. Carbon 3 changes diffIn*() return types to float, tightens createFromFormat(), and deprecates a number of helpers. If your app or other packages are pinned to Carbon 2, Composer will refuse to resolve, and force-upgrading will ripple through every date calculation in your codebase. Audit composer why nesbot/carbon before you try.
  • illuminate/collections ^11|^12|^13 — Laravel 11+ only. On Laravel 10 you are out of luck.

Where to look first:

  1. The agenda/schedule classes — this is where your business hours live. Look for the weekly schedule type (the release notes reference Weekly::addTimePeriods) and its from() / to() builder.
  2. AgendaInterface::toPeriods() — the low-level contract that produces the concrete open windows. Read it to understand how pauses and holidays compose, but don't call it directly (see Gotchas).
  3. The test suite — at 98.4% coverage with 28 new tests specifically covering schedules, boundaries, overnight windows, pauses/holidays and breaches, the tests are the most accurate documentation of intended semantics.

First use case — a support-hours SLA timer. You have a ticket opened Friday 17:40 and a policy of "8 business hours". Naive diffInHours() says the ticket blew its SLA over the weekend. You want the clock to run only Mon–Fri 09:00–17:00, skip public holidays, and pause while the ticket is waiting on the customer. Define that as an agenda once, then ask the package for elapsed business time or for the breach timestamp. That single use case exercises every feature in this release, which makes it a good smoke test.

Implementation Patterns

Define agendas as named, reusable config, not inline closures. Put schedule definitions in config/ (or a small AgendaServiceProvider binding) keyed by policy name — support, billing, sev1. You will need the same agenda in the breach calculator, the reporting job, and the UI countdown; three inline definitions will drift.

Model overnight windows explicitly. As of v0.2.0, from('22:00:00')->to('02:00:00') correctly spans midnight rather than returning zero. This is the natural way to express on-call rotations and 24/7 NOC coverage. Note the counterpart rule: equal from/to (09:00:00 → 09:00:00) now means full 24/7 coverage, not a zero-length window. If you previously used equal times as a "disabled" sentinel, that behaviour is now silently inverted — remove those entries rather than relying on them.

Compose holidays and pauses rather than subtracting manually. The intended workflow is: base weekly schedule → holiday/pause agenda → duration calculation. Subtracting holiday hours by hand after the fact is what produced the dropped-final-day bug fixed here; let the package own the arithmetic.

Cache the computed periods, keyed by agenda + date range. The quadratic runtime is gone (a year of daily holidays went from OOM-at-128MB to ~30ms; 10 years ~90ms), so you no longer need to pre-chunk ranges to avoid blowing memory. But 90ms per call is still 90ms — if you render a countdown on every page load, memoise the day's period set in the cache or a request-scoped singleton.

Test with spatie/pest-plugin-test-time and freeze at boundaries. This is now a dev dependency, which is a strong hint about the intended testing style. The bugs fixed in 0.2.0 were all boundary bugs — subject ending before the start time-of-day, midnight crossings, equal from/to. Write tests that freeze the clock at exactly 08:59:59, 09:00:00, 16:59:59, 17:00:00, and across a midnight boundary. Those are the cases that broke.

Integrate at the edges. Keep the package out of your Eloquent models. Compute in an action or a small service (SlaCalculator) that takes a CarbonInterface start, a CarbonInterface end, and an agenda name, and returns elapsed duration or breach status. That keeps the eventual 0.x → 1.0 API churn confined to one class.

Gotchas and Tips

AgendaInterface::toPeriods() is a breaking change. It now returns start/end Carbon pairs instead of CarbonPeriod[]. If any code of yours iterates the result and calls ->start / ->end / ->forEach() on a period object, it breaks. Grep for toPeriods before upgrading. Because this is documented as breaking but shipped in a 0.2.0 patch-level minor, don't trust 0.x semver — pin the exact version ("0.2.0", not "^0.2") until you've read the next changelog.

The Carbon 3 bump is a whole-application event, not a package detail. Even if you never touch this library's API, installing it can force Carbon 3 across your dependency graph. The classic fallout: diffInDays() and friends returning float instead of int (breaks int type hints and array keys), Carbon::createFromTimestamp() stricter validation, and diffIn* no longer auto-absolving negative results in the same way. Run your full test suite after install, not just the SLA tests.

Timezones are the silent killer. A 22:00 → 02:00 window is only meaningful relative to some timezone. Decide once whether agendas are evaluated in the app timezone, the user's timezone, or UTC, and make it explicit at the call site. Mixed-timezone Carbon instances passed into a duration calculation will give you a plausible-looking wrong number rather than an exception.

Watch how the end boundary interacts with the start time-of-day. The headline fix is that a subject ending before the schedule's start time-of-day no longer loses the final day. If you had a workaround in place — padding the end timestamp by a day, or manually adding the tail — remove it, or you'll now double-count.

PHPStan level 8, no excuses. The release ships phpstan.neon.dist and cleared 50 level-8 findings, including a latent Weekly::addTimePeriods flattening bug. That bug means nested time periods may have been silently flattened before — if you build weekly schedules by merging arrays of periods, re-verify the resulting windows after upgrading. Extending the shipped config into your own static analysis is cheap and will catch the next API change for you.

Extension point: because toPeriods() is now a plain data contract (pairs of Carbon), it is a much better seam for custom agendas than it was — you can implement AgendaInterface yourself and return pairs without pulling in CarbonPeriod. That is the supported way to do anything unusual, such as schedules driven by a database table of shifts, rather than reaching into the weekly schedule internals.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console