Skip to main content
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