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.
Assigning a schedule
Section titled “Assigning a schedule”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:
| Column | Purpose |
|---|---|
schedule_id | FK to the time_schedule that defines the agent’s shift. NULL = no schedule (no adherence measured). |
schedule_bypass | 1 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 (dow0=Sun … 6=Sat) withstart_time/end_timeasHH:MM. Multiple intervals per day are allowed; overnight shifts (start > end, e.g.22:00–06:00) are handled.date: a single-day override (a one-off shift change, oris_closed = 1for 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).
Adherence
Section titled “Adherence”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:
- 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. - If on-shift, the sample counts toward
scheduled. If the agent’s bucket attis an adherent state, it also counts towardadherent.
Adherent states are the “on the phones” buckets:
adherent = ready | incall | wrapup | ringBeing paused, idle, unreachable, or offline during a scheduled shift is non-adherent. The result:
adherencePct = round( 100 × adherent / scheduled )scheduledMin = scheduled samples × 5 minadherentMin = adherent samples × 5 minSo 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.
Reading adherence
Section titled “Reading adherence”Adherence comes back per agent in the same admin-gated GET /debug/reports call as the agent KPIs, as adherencePct (with scheduledMin alongside):
adherencePct value | Meaning |
|---|---|
integer 0–100 | Adherence over the window. |
null | Agent has no schedule_id, or no scheduled time fell in the window. |
"bypass" | Agent has schedule_bypass = 1. |
Status & roadmap
Section titled “Status & roadmap”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.