Skip to main content

Rules

Rules translate business requirements into scheduling constraints. dabke includes 12 built-in rules that cover common workforce scheduling needs.

How rules work

Rules are passed to ModelBuilder as ruleConfigs — an array of { name, config } entries. Each rule compiles into CP-SAT constraints during builder.compile().
const builder = new ModelBuilder({
  // ... employees, shifts, coverage
  ruleConfigs: [
    { name: "max-hours-week", config: { hours: 40, priority: "MANDATORY" } },
    { name: "min-rest-between-shifts", config: { hours: 11, priority: "HIGH" } },
  ],
});

Priority levels

Each rule has a priority that determines how the solver treats it:
PriorityBehavior
MANDATORYHard constraint — the solver will never violate it, even if it means no solution is found
HIGHSoft constraint with high penalty — strongly preferred but can be violated
MEDIUMSoft constraint with medium penalty
LOWSoft constraint with low penalty — nice to have

Built-in rules

Hours limits

RuleDescription
max-hours-weekMaximum hours per employee per week
min-hours-weekMinimum hours per employee per week
max-hours-dayMaximum hours per employee per day
min-hours-dayMinimum hours per employee per day
{ name: "max-hours-week", config: { hours: 40, priority: "MANDATORY" } }
{ name: "min-hours-week", config: { hours: 20, priority: "MEDIUM" } }

Consecutive days

RuleDescription
max-consecutive-daysMaximum consecutive working days
min-consecutive-daysMinimum consecutive working days (avoid isolated single days)
{ name: "max-consecutive-days", config: { days: 5, priority: "MANDATORY" } }

Shift limits

RuleDescription
max-shifts-dayMaximum number of shifts per employee per day
min-rest-between-shiftsMinimum rest hours between consecutive shifts
{ name: "min-rest-between-shifts", config: { hours: 11, priority: "MANDATORY" } }

Time off

RuleDescription
time-offBlock specific dates/times for an employee
{
  name: "time-off",
  config: {
    employeeId: "alice",
    dates: ["2026-02-14"],
    priority: "MANDATORY",
  },
}

Assignment

RuleDescription
assign-togetherKeep specific employees on the same shifts
employee-assignment-priorityPrefer certain employees for certain roles/times
location-preferencePrefer employees at specific locations

Scoping

Rules can be scoped to apply to specific subsets of employees or time periods. Use the scope field:
{
  name: "max-hours-week",
  config: { hours: 20, priority: "MANDATORY" },
  scope: { roleIds: ["part-time"] },
}
Scope options:
  • employeeIds — apply to specific employees
  • roleIds — apply to employees with specific roles
  • skillIds — apply to employees with specific skills
  • days — apply only on specific dates
  • daysOfWeek — apply only on specific days of the week