> ## Documentation Index
> Fetch the complete documentation index at: https://docs.erna.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Rules

> Built-in scheduling rules and how to configure them

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()`.

```typescript theme={null}
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:

| Priority    | Behavior                                                                                 |
| ----------- | ---------------------------------------------------------------------------------------- |
| `MANDATORY` | Hard constraint. The solver will never violate it, even if it means no solution is found |
| `HIGH`      | Soft constraint with high penalty. Strongly preferred but can be violated                |
| `MEDIUM`    | Soft constraint with medium penalty                                                      |
| `LOW`       | Soft constraint with low penalty (nice to have)                                          |

## Built-in rules

### Hours limits

| Rule             | Description                         |
| ---------------- | ----------------------------------- |
| `max-hours-week` | Maximum hours per employee per week |
| `min-hours-week` | Minimum hours per employee per week |
| `max-hours-day`  | Maximum hours per employee per day  |
| `min-hours-day`  | Minimum hours per employee per day  |

```typescript theme={null}
{ name: "max-hours-week", config: { hours: 40, priority: "MANDATORY" } }
{ name: "min-hours-week", config: { hours: 20, priority: "MEDIUM" } }
```

### Consecutive days

| Rule                   | Description                                                   |
| ---------------------- | ------------------------------------------------------------- |
| `max-consecutive-days` | Maximum consecutive working days                              |
| `min-consecutive-days` | Minimum consecutive working days (avoid isolated single days) |

```typescript theme={null}
{ name: "max-consecutive-days", config: { days: 5, priority: "MANDATORY" } }
```

### Shift limits

| Rule                      | Description                                   |
| ------------------------- | --------------------------------------------- |
| `max-shifts-day`          | Maximum number of shifts per employee per day |
| `min-rest-between-shifts` | Minimum rest hours between consecutive shifts |

```typescript theme={null}
{ name: "min-rest-between-shifts", config: { hours: 11, priority: "MANDATORY" } }
```

### Time off

| Rule       | Description                                |
| ---------- | ------------------------------------------ |
| `time-off` | Block specific dates/times for an employee |

```typescript theme={null}
{
  name: "time-off",
  config: {
    employeeId: "alice",
    dates: ["2026-02-14"],
    priority: "MANDATORY",
  },
}
```

### Assignment

| Rule                           | Description                                      |
| ------------------------------ | ------------------------------------------------ |
| `assign-together`              | Keep specific employees on the same shifts       |
| `employee-assignment-priority` | Prefer certain employees for certain roles/times |
| `location-preference`          | Prefer employees at specific locations           |

## Scoping

Rules can be scoped to apply to specific subsets of employees or time periods. Use the `scope` field:

```typescript theme={null}
{
  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
