Skip to content
DocsStart free

Schedules & Adherence

Workforce management in SIP.IO starts with two pieces that already exist elsewhere in the platform: the time-schedule engine that powers business hours, and the agent-state event log that powers reporting. A work schedule is the first applied to an agent; adherence is the second measured against it.

An agent’s shift is an ordinary time_schedule (the same reusable, timezone-aware object used for routing), assigned via two columns on sip_user:

ColumnPurpose
schedule_idFK to the time_schedule that defines the agent’s shift. NULL = no schedule (no adherence measured).
schedule_bypass1 exempts the agent from adherence (overtime, ad-hoc coverage); the report returns "bypass" instead of a number.

Because it’s the standard schedule engine, a shift is expressed as rules, not a bespoke format:

  • weekly: recurring day-of-week rule (dow 0=Sun … 6=Sat) with start_time/end_time as HH:MM. Multiple intervals per day are allowed; overnight shifts (start > end, e.g. 22:0006:00) are handled.
  • date: a single-day override (a one-off shift change, or is_closed = 1 for a day off).
  • date_range: a multi-day override (e.g. a training block or PTO).

Date and date-range rules win over weekly rules; is_closed forces off-shift. Schedule times are evaluated in the schedule’s timezone, falling back to the account timezone, then UTC, consistent with the platform’s UTC-everywhere rule (stored UTC, evaluated in the local IANA zone, DST-aware).

Schedule adherence asks: when the agent was scheduled to be on the phones, were they? It overlays the schedule (when they should be working) against the agent-state event log (what they were actually doing).

The brain samples the window [since, now] at a fixed cadence (every 5 minutes). At each sample time t:

  1. Evaluate the schedule at t. If the agent is off-shift, the sample is skipped entirely: off-shift time is never counted for or against adherence, so scheduled breaks simply don’t appear.
  2. If on-shift, the sample counts toward scheduled. If the agent’s bucket at t is an adherent state, it also counts toward adherent.

Adherent states are the “on the phones” buckets:

adherent = ready | incall | wrapup | ring

Being paused, idle, unreachable, or offline during a scheduled shift is non-adherent. The result:

adherencePct = round( 100 × adherent / scheduled )
scheduledMin = scheduled samples × 5 min
adherentMin = adherent samples × 5 min

So an agent scheduled 9–5 who was ready/on-call for most of it but logged out for an unscheduled 30 minutes scores below 100%; the same agent stepping away during a scheduled break is unaffected.

Adherence comes back per agent in the same admin-gated GET /debug/reports call as the agent KPIs, as adherencePct (with scheduledMin alongside):

adherencePct valueMeaning
integer 0100Adherence over the window.
nullAgent has no schedule_id, or no scheduled time fell in the window.
"bypass"Agent has schedule_bypass = 1.

The schedule model, assignment columns, and adherence computation are live. Still to come:

  • Schedule admin API/UI: schedules are assigned at the data layer today; first-class CRUD endpoints are planned.
  • Auto not-ready outside shift: using the same schedule to flip an agent not-ready when off-shift (today the schedule informs reporting, not enforcement).
  • Per-segment activities: modeling break/lunch/training segments for break-level adherence and shrinkage.
  • Forecasting & scheduling: demand-based shift generation is a longer-term WFM goal; this page is the measurement foundation it will build on.