ShiftPilotUser Manual
Back to app

Compensation & Labor Rules

ShiftPilot can classify and price labor — regular vs. overtime hours, shift differentials, and salaried vs. hourly pay — so you can see estimated labor cost alongside the schedule. It is deliberately not a payroll platform: there are no payroll runs, no tax math, and no money movement. Every dollar figure is labeled estimated labor cost and exists for planning and reporting. Rounding, pay-period boundaries, and final overtime determination stay with your payroll system, which the payroll export can feed later.

Because pay is sensitive, this whole area is gated by capabilities (see Access & Scopes) rather than by role alone — so you can let someone view aggregate cost without exposing individual rates, and edits require a deliberate, audited grant.

Compensation records (/staff/[id])

Each staff member's profile has a Compensation card, visible only to a user who holds the VIEW_COMPENSATION capability at that person's facility. It shows an effective-dated rate history: a list of records, each either Hourly (a $/hr rate) or Salaried (an annual salary, which the estimator prorates over 2,080 hours/yr when it needs an hourly figure).

Records are append-only — a raise is a new record, never an edit of the old one, so history is preserved and the cost engine can resolve the rate that was in force on any worked date. The only in-place change is closing out a record (setting its "effective to" date), which the card offers on the current record.

  • Viewing another person's compensation is audited (compensation.viewed), and the dollar figures are kept out of the audit trail itself.
  • Adding or closing out a record requires the EDIT_COMPENSATION capability, which is grant-only — nobody holds it by default except a System Admin. A Facility Admin can see the card (with VIEW_COMPENSATION) but must be explicitly granted EDIT_COMPENSATION to change pay. Grant it from Access & Scopes.

Labor rules (/org/labor)

The Labor Rules admin page (under Admin & Integrations, gated by MANAGE_LABOR_RULES) is where you configure the two rule types the cost engine uses.

Shift differentials

A differential adds pay for hours worked under certain conditions — a night-shift premium, weekend pay, charge pay, and so on. Each rule has:

  • an amount — either a percent of base (e.g. +15%) or a flat $/hr (e.g. +$4.00/hr);
  • an optional time window (e.g. 19:00–07:00) that may wrap past midnight — only the hours inside the window earn the differential, so a 19:00–07:00 shift against a 23:00–07:00 night window earns 8 differential hours;
  • optional day-of-week, role, and service filters (leave a filter empty to mean "any");
  • a scope — org-wide, or limited to one facility;
  • a stacks toggle — when two rules overlap the same hours, stacking rules both apply; if any overlapping rule is marked highest-only, only the single most valuable rule applies to those hours.

A live preview on the page lets you enter a sample shift (date, times, role, service) and see exactly which differentials would apply and for how many hours — e.g. "a 19:00–07:00 Saturday shift for an RN yields: 8h night diff, 12h weekend diff."

Overtime

An overtime rule sets the weekly threshold (default 40h) and multiplier (default 1.5×), plus an optional daily threshold and multiplier (daily OT is off by default — it's state-dependent). There is one org-default rule plus optional per-facility overrides. The engine carves daily OT out first, then applies weekly OT to the remaining straight-time beyond the threshold, so hours are never double-counted.

How cost is estimated

The pricing engine (src/lib/labor.ts, pure and heavily unit-tested) turns worked hours into an estimate:

  1. Classify the week's hours into regular / weekly-OT / daily-OT buckets.
  2. Apply differentials — split each shift at every rule-window boundary and credit the matching rules.
  3. Estimate cost — price each bucket at the base rate × its multiplier, plus per-hour differential pay, using the compensation record in force on the worked date.

You never see these numbers on the schedule grid itself; they surface in the Staffing Hours report (see Notifications, Audit & Reports), where the cost columns appear only for users who hold VIEW_LABOR_COST_REPORTS.

What's audited

Adding or closing out a compensation record, viewing another person's compensation, and creating or editing a differential/overtime rule are all written to the audit trail. Pay figures themselves are deliberately never snapshotted into audit entries.

Payroll-period export

Payroll Export (admin nav) turns the schedule into a payroll-ready file. Pick a pay period — ShiftPilot knows your organization's cadence (weekly, bi-weekly, semi-monthly, or monthly) and anchor date and offers the recent periods — and download a per-staff CSV (or JSON) of regular/overtime hours, differentials, and estimated cost. The numbers come from the same labor engine as the staffing cost reports, so payroll reconciles to what was actually scheduled. Every export is audited.