Skip to main content

Overview

This example demonstrates restaurant scheduling where diverse staff roles must be coordinated across kitchen, floor, and bar positions. The solution balances skill requirements, prevents fatigue-inducing shift sequences, and ensures fair distribution of premium shifts.
This example showcases multi-skill employees, role-based shift requirements, pattern prohibitions for work-life balance, and tip-shift fairness.

Business Scenario

A restaurant manages:
  • 20 employees across kitchen, floor, and bar roles
  • Split shifts for lunch and dinner service
  • Multi-skilled staff who can work multiple positions
  • Premium evening/weekend shifts with fair distribution
  • No close-then-open (clopening) sequences
  • Minimum rest between late nights and early mornings

Complete Implementation

  • Request
  • Solution
  • Analysis
{
  "employees": [
    {
      "name": "Chef-Marco",
      "skills": [
        { "name": "kitchen", "level": 5 },
        { "name": "head-chef", "level": 5 },
        { "name": "prep", "level": 4 }
      ],
      "availability": [
        "2024-04-01T00:00:00/2024-04-07T23:59:59"
      ],
      "wage": 28
    },
    {
      "name": "Cook-Lisa",
      "skills": [
        { "name": "kitchen", "level": 4 },
        { "name": "prep", "level": 5 },
        { "name": "pastry", "level": 3 }
      ],
      "availability": [
        "2024-04-01T00:00:00/2024-04-07T23:59:59"
      ],
      "wage": 20
    },
    {
      "name": "Server-James",
      "skills": [
        { "name": "floor", "level": 5 },
        { "name": "bar", "level": 3 },
        { "name": "sommelier", "level": 2 }
      ],
      "availability": [
        "2024-04-01T00:00:00/2024-04-07T23:59:59"
      ],
      "preference": ["fri-dinner-floor", "sat-dinner-floor"],
      "wage": 12
    },
    {
      "name": "Server-Emma",
      "skills": [
        { "name": "floor", "level": 4 },
        { "name": "host", "level": 5 }
      ],
      "availability": [
        "2024-04-01T10:00:00/2024-04-01T22:00:00",
        "2024-04-02T10:00:00/2024-04-02T22:00:00",
        "2024-04-03T10:00:00/2024-04-03T22:00:00",
        "2024-04-04T10:00:00/2024-04-04T22:00:00",
        "2024-04-05T16:00:00/2024-04-05T24:00:00",
        "2024-04-06T16:00:00/2024-04-06T24:00:00"
      ],
      "wage": 12
    },
    {
      "name": "Bartender-Mike",
      "skills": [
        { "name": "bar", "level": 5 },
        { "name": "floor", "level": 2 },
        { "name": "mixology", "level": 5 }
      ],
      "availability": [
        "2024-04-01T00:00:00/2024-04-07T23:59:59"
      ],
      "preference": ["fri-bar", "sat-bar"],
      "wage": 15
    },
    {
      "name": "Flex-Alex",
      "skills": [
        { "name": "kitchen", "level": 2 },
        { "name": "floor", "level": 3 },
        { "name": "bar", "level": 2 },
        { "name": "host", "level": 3 }
      ],
      "availability": [
        "2024-04-01T00:00:00/2024-04-07T23:59:59"
      ],
      "wage": 14
    }
  ],
  "shifts": [
    {
      "name": "mon-lunch-kitchen",
      "from": "2024-04-01T10:00:00",
      "to": "2024-04-01T15:00:00",
      "skills": [{ "name": "kitchen" }],
      "min": 2,
      "max": 3,
      "tags": [{ "name": "LUNCH" }, { "name": "KITCHEN" }],
      "priority": 2
    },
    {
      "name": "mon-dinner-kitchen",
      "from": "2024-04-01T17:00:00",
      "to": "2024-04-01T23:00:00",
      "skills": [{ "name": "kitchen" }],
      "min": 3,
      "max": 4,
      "tags": [{ "name": "DINNER" }, { "name": "KITCHEN" }],
      "priority": 1
    },
    {
      "name": "mon-lunch-floor",
      "from": "2024-04-01T11:00:00",
      "to": "2024-04-01T15:00:00",
      "skills": [{ "name": "floor" }],
      "min": 2,
      "max": 3,
      "tags": [{ "name": "LUNCH" }, { "name": "FLOOR" }],
      "priority": 2
    },
    {
      "name": "mon-dinner-floor",
      "from": "2024-04-01T17:00:00",
      "to": "2024-04-01T23:00:00",
      "skills": [{ "name": "floor" }],
      "min": 4,
      "max": 5,
      "tags": [{ "name": "DINNER" }, { "name": "FLOOR" }],
      "priority": 1
    },
    {
      "name": "mon-bar",
      "from": "2024-04-01T17:00:00",
      "to": "2024-04-01T24:00:00",
      "skills": [{ "name": "bar" }],
      "min": 1,
      "max": 2,
      "tags": [{ "name": "EVENING" }, { "name": "BAR" }],
      "priority": 1
    },
    {
      "name": "fri-dinner-floor",
      "from": "2024-04-05T17:00:00",
      "to": "2024-04-06T00:00:00",
      "skills": [{ "name": "floor" }],
      "min": 5,
      "max": 6,
      "tags": [{ "name": "DINNER" }, { "name": "FLOOR" }, { "name": "PREMIUM" }],
      "priority": 1
    },
    {
      "name": "fri-bar",
      "from": "2024-04-05T18:00:00",
      "to": "2024-04-06T01:00:00",
      "skills": [{ "name": "bar" }],
      "min": 2,
      "max": 3,
      "tags": [{ "name": "EVENING" }, { "name": "BAR" }, { "name": "PREMIUM" }],
      "priority": 1
    },
    {
      "name": "sat-dinner-floor",
      "from": "2024-04-06T17:00:00",
      "to": "2024-04-07T00:00:00",
      "skills": [{ "name": "floor" }],
      "min": 6,
      "max": 7,
      "tags": [{ "name": "DINNER" }, { "name": "FLOOR" }, { "name": "PREMIUM" }],
      "priority": 1
    },
    {
      "name": "sat-bar",
      "from": "2024-04-06T18:00:00",
      "to": "2024-04-07T01:00:00",
      "skills": [{ "name": "bar" }],
      "min": 2,
      "max": 3,
      "tags": [{ "name": "EVENING" }, { "name": "BAR" }, { "name": "PREMIUM" }],
      "priority": 1
    },
    {
      "name": "sat-lunch-prep",
      "from": "2024-04-06T08:00:00",
      "to": "2024-04-06T12:00:00",
      "skills": [{ "name": "prep" }],
      "min": 1,
      "max": 2,
      "tags": [{ "name": "MORNING" }, { "name": "PREP" }],
      "priority": 2
    }
  ],
  "rules": [
    {
      "constraint": "COUNTER",
      "type": "HOURS_WORKED",
      "max": 45,
      "period": { "duration": "P7D" }
    },
    {
      "constraint": "SEQUENCE",
      "type": "WORKING_DAYS",
      "max": 6
    },
    {
      "constraint": "COUNTER",
      "type": "WORKING_SHIFT_TYPE",
      "tags": ["PREMIUM"],
      "min": 1,
      "max": 3,
      "period": { "duration": "P7D" }
    }
  ],
  "rests": [
    {
      "tags": ["EVENING"],
      "sequence": "AFTER",
      "min": "PT10H"
    }
  ],
  "patterns": [
    {
      "type": "MULTI_DAY",
      "satisfy": "PROHIBITED",
      "elements": [
        { "type": "ON", "includes": ["EVENING"] },
        { "type": "ON", "includes": ["MORNING"] }
      ],
      "weight": 100
    },
    {
      "type": "SINGLE_DAY",
      "satisfy": "PREFERRED",
      "elements": [
        { "type": "ON", "includes": ["LUNCH"] },
        { "type": "OFF" },
        { "type": "ON", "includes": ["DINNER"] }
      ],
      "weight": 10
    }
  ],
  "requirements": [
    {
      "shifts": ["mon-dinner-kitchen", "fri-dinner-kitchen", "sat-dinner-kitchen"],
      "skill": "head-chef",
      "value": 1
    },
    {
      "shifts": ["fri-dinner-floor", "sat-dinner-floor"],
      "skill": "host",
      "value": 1
    }
  ],
  "fairnessBuckets": [
    {
      "employees": ["Server-James", "Server-Emma", "Flex-Alex"],
      "shifts": ["fri-dinner-floor", "sat-dinner-floor", "fri-bar", "sat-bar"],
      "period": {
        "from": "2024-04-01",
        "to": "2024-04-30"
      }
    }
  ],
  "options": {
    "hardAvailability": true,
    "hardSkill": true
  },
  "weights": {
    "skills": "100hard",
    "minRest": "50hard",
    "pref": "15medium",
    "wages": "2soft"
  }
}

Key Hospitality Features

Multi-Skill Employees

Leverage cross-trained staff:
{
  "employees": [{
    "name": "Flex-Worker",
    "skills": [
      { "name": "kitchen", "level": 2 },
      { "name": "floor", "level": 3 },
      { "name": "bar", "level": 2 }
    ]
  }]
}

Clopening Prevention

Prohibit close-then-open sequences:
{
  "patterns": [
    {
      "type": "MULTI_DAY",
      "satisfy": "PROHIBITED",
      "elements": [
        { "type": "ON", "includes": ["EVENING"] },
        { "type": "ON", "includes": ["MORNING"] }
      ]
    }
  ]
}
“Clopening” (closing then opening) shifts are a major cause of employee burnout. Always prohibit these patterns.

Premium Shift Limits

Ensure fair access to high-tip shifts:
{
  "rules": [
    {
      "constraint": "COUNTER",
      "type": "WORKING_SHIFT_TYPE",
      "tags": ["PREMIUM"],
      "min": 1,
      "max": 3,
      "period": { "duration": "P7D" }
    }
  ]
}

Role Requirements by Service

Ensure key roles during busy periods:
{
  "requirements": [
    {
      "shifts": ["fri-dinner", "sat-dinner"],
      "skill": "head-chef",
      "value": 1
    },
    {
      "shifts": ["fri-dinner-floor", "sat-dinner-floor"],
      "skill": "host",
      "value": 1
    }
  ]
}

Common Hospitality Patterns

{
  "shifts": [
    {
      "name": "lunch-service",
      "from": "11:00",
      "to": "15:00",
      "tags": [{ "name": "LUNCH" }]
    },
    {
      "name": "dinner-service",
      "from": "17:00",
      "to": "23:00",
      "tags": [{ "name": "DINNER" }]
    }
  ],
  "patterns": [{
    "type": "SINGLE_DAY",
    "satisfy": "PREFERRED",
    "elements": [
      { "type": "ON", "includes": ["LUNCH"] },
      { "type": "OFF" },
      { "type": "ON", "includes": ["DINNER"] }
    ]
  }]
}
{
  "shifts": [{
    "name": "private-event",
    "from": "2024-04-15T18:00:00",
    "to": "2024-04-16T02:00:00",
    "skills": [{ "name": "floor" }],
    "min": 8,
    "max": 10,
    "tags": [{ "name": "EVENT" }, { "name": "PREMIUM" }],
    "cost": 200
  }]
}
{
  "requirements": [
    { "shifts": ["dinner-kitchen"], "skill": "head-chef", "value": 1 },
    { "shifts": ["dinner-kitchen"], "skill": "sous-chef", "value": 1 },
    { "shifts": ["dinner-kitchen"], "skill": "line-cook", "value": 2 }
  ]
}
{
  "shifts": [{
    "name": "bar-shift",
    "skills": [
      { "name": "bar" },
      { "name": "alcohol-license" }
    ]
  }],
  "options": { "hardSkill": true }
}

Hospitality-Specific Constraints

Late Night Rest

Enforce rest after late closes:
{
  "rests": [
    {
      "tags": ["LATE"],
      "sequence": "AFTER",
      "min": "PT11H"
    }
  ]
}

Weekend Rotation

Ensure staff get some weekends off:
{
  "rules": [
    {
      "constraint": "COUNTER",
      "type": "WEEKENDS_IDLE",
      "min": 1,
      "period": { "from": "2024-04-01", "to": "2024-04-30" }
    }
  ],
  "options": {
    "idleWeekend": {
      "fromDayOfWeek": "FRIDAY",
      "fromTime": "17:00:00",
      "toDayOfWeek": "SUNDAY",
      "toTime": "23:59:00"
    }
  }
}

Tip Pool Fairness

Balance access to high-earning shifts:
{
  "fairnessBuckets": [
    {
      "employees": ["Server-1", "Server-2", "Server-3", "Server-4"],
      "shifts": ["fri-dinner", "sat-dinner", "sun-brunch"],
      "period": { "from": "2024-04-01", "to": "2024-04-30" },
      "target": "PT24H"
    }
  ]
}