dabke 0.78.2 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +68 -31
- package/dist/client.types.d.ts +58 -0
- package/dist/client.types.d.ts.map +1 -1
- package/dist/client.types.js.map +1 -1
- package/dist/cpsat/model-builder.d.ts +13 -2
- package/dist/cpsat/model-builder.d.ts.map +1 -1
- package/dist/cpsat/model-builder.js.map +1 -1
- package/dist/cpsat/response.d.ts +12 -3
- package/dist/cpsat/response.d.ts.map +1 -1
- package/dist/cpsat/response.js.map +1 -1
- package/dist/cpsat/rules/assign-together.d.ts +7 -0
- package/dist/cpsat/rules/assign-together.d.ts.map +1 -1
- package/dist/cpsat/rules/assign-together.js +1 -0
- package/dist/cpsat/rules/assign-together.js.map +1 -1
- package/dist/cpsat/rules/employee-assignment-priority.d.ts +11 -37
- package/dist/cpsat/rules/employee-assignment-priority.d.ts.map +1 -1
- package/dist/cpsat/rules/employee-assignment-priority.js +12 -104
- package/dist/cpsat/rules/employee-assignment-priority.js.map +1 -1
- package/dist/cpsat/rules/location-preference.d.ts +12 -10
- package/dist/cpsat/rules/location-preference.d.ts.map +1 -1
- package/dist/cpsat/rules/location-preference.js +16 -14
- package/dist/cpsat/rules/location-preference.js.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.d.ts +12 -13
- package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.js +11 -12
- package/dist/cpsat/rules/max-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/max-hours-day.d.ts +12 -28
- package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-day.js +12 -95
- package/dist/cpsat/rules/max-hours-day.js.map +1 -1
- package/dist/cpsat/rules/max-hours-week.d.ts +14 -34
- package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-week.js +12 -103
- package/dist/cpsat/rules/max-hours-week.js.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.d.ts +14 -39
- package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.js +14 -106
- package/dist/cpsat/rules/max-shifts-day.js.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.d.ts +12 -13
- package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.js +11 -12
- package/dist/cpsat/rules/min-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/min-hours-day.d.ts +12 -13
- package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-day.js +11 -12
- package/dist/cpsat/rules/min-hours-day.js.map +1 -1
- package/dist/cpsat/rules/min-hours-week.d.ts +13 -13
- package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-week.js +10 -14
- package/dist/cpsat/rules/min-hours-week.js.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts +13 -14
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.js +11 -12
- package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -1
- package/dist/cpsat/rules/resolver.d.ts +2 -2
- package/dist/cpsat/rules/resolver.d.ts.map +1 -1
- package/dist/cpsat/rules/resolver.js +55 -30
- package/dist/cpsat/rules/resolver.js.map +1 -1
- package/dist/cpsat/rules/scope.types.d.ts +267 -0
- package/dist/cpsat/rules/scope.types.d.ts.map +1 -0
- package/dist/cpsat/rules/scope.types.js +325 -0
- package/dist/cpsat/rules/scope.types.js.map +1 -0
- package/dist/cpsat/rules/time-off.d.ts +21 -25
- package/dist/cpsat/rules/time-off.d.ts.map +1 -1
- package/dist/cpsat/rules/time-off.js +20 -110
- package/dist/cpsat/rules/time-off.js.map +1 -1
- package/dist/cpsat/semantic-time.d.ts +2 -0
- package/dist/cpsat/semantic-time.d.ts.map +1 -1
- package/dist/cpsat/semantic-time.js +2 -4
- package/dist/cpsat/semantic-time.js.map +1 -1
- package/dist/cpsat/types.d.ts +22 -6
- package/dist/cpsat/types.d.ts.map +1 -1
- package/dist/cpsat/utils.d.ts +1 -1
- package/dist/cpsat/utils.js +1 -1
- package/dist/cpsat/validation-reporter.js +1 -1
- package/dist/cpsat/validation-reporter.js.map +1 -1
- package/dist/datetime.utils.d.ts +14 -14
- package/dist/datetime.utils.d.ts.map +1 -1
- package/dist/datetime.utils.js +26 -27
- package/dist/datetime.utils.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/llms.d.ts +1 -1
- package/dist/llms.d.ts.map +1 -1
- package/dist/llms.js +1 -1
- package/dist/llms.js.map +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/solver-container.js +3 -1
- package/dist/testing/solver-container.js.map +1 -1
- package/dist/types.d.ts +18 -20
- package/dist/types.d.ts.map +1 -1
- package/llms.txt +516 -263
- package/package.json +25 -25
- package/src/client.types.ts +58 -0
- package/src/cpsat/model-builder.ts +19 -7
- package/src/cpsat/response.ts +12 -3
- package/src/cpsat/rules/assign-together.ts +7 -0
- package/src/cpsat/rules/employee-assignment-priority.ts +28 -128
- package/src/cpsat/rules/location-preference.ts +24 -17
- package/src/cpsat/rules/max-consecutive-days.ts +19 -15
- package/src/cpsat/rules/max-hours-day.ts +29 -119
- package/src/cpsat/rules/max-hours-week.ts +42 -135
- package/src/cpsat/rules/max-shifts-day.ts +31 -130
- package/src/cpsat/rules/min-consecutive-days.ts +19 -15
- package/src/cpsat/rules/min-hours-day.ts +19 -15
- package/src/cpsat/rules/min-hours-week.ts +28 -26
- package/src/cpsat/rules/min-rest-between-shifts.ts +21 -17
- package/src/cpsat/rules/resolver.ts +66 -45
- package/src/cpsat/rules/scope.types.ts +534 -0
- package/src/cpsat/rules/time-off.ts +48 -145
- package/src/cpsat/semantic-time.ts +10 -8
- package/src/cpsat/types.ts +22 -6
- package/src/cpsat/utils.ts +1 -1
- package/src/cpsat/validation-reporter.ts +1 -1
- package/src/datetime.utils.ts +27 -29
- package/src/index.ts +11 -7
- package/src/llms.ts +1 -1
- package/src/testing/index.ts +1 -1
- package/src/testing/solver-container.ts +3 -3
- package/src/types.ts +27 -31
- package/dist/cpsat/rules/scoping.d.ts +0 -129
- package/dist/cpsat/rules/scoping.d.ts.map +0 -1
- package/dist/cpsat/rules/scoping.js +0 -190
- package/dist/cpsat/rules/scoping.js.map +0 -1
- package/src/cpsat/rules/scoping.ts +0 -340
package/llms.txt
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Scheduling library powered by constraint programming (CP-SAT).
|
|
6
6
|
|
|
7
|
-
Define teams, shifts, coverage, and rules
|
|
7
|
+
Define teams, shifts, coverage, and rules. dabke turns them
|
|
8
8
|
into an optimized schedule.
|
|
9
9
|
|
|
10
10
|
## Core Concepts
|
|
@@ -109,6 +109,47 @@ Used for checking overlaps and scheduling constraints.
|
|
|
109
109
|
- `start: DateTimeWithUtcOffset | DateTimeWithTimeZone`
|
|
110
110
|
- `end: DateTimeWithUtcOffset | DateTimeWithTimeZone`
|
|
111
111
|
|
|
112
|
+
### SchedulingPeriod
|
|
113
|
+
Defines a scheduling period as a date range with optional filters.
|
|
114
|
+
|
|
115
|
+
The `dateRange` specifies the overall scheduling window. Use `daysOfWeek`
|
|
116
|
+
and/or `dates` to narrow which days within the range are included.
|
|
117
|
+
Filters compose: a day must pass all specified filters to be included.
|
|
118
|
+
|
|
119
|
+
**Example:**
|
|
120
|
+
All days in a week
|
|
121
|
+
```typescript
|
|
122
|
+
const period: SchedulingPeriod = {
|
|
123
|
+
dateRange: { start: '2025-02-03', end: '2025-02-09' },
|
|
124
|
+
};
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Example:**
|
|
128
|
+
Only specific days of the week (restaurant closed Mon/Tue)
|
|
129
|
+
```typescript
|
|
130
|
+
const period: SchedulingPeriod = {
|
|
131
|
+
dateRange: { start: '2025-02-03', end: '2025-02-09' },
|
|
132
|
+
daysOfWeek: ['wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Example:**
|
|
137
|
+
Only specific dates within the range
|
|
138
|
+
```typescript
|
|
139
|
+
const period: SchedulingPeriod = {
|
|
140
|
+
dateRange: { start: '2025-02-03', end: '2025-02-09' },
|
|
141
|
+
dates: ['2025-02-05', '2025-02-07'],
|
|
142
|
+
};
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Properties:**
|
|
146
|
+
- `dateRange: { start: string; end: string; }` - The overall scheduling window (start and end are inclusive).
|
|
147
|
+
Dates should be in YYYY-MM-DD format.
|
|
148
|
+
- `daysOfWeek?: DayOfWeek[] | undefined` - Include only these days of the week.
|
|
149
|
+
If omitted, all days of the week are included.
|
|
150
|
+
- `dates?: string[] | undefined` - Include only these specific dates (YYYY-MM-DD) within the range.
|
|
151
|
+
If omitted, all dates in the range are included (subject to daysOfWeek filter).
|
|
152
|
+
|
|
112
153
|
### SolverClient
|
|
113
154
|
**Properties:**
|
|
114
155
|
- `solve: (request: SolverRequest, options?: { signal?: AbortSignal; }) => Promise<SolverResponse>`
|
|
@@ -132,10 +173,10 @@ daysOfWeek: ['wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
|
|
|
132
173
|
```
|
|
133
174
|
|
|
134
175
|
**Properties:**
|
|
135
|
-
- `employees: SchedulingEmployee[]`
|
|
136
|
-
- `shiftPatterns: ShiftPattern[]`
|
|
137
|
-
- `schedulingPeriod:
|
|
138
|
-
|
|
176
|
+
- `employees: SchedulingEmployee[]` - Team members available for scheduling.
|
|
177
|
+
- `shiftPatterns: ShiftPattern[]` - Available shift patterns (time slots) that employees can be assigned to.
|
|
178
|
+
- `schedulingPeriod: SchedulingPeriod` - Defines when scheduling should occur as a date range with optional
|
|
179
|
+
`daysOfWeek` and `dates` filters that compose to narrow which days are included.
|
|
139
180
|
- `coverage: CoverageRequirement[]`
|
|
140
181
|
- `rules?: CompilationRule[] | undefined` - Pre-compiled rules; use this for custom rules that are not part of the registry.
|
|
141
182
|
- `ruleConfigs?: CpsatRuleConfigEntry[] | undefined` - Named rule configurations that will be compiled using the provided rule factories.
|
|
@@ -149,9 +190,15 @@ daysOfWeek: ['wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
|
|
|
149
190
|
- `canSolve: boolean`
|
|
150
191
|
|
|
151
192
|
### CompilationRule
|
|
193
|
+
A rule that adds constraints or objectives to the solver model.
|
|
194
|
+
|
|
195
|
+
Rules implement `compile` to emit solver constraints during model building,
|
|
196
|
+
and optionally `validate` to check the solution after solving.
|
|
197
|
+
Use the `create*Rule` functions to create built-in rules.
|
|
198
|
+
|
|
152
199
|
**Properties:**
|
|
153
|
-
- `compile: (builder: ModelBuilder) => void`
|
|
154
|
-
- `validate?: ((assignments: ResolvedShiftAssignment[], reporter: ValidationReporter, context: RuleValidationContext) => void) | undefined`
|
|
200
|
+
- `compile: (builder: ModelBuilder) => void` - Emit constraints and objectives into the model builder.
|
|
201
|
+
- `validate?: ((assignments: ResolvedShiftAssignment[], reporter: ValidationReporter, context: RuleValidationContext) => void) | undefined` - Validate the solved schedule and report violations.
|
|
155
202
|
|
|
156
203
|
### RuleValidationContext
|
|
157
204
|
Context provided to rules during post-solve validation.
|
|
@@ -162,52 +209,62 @@ Context provided to rules during post-solve validation.
|
|
|
162
209
|
- `shiftPatterns: ShiftPattern[]`
|
|
163
210
|
|
|
164
211
|
### ShiftAssignment
|
|
165
|
-
A
|
|
212
|
+
A raw assignment from the solver: which employee works which shift on which day.
|
|
166
213
|
|
|
167
214
|
**Properties:**
|
|
168
|
-
- `employeeId: string`
|
|
169
|
-
- `shiftPatternId: string`
|
|
170
|
-
- `day: string`
|
|
215
|
+
- `employeeId: string` - The assigned employee's ID.
|
|
216
|
+
- `shiftPatternId: string` - The shift pattern this employee is assigned to.
|
|
217
|
+
- `day: string` - The date of the assignment (YYYY-MM-DD).
|
|
171
218
|
|
|
172
219
|
### ResolvedShiftAssignment
|
|
173
220
|
A shift assignment with resolved times.
|
|
174
221
|
|
|
175
222
|
**Properties:**
|
|
176
|
-
- `employeeId: string`
|
|
177
|
-
- `day: string`
|
|
178
|
-
- `startTime: TimeOfDay`
|
|
179
|
-
- `endTime: TimeOfDay`
|
|
223
|
+
- `employeeId: string` - The assigned employee's ID.
|
|
224
|
+
- `day: string` - The date of the assignment (YYYY-MM-DD).
|
|
225
|
+
- `startTime: TimeOfDay` - When the shift starts.
|
|
226
|
+
- `endTime: TimeOfDay` - When the shift ends.
|
|
180
227
|
|
|
181
228
|
### SolverResult
|
|
182
229
|
Parsed solver result with assignments and metadata.
|
|
183
230
|
|
|
184
231
|
**Properties:**
|
|
185
|
-
- `status: "OPTIMAL" | "FEASIBLE" | "INFEASIBLE" | "TIMEOUT" | "ERROR"`
|
|
186
|
-
- `assignments: ShiftAssignment[]`
|
|
187
|
-
- `statistics?: { solveTimeMs?: number | undefined; conflicts?: number | undefined; branches?: number | undefined; } | undefined`
|
|
188
|
-
- `error?: string | undefined`
|
|
232
|
+
- `status: "OPTIMAL" | "FEASIBLE" | "INFEASIBLE" | "TIMEOUT" | "ERROR"` - The solver outcome: OPTIMAL, FEASIBLE, INFEASIBLE, TIMEOUT, or ERROR.
|
|
233
|
+
- `assignments: ShiftAssignment[]` - The shift assignments extracted from the solution.
|
|
234
|
+
- `statistics?: { solveTimeMs?: number | undefined; conflicts?: number | undefined; branches?: number | undefined; } | undefined` - Solver performance statistics (branches, conflicts, solve time).
|
|
235
|
+
- `error?: string | undefined` - Error message if the solver returned an error status.
|
|
236
|
+
|
|
237
|
+
### RecurringPeriod
|
|
238
|
+
Recurring calendar period for time scoping.
|
|
239
|
+
|
|
240
|
+
**Properties:**
|
|
241
|
+
- `name: string`
|
|
242
|
+
- `startMonth: number`
|
|
243
|
+
- `startDay: number`
|
|
244
|
+
- `endMonth: number`
|
|
245
|
+
- `endDay: number`
|
|
189
246
|
|
|
190
247
|
### CpsatRuleRegistry
|
|
191
248
|
**Properties:**
|
|
192
249
|
- `"assign-together": { groupEmployeeIds: [string, string, ...string[]]; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; }`
|
|
193
|
-
- `"employee-assignment-priority": { preference: "high" | "low";
|
|
194
|
-
- `"location-preference": { locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
195
|
-
- `"max-consecutive-days": { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
196
|
-
- `"max-hours-day": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
197
|
-
- `"max-hours-week": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
198
|
-
- `"max-shifts-day": { shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
199
|
-
- `"min-consecutive-days": { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
200
|
-
- `"min-hours-day": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
201
|
-
- `"min-hours-week": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
202
|
-
- `"min-rest-between-shifts": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
203
|
-
- `"time-off": { priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined;
|
|
250
|
+
- `"employee-assignment-priority": ({ preference: "high" | "low"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
251
|
+
- `"location-preference": { locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
252
|
+
- `"max-consecutive-days": { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
253
|
+
- `"max-hours-day": ({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
254
|
+
- `"max-hours-week": ({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
255
|
+
- `"max-shifts-day": ({ shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
256
|
+
- `"min-consecutive-days": { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
257
|
+
- `"min-hours-day": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
258
|
+
- `"min-hours-week": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
259
|
+
- `"min-rest-between-shifts": { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
260
|
+
- `"time-off": ({ priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & RequiredTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
204
261
|
|
|
205
262
|
### SemanticTimeDef
|
|
206
263
|
Base definition for a semantic time period.
|
|
207
264
|
|
|
208
265
|
**Properties:**
|
|
209
|
-
- `startTime: TimeOfDay`
|
|
210
|
-
- `endTime: TimeOfDay`
|
|
266
|
+
- `startTime: TimeOfDay` - When this time period starts.
|
|
267
|
+
- `endTime: TimeOfDay` - When this time period ends.
|
|
211
268
|
|
|
212
269
|
### SemanticTimeVariant
|
|
213
270
|
Variant of a semantic time that applies to specific days or dates.
|
|
@@ -227,13 +284,18 @@ Accepts both semantic references and concrete one-off requirements.
|
|
|
227
284
|
for the given days in the scheduling horizon.
|
|
228
285
|
|
|
229
286
|
### SchedulingEmployee
|
|
287
|
+
A team member available for scheduling.
|
|
288
|
+
|
|
289
|
+
Employees are assigned to shift patterns by the solver based on
|
|
290
|
+
coverage requirements, rules, and constraints.
|
|
291
|
+
|
|
230
292
|
**Properties:**
|
|
231
|
-
- `id: string`
|
|
232
|
-
- `roleIds: string[]`
|
|
233
|
-
- `skillIds?: string[] | undefined`
|
|
293
|
+
- `id: string` - Unique identifier for this employee. Must not contain colons.
|
|
294
|
+
- `roleIds: string[]` - Roles this employee can fill (e.g. "waiter", "chef").
|
|
295
|
+
- `skillIds?: string[] | undefined` - Skills this employee has (e.g. "senior", "trainer").
|
|
234
296
|
|
|
235
297
|
### ShiftPattern
|
|
236
|
-
A shift pattern defines WHEN people can work
|
|
298
|
+
A shift pattern defines WHEN people can work: the time slots available for assignment.
|
|
237
299
|
|
|
238
300
|
Shift patterns are templates that repeat across all scheduling days. The solver assigns
|
|
239
301
|
team members to these patterns based on coverage requirements and constraints.
|
|
@@ -277,8 +339,8 @@ earlier than floor staff).
|
|
|
277
339
|
```
|
|
278
340
|
- `locationId?: string | undefined` - Physical location where this shift takes place.
|
|
279
341
|
Used for multi-location scheduling and location-based constraints.
|
|
280
|
-
- `startTime: TimeOfDay` - When the shift starts (e.g., { hours: 9, minutes: 0 } for 9:00 AM)
|
|
281
|
-
- `endTime: TimeOfDay` - When the shift ends (e.g., { hours: 17, minutes: 30 } for 5:30 PM)
|
|
342
|
+
- `startTime: TimeOfDay` - When the shift starts (e.g., `{ hours: 9, minutes: 0 }` for 9:00 AM)
|
|
343
|
+
- `endTime: TimeOfDay` - When the shift ends (e.g., `{ hours: 17, minutes: 30 }` for 5:30 PM)
|
|
282
344
|
|
|
283
345
|
### TimeInterval
|
|
284
346
|
**Properties:**
|
|
@@ -287,9 +349,11 @@ Used for multi-location scheduling and location-based constraints.
|
|
|
287
349
|
- `endTime: TimeOfDay`
|
|
288
350
|
|
|
289
351
|
### ModelBuilderOptions
|
|
352
|
+
Optional settings for the model builder.
|
|
353
|
+
|
|
290
354
|
**Properties:**
|
|
291
|
-
- `weekStartsOn?: DayOfWeek | undefined`
|
|
292
|
-
- `solverOptions?: { timeLimitSeconds?: number | undefined; solutionLimit?: number | undefined; } | undefined`
|
|
355
|
+
- `weekStartsOn?: DayOfWeek | undefined` - Which day starts the week for weekly rules. Defaults to "monday".
|
|
356
|
+
- `solverOptions?: { timeLimitSeconds?: number | undefined; solutionLimit?: number | undefined; } | undefined` - Solver-level options (time limit, solution limit).
|
|
293
357
|
- `coverageBucketMinutes?: number | undefined` - Bucket size used when translating coverage requirements into time-indexed constraints.
|
|
294
358
|
Smaller buckets are more accurate but increase the number of constraints.
|
|
295
359
|
- `fairDistribution?: boolean | undefined` - Whether to enable fair distribution of shifts across team members.
|
|
@@ -299,7 +363,7 @@ any single person works, ensuring work is distributed evenly. Each person
|
|
|
299
363
|
works between floor(total/n) and ceil(total/n) shifts.
|
|
300
364
|
|
|
301
365
|
Disable this if you want other rules (like employee-assignment-priority)
|
|
302
|
-
to have full control over shift distribution.
|
|
366
|
+
to have full control over shift distribution. Defaults to true.
|
|
303
367
|
|
|
304
368
|
### ValidationReporter
|
|
305
369
|
**Properties:**
|
|
@@ -467,6 +531,25 @@ Combined validation result for coverage requirements.
|
|
|
467
531
|
- `skills: SkillValidationResult`
|
|
468
532
|
- `errors: string[]` - Human-readable error messages
|
|
469
533
|
|
|
534
|
+
### EntityScopeInput
|
|
535
|
+
Input shape accepted by {@link parseEntityScope}.
|
|
536
|
+
|
|
537
|
+
**Properties:**
|
|
538
|
+
- `employeeIds?: string[] | undefined`
|
|
539
|
+
- `roleIds?: string[] | undefined`
|
|
540
|
+
- `skillIds?: string[] | undefined`
|
|
541
|
+
- `unknown: any`
|
|
542
|
+
|
|
543
|
+
### TimeScopeInput
|
|
544
|
+
Input shape accepted by {@link parseTimeScope}.
|
|
545
|
+
|
|
546
|
+
**Properties:**
|
|
547
|
+
- `dateRange?: { start: string; end: string; } | undefined`
|
|
548
|
+
- `specificDates?: string[] | undefined`
|
|
549
|
+
- `dayOfWeek?: DayOfWeek[] | undefined`
|
|
550
|
+
- `recurringPeriods?: RecurringPeriod[] | undefined`
|
|
551
|
+
- `unknown: any`
|
|
552
|
+
|
|
470
553
|
## Type Aliases
|
|
471
554
|
|
|
472
555
|
### DayOfWeek
|
|
@@ -486,85 +569,99 @@ DateTimeWithUtcOffset | DateTimeWithTimeZone
|
|
|
486
569
|
```
|
|
487
570
|
|
|
488
571
|
|
|
489
|
-
###
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
Use this to specify when scheduling should occur. This is more expressive
|
|
493
|
-
than a simple list of days because it can filter by day-of-week.
|
|
494
|
-
|
|
495
|
-
**Example:**
|
|
496
|
-
Date range with day-of-week filtering (restaurant closed Mon/Tue)
|
|
497
|
-
```typescript
|
|
498
|
-
const period: SchedulingPeriod = {
|
|
499
|
-
dateRange: { start: '2025-02-03', end: '2025-02-09' },
|
|
500
|
-
daysOfWeek: ['wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
|
|
501
|
-
};
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
**Example:**
|
|
505
|
-
Date range for all days
|
|
506
|
-
```typescript
|
|
507
|
-
const period: SchedulingPeriod = {
|
|
508
|
-
dateRange: { start: '2025-02-03', end: '2025-02-09' },
|
|
509
|
-
};
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
**Example:**
|
|
513
|
-
Specific dates (non-contiguous or custom selection)
|
|
514
|
-
```typescript
|
|
515
|
-
const period: SchedulingPeriod = {
|
|
516
|
-
specificDates: ['2025-02-05', '2025-02-07', '2025-02-10'],
|
|
517
|
-
};
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
```typescript
|
|
521
|
-
{ dateRange: { start: string; end: string; }; daysOfWeek?: DayOfWeek[]; specificDates?: never; } | { specificDates: string[]; dateRange?: never; daysOfWeek?: never; }
|
|
522
|
-
```
|
|
572
|
+
### SolverRequest
|
|
573
|
+
The full request payload sent to the CP-SAT solver service.
|
|
523
574
|
|
|
575
|
+
- `variables` (required): all decision variables
|
|
576
|
+
- `constraints` (required): all constraints
|
|
577
|
+
- `objective` (optional): optimization objective
|
|
578
|
+
- `timeoutSeconds` (optional): solver time limit
|
|
524
579
|
|
|
525
|
-
### SolverRequest
|
|
526
580
|
```typescript
|
|
527
581
|
{ variables: ({ type: "bool"; name: string; } | { type: "int"; name: string; min: number; max: number; } | { type: "interval"; name: string; start: number; end: number; size: number; presenceVar?: string | undefined; })[]; constraints: ({ type: "linear"; terms: { var: string; coeff: number; }[]; op: "<=" | ">=" | "=="; rhs: number; } | { type: "soft_linear"; terms: { var: string; coeff: number; }[]; op: "<=" | ">="; rhs: number; penalty: number; id?: string | undefined; } | { type: "exactly_one"; vars: string[]; } | { type: "at_most_one"; vars: string[]; } | { type: "implication"; if: string; then: string; } | { type: "bool_or"; vars: string[]; } | { type: "bool_and"; vars: string[]; } | { type: "no_overlap"; intervals: string[]; })[]; objective?: { sense: "minimize" | "maximize"; terms: { var: string; coeff: number; }[]; } | undefined; options?: { timeLimitSeconds?: number | undefined; solutionLimit?: number | undefined; } | undefined; }
|
|
528
582
|
```
|
|
529
583
|
|
|
530
584
|
|
|
531
585
|
### SolverResponse
|
|
586
|
+
The response payload returned by the CP-SAT solver service.
|
|
587
|
+
|
|
588
|
+
- `status` (required): solve outcome (see {@link SolverStatus})
|
|
589
|
+
- `values` (optional): variable assignments when a solution is found
|
|
590
|
+
- `statistics` (optional): solve time, conflicts, branches
|
|
591
|
+
- `softViolations` (optional): which soft constraints were violated
|
|
592
|
+
- `error` (optional): error message on failure
|
|
593
|
+
- `solutionInfo` (optional): solver diagnostic info
|
|
594
|
+
|
|
532
595
|
```typescript
|
|
533
596
|
{ status: "OPTIMAL" | "FEASIBLE" | "INFEASIBLE" | "TIMEOUT" | "ERROR"; values?: Record<string, number> | undefined; statistics?: { solveTimeMs?: number | undefined; conflicts?: number | undefined; branches?: number | undefined; } | undefined; error?: string | undefined; solutionInfo?: string | undefined; softViolations?: { constraintId: string; violationAmount: number; targetValue: number; actualValue: number; }[] | undefined; }
|
|
534
597
|
```
|
|
535
598
|
|
|
536
599
|
|
|
537
600
|
### SolverVariable
|
|
601
|
+
A decision variable in the CP-SAT model.
|
|
602
|
+
|
|
603
|
+
- `name` (required): unique variable identifier
|
|
604
|
+
- `lb` (required): lower bound
|
|
605
|
+
- `ub` (required): upper bound
|
|
606
|
+
- `isBoolean` (optional): whether this is a boolean variable
|
|
607
|
+
- `isInterval` (optional): whether this is an interval variable
|
|
608
|
+
- `start`, `end`, `size`, `presenceVar` (optional): interval variable fields
|
|
609
|
+
|
|
538
610
|
```typescript
|
|
539
611
|
{ type: "bool"; name: string; } | { type: "int"; name: string; min: number; max: number; } | { type: "interval"; name: string; start: number; end: number; size: number; presenceVar?: string | undefined; }
|
|
540
612
|
```
|
|
541
613
|
|
|
542
614
|
|
|
543
615
|
### SolverConstraint
|
|
616
|
+
A constraint in the CP-SAT model.
|
|
617
|
+
|
|
618
|
+
- `name` (required): constraint identifier
|
|
619
|
+
- `type` (required): constraint kind (e.g. "linear", "bool_and", "no_overlap")
|
|
620
|
+
- Additional fields vary by constraint type
|
|
621
|
+
|
|
544
622
|
```typescript
|
|
545
623
|
{ type: "linear"; terms: { var: string; coeff: number; }[]; op: "<=" | ">=" | "=="; rhs: number; } | { type: "soft_linear"; terms: { var: string; coeff: number; }[]; op: "<=" | ">="; rhs: number; penalty: number; id?: string | undefined; } | { type: "exactly_one"; vars: string[]; } | { type: "at_most_one"; vars: string[]; } | { type: "implication"; if: string; then: string; } | { type: "bool_or"; vars: string[]; } | { type: "bool_and"; vars: string[]; } | { type: "no_overlap"; intervals: string[]; }
|
|
546
624
|
```
|
|
547
625
|
|
|
548
626
|
|
|
549
627
|
### SolverTerm
|
|
628
|
+
A single linear term in a constraint or objective.
|
|
629
|
+
|
|
630
|
+
- `var` (required): variable name
|
|
631
|
+
- `coeff` (required): integer coefficient
|
|
632
|
+
|
|
550
633
|
```typescript
|
|
551
634
|
{ var: string; coeff: number; }
|
|
552
635
|
```
|
|
553
636
|
|
|
554
637
|
|
|
555
638
|
### SolverObjective
|
|
639
|
+
An optimization objective for the solver.
|
|
640
|
+
|
|
641
|
+
- `terms` (required): linear terms to minimize/maximize
|
|
642
|
+
- `minimize` (required): whether to minimize (true) or maximize (false)
|
|
643
|
+
|
|
556
644
|
```typescript
|
|
557
645
|
{ sense: "minimize" | "maximize"; terms: { var: string; coeff: number; }[]; }
|
|
558
646
|
```
|
|
559
647
|
|
|
560
648
|
|
|
561
649
|
### SolverStatus
|
|
650
|
+
Solver outcome status.
|
|
651
|
+
|
|
652
|
+
One of `"OPTIMAL"`, `"FEASIBLE"`, `"INFEASIBLE"`, `"TIMEOUT"`, or `"ERROR"`.
|
|
653
|
+
|
|
562
654
|
```typescript
|
|
563
655
|
"OPTIMAL" | "FEASIBLE" | "INFEASIBLE" | "TIMEOUT" | "ERROR"
|
|
564
656
|
```
|
|
565
657
|
|
|
566
658
|
|
|
567
659
|
### SoftConstraintViolation
|
|
660
|
+
A soft constraint violation reported by the solver.
|
|
661
|
+
|
|
662
|
+
- `constraintId` (required): which soft constraint was violated
|
|
663
|
+
- `violationAmount` (required): magnitude of the violation
|
|
664
|
+
|
|
568
665
|
```typescript
|
|
569
666
|
{ constraintId: string; violationAmount: number; targetValue: number; actualValue: number; }
|
|
570
667
|
```
|
|
@@ -576,75 +673,214 @@ specificDates: ['2025-02-05', '2025-02-07', '2025-02-10'],
|
|
|
576
673
|
```
|
|
577
674
|
|
|
578
675
|
|
|
676
|
+
### EntityScopeType
|
|
677
|
+
Entity scope type for a subset of entity keys (at most one).
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
ExclusiveOne<ActiveEntityFields, InactiveEntityFields, K> | MergeValues<Pick<InactiveEntityFields, K>>
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
### OptionalTimeScopeType
|
|
685
|
+
Time scope type for a subset of time keys (at most one, optional).
|
|
686
|
+
|
|
687
|
+
```typescript
|
|
688
|
+
ExclusiveOne<ActiveTimeFields, InactiveTimeFields, K> | MergeValues<Pick<InactiveTimeFields, K>>
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
### RequiredTimeScopeType
|
|
693
|
+
Time scope type for a subset of time keys (exactly one, required).
|
|
694
|
+
|
|
695
|
+
```typescript
|
|
696
|
+
{ [K in K]: ActiveTimeFields[K] & MergeValues<Pick<InactiveTimeFields, Exclude<K, K>>>; }[K]
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
### ParsedEntityScope
|
|
701
|
+
Parsed entity scope from a flat config.
|
|
702
|
+
Used internally by scope resolution functions.
|
|
703
|
+
|
|
704
|
+
```typescript
|
|
705
|
+
{ type: "global"; } | { type: "employees"; employeeIds: string[]; } | { type: "roles"; roleIds: string[]; } | { type: "skills"; skillIds: string[]; }
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
### ParsedTimeScope
|
|
710
|
+
Parsed time scope from a flat config.
|
|
711
|
+
Used internally by scope resolution functions.
|
|
712
|
+
|
|
713
|
+
```typescript
|
|
714
|
+
{ type: "none"; } | { type: "dateRange"; start: string; end: string; } | { type: "specificDates"; dates: string[]; } | { type: "dayOfWeek"; days: DayOfWeek[]; } | { type: "recurring"; periods: RecurringPeriod[]; }
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
|
|
579
718
|
### AssignTogetherConfig
|
|
719
|
+
Configuration for {@link createAssignTogetherRule}.
|
|
720
|
+
|
|
721
|
+
- `groupEmployeeIds` (required): employee IDs to assign together (at least two, must be unique)
|
|
722
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
723
|
+
|
|
580
724
|
```typescript
|
|
581
725
|
{ groupEmployeeIds: [string, string, ...string[]]; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; }
|
|
582
726
|
```
|
|
583
727
|
|
|
584
728
|
|
|
585
729
|
### EmployeeAssignmentPriorityConfig
|
|
730
|
+
Configuration for {@link createEmployeeAssignmentPriorityRule}.
|
|
731
|
+
|
|
732
|
+
- `preference` (required): `"high"` to prefer assigning or `"low"` to avoid assigning
|
|
733
|
+
|
|
734
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
735
|
+
Time scoping (at most one, optional): `dateRange`, `specificDates`, `dayOfWeek`, `recurringPeriods`
|
|
736
|
+
|
|
586
737
|
```typescript
|
|
587
|
-
{ preference: "high" | "low";
|
|
738
|
+
({ preference: "high" | "low"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">
|
|
588
739
|
```
|
|
589
740
|
|
|
590
741
|
|
|
591
742
|
### LocationPreferenceConfig
|
|
743
|
+
Configuration for {@link createLocationPreferenceRule}.
|
|
744
|
+
|
|
745
|
+
- `locationId` (required): the location ID to prefer for matching shift patterns
|
|
746
|
+
- `priority` (required): how strongly to prefer this location
|
|
747
|
+
|
|
748
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
749
|
+
|
|
592
750
|
```typescript
|
|
593
|
-
{ locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
751
|
+
{ locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">
|
|
594
752
|
```
|
|
595
753
|
|
|
596
754
|
|
|
597
755
|
### MaxConsecutiveDaysConfig
|
|
756
|
+
Configuration for {@link createMaxConsecutiveDaysRule}.
|
|
757
|
+
|
|
758
|
+
- `days` (required): maximum consecutive days allowed
|
|
759
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
760
|
+
|
|
761
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
762
|
+
|
|
598
763
|
```typescript
|
|
599
|
-
{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
764
|
+
{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">
|
|
600
765
|
```
|
|
601
766
|
|
|
602
767
|
|
|
603
768
|
### MaxHoursDayConfig
|
|
769
|
+
Configuration for {@link createMaxHoursDayRule}.
|
|
770
|
+
|
|
771
|
+
- `hours` (required): maximum hours allowed per day
|
|
772
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
773
|
+
|
|
774
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
775
|
+
Time scoping (at most one, optional): `dateRange`, `specificDates`, `dayOfWeek`, `recurringPeriods`
|
|
776
|
+
|
|
604
777
|
```typescript
|
|
605
|
-
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
778
|
+
({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">
|
|
606
779
|
```
|
|
607
780
|
|
|
608
781
|
|
|
609
782
|
### MaxHoursWeekConfig
|
|
783
|
+
Configuration for {@link createMaxHoursWeekRule}.
|
|
784
|
+
|
|
785
|
+
- `hours` (required): maximum hours allowed per scheduling week
|
|
786
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
787
|
+
- `weekStartsOn` (optional): which day starts the week; defaults to {@link ModelBuilder.weekStartsOn}
|
|
788
|
+
|
|
789
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
790
|
+
Time scoping (at most one, optional): `dateRange`, `specificDates`, `dayOfWeek`, `recurringPeriods`
|
|
791
|
+
|
|
610
792
|
```typescript
|
|
611
|
-
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
793
|
+
({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">
|
|
612
794
|
```
|
|
613
795
|
|
|
614
796
|
|
|
615
797
|
### MaxShiftsDayConfig
|
|
798
|
+
Configuration for {@link createMaxShiftsDayRule}.
|
|
799
|
+
|
|
800
|
+
- `shifts` (required): maximum number of shifts per day (at least 1)
|
|
801
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
802
|
+
|
|
803
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
804
|
+
Time scoping (at most one, optional): `dateRange`, `specificDates`, `dayOfWeek`, `recurringPeriods`
|
|
805
|
+
|
|
616
806
|
```typescript
|
|
617
|
-
{ shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
807
|
+
({ shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">
|
|
618
808
|
```
|
|
619
809
|
|
|
620
810
|
|
|
621
811
|
### MinConsecutiveDaysConfig
|
|
812
|
+
Configuration for {@link createMinConsecutiveDaysRule}.
|
|
813
|
+
|
|
814
|
+
- `days` (required): minimum consecutive days required once a person starts working
|
|
815
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
816
|
+
|
|
817
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
818
|
+
|
|
622
819
|
```typescript
|
|
623
|
-
{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
820
|
+
{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">
|
|
624
821
|
```
|
|
625
822
|
|
|
626
823
|
|
|
627
824
|
### MinHoursDayConfig
|
|
825
|
+
Configuration for {@link createMinHoursDayRule}.
|
|
826
|
+
|
|
827
|
+
- `hours` (required): minimum hours required per day when scheduled
|
|
828
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
829
|
+
|
|
830
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
831
|
+
|
|
628
832
|
```typescript
|
|
629
|
-
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
833
|
+
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">
|
|
630
834
|
```
|
|
631
835
|
|
|
632
836
|
|
|
633
837
|
### MinHoursWeekConfig
|
|
838
|
+
Configuration for {@link createMinHoursWeekRule}.
|
|
839
|
+
|
|
840
|
+
- `hours` (required): minimum hours required per scheduling week
|
|
841
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
842
|
+
- `weekStartsOn` (optional): which day starts the week; defaults to {@link ModelBuilder.weekStartsOn}
|
|
843
|
+
|
|
844
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
845
|
+
|
|
634
846
|
```typescript
|
|
635
|
-
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
847
|
+
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">
|
|
636
848
|
```
|
|
637
849
|
|
|
638
850
|
|
|
639
851
|
### MinRestBetweenShiftsConfig
|
|
852
|
+
Configuration for {@link createMinRestBetweenShiftsRule}.
|
|
853
|
+
|
|
854
|
+
- `hours` (required): minimum rest hours required between consecutive shifts
|
|
855
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
856
|
+
|
|
857
|
+
Entity scoping (at most one): `employeeIds`, `roleIds`, `skillIds`
|
|
858
|
+
|
|
640
859
|
```typescript
|
|
641
|
-
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
860
|
+
{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">
|
|
642
861
|
```
|
|
643
862
|
|
|
644
863
|
|
|
645
864
|
### TimeOffConfig
|
|
865
|
+
Configuration for {@link createTimeOffRule}.
|
|
866
|
+
|
|
867
|
+
- `priority` (required): how strictly the solver enforces this rule
|
|
868
|
+
- `startTime` (optional): start of the time-off window within each day; must be paired with `endTime`
|
|
869
|
+
- `endTime` (optional): end of the time-off window within each day; must be paired with `startTime`
|
|
870
|
+
|
|
871
|
+
Entity scoping (at most one):
|
|
872
|
+
- `employeeIds`: restrict to specific employees
|
|
873
|
+
- `roleIds`: restrict to employees with matching roles
|
|
874
|
+
- `skillIds`: restrict to employees with matching skills
|
|
875
|
+
|
|
876
|
+
Time scoping (exactly one required):
|
|
877
|
+
- `dateRange`: contiguous date range
|
|
878
|
+
- `specificDates`: specific dates
|
|
879
|
+
- `dayOfWeek`: days of the week
|
|
880
|
+
- `recurringPeriods`: recurring calendar periods
|
|
881
|
+
|
|
646
882
|
```typescript
|
|
647
|
-
{ priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined;
|
|
883
|
+
({ priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & RequiredTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">
|
|
648
884
|
```
|
|
649
885
|
|
|
650
886
|
|
|
@@ -763,6 +999,11 @@ RoleBasedCoverageRequirement | SkillBasedCoverageRequirement
|
|
|
763
999
|
|
|
764
1000
|
|
|
765
1001
|
### Priority
|
|
1002
|
+
How strictly the solver enforces a rule.
|
|
1003
|
+
|
|
1004
|
+
- `"LOW"`, `"MEDIUM"`, `"HIGH"`: soft constraints with increasing penalty for violations
|
|
1005
|
+
- `"MANDATORY"`: hard constraint; the solver will not produce a solution that violates it
|
|
1006
|
+
|
|
766
1007
|
```typescript
|
|
767
1008
|
"LOW" | "MEDIUM" | "HIGH" | "MANDATORY"
|
|
768
1009
|
```
|
|
@@ -795,6 +1036,42 @@ string & { readonly [GroupKeyBrand]: never; }
|
|
|
795
1036
|
```
|
|
796
1037
|
|
|
797
1038
|
|
|
1039
|
+
### EntityKey
|
|
1040
|
+
```typescript
|
|
1041
|
+
"employees" | "roles" | "skills"
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
### TimeKey
|
|
1046
|
+
```typescript
|
|
1047
|
+
"dateRange" | "specificDates" | "dayOfWeek" | "recurring"
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
### ExclusiveOne
|
|
1052
|
+
Exactly one of the specified keys must be present.
|
|
1053
|
+
The active key's field is required; all others are `?: never`.
|
|
1054
|
+
|
|
1055
|
+
**Example:**
|
|
1056
|
+
ExclusiveOne<ActiveEntityFields, InactiveEntityFields, "employees" | "roles">
|
|
1057
|
+
=
|
|
1058
|
+
| { employeeIds: [string, ...string[]]; roleIds?: never }
|
|
1059
|
+
| { roleIds: [string, ...string[]]; employeeIds?: never }
|
|
1060
|
+
|
|
1061
|
+
```typescript
|
|
1062
|
+
{ [K in Keys]: Active[K] & MergeValues<Pick<Inactive, Exclude<Keys, K>>>; }[Keys]
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
### MaybeOne
|
|
1067
|
+
At most one of the specified keys may be present (or none).
|
|
1068
|
+
Same as {@link ExclusiveOne} plus the case where all fields are `?: never`.
|
|
1069
|
+
|
|
1070
|
+
```typescript
|
|
1071
|
+
ExclusiveOne<Active, Inactive, Keys> | MergeValues<Pick<Inactive, Keys>>
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
|
|
798
1075
|
### InferCpsatRuleConfig
|
|
799
1076
|
```typescript
|
|
800
1077
|
T extends CreateCpsatRuleFunction<infer Config> ? Config : never
|
|
@@ -1014,41 +1291,41 @@ daysBetween(new Date('2025-01-01'), new Date('2025-01-05')); // 4
|
|
|
1014
1291
|
### resolveDaysFromPeriod
|
|
1015
1292
|
Computes the list of day strings (YYYY-MM-DD) from a SchedulingPeriod.
|
|
1016
1293
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
For specific dates, returns the dates as-is (sorted).
|
|
1294
|
+
Generates all days between start and end (inclusive), applying optional
|
|
1295
|
+
daysOfWeek and dates filters. Filters compose: a day must pass all
|
|
1296
|
+
specified filters to be included.
|
|
1021
1297
|
|
|
1022
1298
|
**Example:**
|
|
1023
|
-
|
|
1299
|
+
All days in range
|
|
1024
1300
|
```typescript
|
|
1025
1301
|
const days = resolveDaysFromPeriod({
|
|
1026
|
-
dateRange: { start: '2025-02-03', end: '2025-02-
|
|
1027
|
-
daysOfWeek: ['wednesday', 'friday'],
|
|
1302
|
+
dateRange: { start: '2025-02-03', end: '2025-02-05' },
|
|
1028
1303
|
});
|
|
1029
|
-
// Returns: ['2025-02-
|
|
1304
|
+
// Returns: ['2025-02-03', '2025-02-04', '2025-02-05']
|
|
1030
1305
|
```
|
|
1031
1306
|
|
|
1032
1307
|
**Example:**
|
|
1033
|
-
|
|
1308
|
+
Day-of-week filter
|
|
1034
1309
|
```typescript
|
|
1035
1310
|
const days = resolveDaysFromPeriod({
|
|
1036
|
-
dateRange: { start: '2025-02-03', end: '2025-02-
|
|
1311
|
+
dateRange: { start: '2025-02-03', end: '2025-02-09' },
|
|
1312
|
+
daysOfWeek: ['wednesday', 'friday'],
|
|
1037
1313
|
});
|
|
1038
|
-
// Returns: ['2025-02-
|
|
1314
|
+
// Returns: ['2025-02-05', '2025-02-07']
|
|
1039
1315
|
```
|
|
1040
1316
|
|
|
1041
1317
|
**Example:**
|
|
1042
|
-
Specific dates
|
|
1318
|
+
Specific dates filter
|
|
1043
1319
|
```typescript
|
|
1044
1320
|
const days = resolveDaysFromPeriod({
|
|
1045
|
-
|
|
1321
|
+
dateRange: { start: '2025-02-03', end: '2025-02-10' },
|
|
1322
|
+
dates: ['2025-02-05', '2025-02-07'],
|
|
1046
1323
|
});
|
|
1047
|
-
// Returns: ['2025-02-
|
|
1324
|
+
// Returns: ['2025-02-05', '2025-02-07']
|
|
1048
1325
|
```
|
|
1049
1326
|
|
|
1050
1327
|
**Parameters:**
|
|
1051
|
-
- `period:
|
|
1328
|
+
- `period: SchedulingPeriod`
|
|
1052
1329
|
|
|
1053
1330
|
**Returns:** `string[]`
|
|
1054
1331
|
|
|
@@ -1122,9 +1399,6 @@ builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
|
1122
1399
|
### createEmployeeAssignmentPriorityRule
|
|
1123
1400
|
Adds objective weight to prefer or avoid assigning team members.
|
|
1124
1401
|
|
|
1125
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
1126
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
1127
|
-
|
|
1128
1402
|
**Example:**
|
|
1129
1403
|
Prefer specific team members
|
|
1130
1404
|
```ts
|
|
@@ -1144,18 +1418,8 @@ preference: "low",
|
|
|
1144
1418
|
});
|
|
1145
1419
|
```
|
|
1146
1420
|
|
|
1147
|
-
**Example:**
|
|
1148
|
-
Prefer experienced staff on weekends
|
|
1149
|
-
```ts
|
|
1150
|
-
createEmployeeAssignmentPriorityRule({
|
|
1151
|
-
skillIds: ["senior"],
|
|
1152
|
-
dayOfWeek: ["saturday", "sunday"],
|
|
1153
|
-
preference: "high",
|
|
1154
|
-
});
|
|
1155
|
-
```
|
|
1156
|
-
|
|
1157
1421
|
**Parameters:**
|
|
1158
|
-
- `config: { preference: "high" | "low";
|
|
1422
|
+
- `config: ({ preference: "high" | "low"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
1159
1423
|
|
|
1160
1424
|
**Returns:** `CompilationRule`
|
|
1161
1425
|
|
|
@@ -1165,16 +1429,15 @@ Prefers assigning a person to shift patterns matching a specific location.
|
|
|
1165
1429
|
|
|
1166
1430
|
**Example:**
|
|
1167
1431
|
```ts
|
|
1168
|
-
|
|
1432
|
+
createLocationPreferenceRule({
|
|
1169
1433
|
locationId: "terrace",
|
|
1170
1434
|
priority: "HIGH",
|
|
1171
1435
|
employeeIds: ["alice"],
|
|
1172
1436
|
});
|
|
1173
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
1174
1437
|
```
|
|
1175
1438
|
|
|
1176
1439
|
**Parameters:**
|
|
1177
|
-
- `config: { locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
1440
|
+
- `config: { locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1178
1441
|
|
|
1179
1442
|
**Returns:** `CompilationRule`
|
|
1180
1443
|
|
|
@@ -1184,15 +1447,11 @@ Limits how many consecutive days a person can be assigned.
|
|
|
1184
1447
|
|
|
1185
1448
|
**Example:**
|
|
1186
1449
|
```ts
|
|
1187
|
-
|
|
1188
|
-
days: 5,
|
|
1189
|
-
priority: "MANDATORY",
|
|
1190
|
-
});
|
|
1191
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
1450
|
+
createMaxConsecutiveDaysRule({ days: 5, priority: "MANDATORY" });
|
|
1192
1451
|
```
|
|
1193
1452
|
|
|
1194
1453
|
**Parameters:**
|
|
1195
|
-
- `config: { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
1454
|
+
- `config: { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1196
1455
|
|
|
1197
1456
|
**Returns:** `CompilationRule`
|
|
1198
1457
|
|
|
@@ -1200,9 +1459,6 @@ builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
|
1200
1459
|
### createMaxHoursDayRule
|
|
1201
1460
|
Limits how many hours a person can work in a single day.
|
|
1202
1461
|
|
|
1203
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
1204
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
1205
|
-
|
|
1206
1462
|
**Example:**
|
|
1207
1463
|
Limit everyone to 8 hours per day
|
|
1208
1464
|
```ts
|
|
@@ -1224,7 +1480,7 @@ priority: "MANDATORY",
|
|
|
1224
1480
|
```
|
|
1225
1481
|
|
|
1226
1482
|
**Parameters:**
|
|
1227
|
-
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
1483
|
+
- `config: ({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
1228
1484
|
|
|
1229
1485
|
**Returns:** `CompilationRule`
|
|
1230
1486
|
|
|
@@ -1232,17 +1488,10 @@ priority: "MANDATORY",
|
|
|
1232
1488
|
### createMaxHoursWeekRule
|
|
1233
1489
|
Caps total hours a person can work within each scheduling week.
|
|
1234
1490
|
|
|
1235
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
1236
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
1237
|
-
Time scoping filters which days within each week count toward the limit.
|
|
1238
|
-
|
|
1239
1491
|
**Example:**
|
|
1240
1492
|
Limit everyone to 40 hours per week
|
|
1241
1493
|
```ts
|
|
1242
|
-
createMaxHoursWeekRule({
|
|
1243
|
-
hours: 40,
|
|
1244
|
-
priority: "HIGH",
|
|
1245
|
-
});
|
|
1494
|
+
createMaxHoursWeekRule({ hours: 40, priority: "HIGH" });
|
|
1246
1495
|
```
|
|
1247
1496
|
|
|
1248
1497
|
**Example:**
|
|
@@ -1253,14 +1502,13 @@ roleIds: ["student"],
|
|
|
1253
1502
|
hours: 20,
|
|
1254
1503
|
recurringPeriods: [
|
|
1255
1504
|
{ name: "fall-term", startMonth: 9, startDay: 1, endMonth: 12, endDay: 15 },
|
|
1256
|
-
{ name: "spring-term", startMonth: 1, startDay: 15, endMonth: 5, endDay: 31 },
|
|
1257
1505
|
],
|
|
1258
1506
|
priority: "MANDATORY",
|
|
1259
1507
|
});
|
|
1260
1508
|
```
|
|
1261
1509
|
|
|
1262
1510
|
**Parameters:**
|
|
1263
|
-
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
1511
|
+
- `config: ({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
1264
1512
|
|
|
1265
1513
|
**Returns:** `CompilationRule`
|
|
1266
1514
|
|
|
@@ -1268,14 +1516,11 @@ priority: "MANDATORY",
|
|
|
1268
1516
|
### createMaxShiftsDayRule
|
|
1269
1517
|
Limits how many shifts a person can work in a single day.
|
|
1270
1518
|
|
|
1271
|
-
|
|
1519
|
+
Controls the maximum number of distinct shift assignments per day,
|
|
1272
1520
|
regardless of shift duration. For limiting total hours worked, use `max-hours-day`.
|
|
1273
1521
|
|
|
1274
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
1275
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
1276
|
-
|
|
1277
1522
|
**Example:**
|
|
1278
|
-
Limit to one shift per day
|
|
1523
|
+
Limit to one shift per day
|
|
1279
1524
|
```ts
|
|
1280
1525
|
createMaxShiftsDayRule({
|
|
1281
1526
|
shifts: 1,
|
|
@@ -1283,16 +1528,6 @@ priority: "MANDATORY",
|
|
|
1283
1528
|
});
|
|
1284
1529
|
```
|
|
1285
1530
|
|
|
1286
|
-
**Example:**
|
|
1287
|
-
Allow up to two shifts per day for part-time workers
|
|
1288
|
-
```ts
|
|
1289
|
-
createMaxShiftsDayRule({
|
|
1290
|
-
roleIds: ["part-time"],
|
|
1291
|
-
shifts: 2,
|
|
1292
|
-
priority: "HIGH",
|
|
1293
|
-
});
|
|
1294
|
-
```
|
|
1295
|
-
|
|
1296
1531
|
**Example:**
|
|
1297
1532
|
Students can work 2 shifts on weekends only
|
|
1298
1533
|
```ts
|
|
@@ -1305,7 +1540,7 @@ priority: "MANDATORY",
|
|
|
1305
1540
|
```
|
|
1306
1541
|
|
|
1307
1542
|
**Parameters:**
|
|
1308
|
-
- `config: { shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
1543
|
+
- `config: ({ shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
1309
1544
|
|
|
1310
1545
|
**Returns:** `CompilationRule`
|
|
1311
1546
|
|
|
@@ -1316,15 +1551,11 @@ number of consecutive days.
|
|
|
1316
1551
|
|
|
1317
1552
|
**Example:**
|
|
1318
1553
|
```ts
|
|
1319
|
-
|
|
1320
|
-
days: 3,
|
|
1321
|
-
priority: "MANDATORY",
|
|
1322
|
-
});
|
|
1323
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
1554
|
+
createMinConsecutiveDaysRule({ days: 3, priority: "MANDATORY" });
|
|
1324
1555
|
```
|
|
1325
1556
|
|
|
1326
1557
|
**Parameters:**
|
|
1327
|
-
- `config: { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
1558
|
+
- `config: { days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1328
1559
|
|
|
1329
1560
|
**Returns:** `CompilationRule`
|
|
1330
1561
|
|
|
@@ -1334,15 +1565,11 @@ Ensures a person works at least a minimum number of hours per day.
|
|
|
1334
1565
|
|
|
1335
1566
|
**Example:**
|
|
1336
1567
|
```ts
|
|
1337
|
-
|
|
1338
|
-
hours: 6,
|
|
1339
|
-
priority: "MANDATORY",
|
|
1340
|
-
});
|
|
1341
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
1568
|
+
createMinHoursDayRule({ hours: 6, priority: "MANDATORY" });
|
|
1342
1569
|
```
|
|
1343
1570
|
|
|
1344
1571
|
**Parameters:**
|
|
1345
|
-
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
1572
|
+
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1346
1573
|
|
|
1347
1574
|
**Returns:** `CompilationRule`
|
|
1348
1575
|
|
|
@@ -1352,15 +1579,11 @@ Enforces a minimum total number of hours per scheduling week.
|
|
|
1352
1579
|
|
|
1353
1580
|
**Example:**
|
|
1354
1581
|
```ts
|
|
1355
|
-
|
|
1356
|
-
hours: 30,
|
|
1357
|
-
priority: "HIGH",
|
|
1358
|
-
});
|
|
1359
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
1582
|
+
createMinHoursWeekRule({ hours: 30, priority: "HIGH" });
|
|
1360
1583
|
```
|
|
1361
1584
|
|
|
1362
1585
|
**Parameters:**
|
|
1363
|
-
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
1586
|
+
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1364
1587
|
|
|
1365
1588
|
**Returns:** `CompilationRule`
|
|
1366
1589
|
|
|
@@ -1370,15 +1593,11 @@ Enforces a minimum rest period between any two shifts a person works.
|
|
|
1370
1593
|
|
|
1371
1594
|
**Example:**
|
|
1372
1595
|
```ts
|
|
1373
|
-
|
|
1374
|
-
hours: 10,
|
|
1375
|
-
priority: "MANDATORY",
|
|
1376
|
-
});
|
|
1377
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
1596
|
+
createMinRestBetweenShiftsRule({ hours: 10, priority: "MANDATORY" });
|
|
1378
1597
|
```
|
|
1379
1598
|
|
|
1380
1599
|
**Parameters:**
|
|
1381
|
-
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
1600
|
+
- `config: { hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1382
1601
|
|
|
1383
1602
|
**Returns:** `CompilationRule`
|
|
1384
1603
|
|
|
@@ -1425,7 +1644,7 @@ priority: "MANDATORY",
|
|
|
1425
1644
|
```
|
|
1426
1645
|
|
|
1427
1646
|
**Parameters:**
|
|
1428
|
-
- `config: { priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined;
|
|
1647
|
+
- `config: ({ priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & RequiredTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
1429
1648
|
|
|
1430
1649
|
**Returns:** `CompilationRule`
|
|
1431
1650
|
|
|
@@ -1666,6 +1885,98 @@ Always includes range start. Sorted ascending.
|
|
|
1666
1885
|
**Returns:** `number[]`
|
|
1667
1886
|
|
|
1668
1887
|
|
|
1888
|
+
### entityScope
|
|
1889
|
+
Creates a Zod schema for optional entity scoping (at most one of the
|
|
1890
|
+
specified entity variants).
|
|
1891
|
+
|
|
1892
|
+
The returned schema accepts flat fields (`employeeIds`, `roleIds`, `skillIds`)
|
|
1893
|
+
but the TypeScript type enforces mutual exclusivity via `?: never`.
|
|
1894
|
+
|
|
1895
|
+
**Example:**
|
|
1896
|
+
```ts
|
|
1897
|
+
// Supports all entity scopes
|
|
1898
|
+
entityScope(["employees", "roles", "skills"])
|
|
1899
|
+
|
|
1900
|
+
// Only employee scoping
|
|
1901
|
+
entityScope(["employees"])
|
|
1902
|
+
```
|
|
1903
|
+
|
|
1904
|
+
**Parameters:**
|
|
1905
|
+
- `keys: K`
|
|
1906
|
+
|
|
1907
|
+
**Returns:** `z.ZodType<EntityScopeType<K[number]>, unknown, z.core.$ZodTypeInternals<EntityScopeType<K[number]>, unknown>>`
|
|
1908
|
+
|
|
1909
|
+
|
|
1910
|
+
### timeScope
|
|
1911
|
+
Creates a Zod schema for optional time scoping (at most one of the
|
|
1912
|
+
specified time variants, or none).
|
|
1913
|
+
|
|
1914
|
+
**Example:**
|
|
1915
|
+
```ts
|
|
1916
|
+
// Supports all time scopes, all optional
|
|
1917
|
+
timeScope(["dateRange", "specificDates", "dayOfWeek", "recurring"])
|
|
1918
|
+
```
|
|
1919
|
+
|
|
1920
|
+
**Parameters:**
|
|
1921
|
+
- `keys: K`
|
|
1922
|
+
|
|
1923
|
+
**Returns:** `z.ZodType<OptionalTimeScopeType<K[number]>, unknown, z.core.$ZodTypeInternals<OptionalTimeScopeType<K[number]>, unknown>>`
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
### requiredTimeScope
|
|
1927
|
+
Creates a Zod schema for required time scoping (exactly one of the
|
|
1928
|
+
specified time variants must be present).
|
|
1929
|
+
|
|
1930
|
+
**Example:**
|
|
1931
|
+
```ts
|
|
1932
|
+
// Exactly one time scope required (for time-off)
|
|
1933
|
+
requiredTimeScope(["dateRange", "specificDates", "dayOfWeek", "recurring"])
|
|
1934
|
+
```
|
|
1935
|
+
|
|
1936
|
+
**Parameters:**
|
|
1937
|
+
- `keys: K`
|
|
1938
|
+
|
|
1939
|
+
**Returns:** `z.ZodType<RequiredTimeScopeType<K[number]>, unknown, z.core.$ZodTypeInternals<RequiredTimeScopeType<K[number]>, unknown>>`
|
|
1940
|
+
|
|
1941
|
+
|
|
1942
|
+
### parseEntityScope
|
|
1943
|
+
Extracts the entity scope from a parsed flat config.
|
|
1944
|
+
|
|
1945
|
+
**Parameters:**
|
|
1946
|
+
- `config: EntityScopeInput`
|
|
1947
|
+
|
|
1948
|
+
**Returns:** `{ type: "global"; } | { type: "employees"; employeeIds: string[]; } | { type: "roles"; roleIds: string[]; } | { type: "skills"; skillIds: string[]; }`
|
|
1949
|
+
|
|
1950
|
+
|
|
1951
|
+
### parseTimeScope
|
|
1952
|
+
Extracts the time scope from a parsed flat config.
|
|
1953
|
+
|
|
1954
|
+
**Parameters:**
|
|
1955
|
+
- `config: TimeScopeInput`
|
|
1956
|
+
|
|
1957
|
+
**Returns:** `{ type: "none"; } | { type: "dateRange"; start: string; end: string; } | { type: "specificDates"; dates: string[]; } | { type: "dayOfWeek"; days: DayOfWeek[]; } | { type: "recurring"; periods: RecurringPeriod[]; }`
|
|
1958
|
+
|
|
1959
|
+
|
|
1960
|
+
### resolveEmployeesFromScope
|
|
1961
|
+
Resolves which employees a rule applies to based on entity scope.
|
|
1962
|
+
|
|
1963
|
+
**Parameters:**
|
|
1964
|
+
- `scope: { type: "global"; } | { type: "employees"; employeeIds: string[]; } | { type: "roles"; roleIds: string[]; } | { type: "skills"; skillIds: string[]; }`
|
|
1965
|
+
- `employees: SchedulingEmployee[]`
|
|
1966
|
+
|
|
1967
|
+
**Returns:** `SchedulingEmployee[]`
|
|
1968
|
+
|
|
1969
|
+
|
|
1970
|
+
### resolveActiveDaysFromScope
|
|
1971
|
+
Resolves which days a rule applies to based on time scope.
|
|
1972
|
+
|
|
1973
|
+
**Parameters:**
|
|
1974
|
+
- `scope: { type: "none"; } | { type: "dateRange"; start: string; end: string; } | { type: "specificDates"; dates: string[]; } | { type: "dayOfWeek"; days: DayOfWeek[]; } | { type: "recurring"; periods: RecurringPeriod[]; }`
|
|
1975
|
+
- `allDays: string[]`
|
|
1976
|
+
|
|
1977
|
+
**Returns:** `string[]`
|
|
1978
|
+
|
|
1979
|
+
|
|
1669
1980
|
### parseDayString
|
|
1670
1981
|
Parse a day string (YYYY-MM-DD) to a UTC Date.
|
|
1671
1982
|
Used internally for day-of-week calculations and date comparisons.
|
|
@@ -1747,6 +2058,10 @@ Useful for rule configs that need to accept a day-of-week string.
|
|
|
1747
2058
|
**Type:** `z.ZodObject<{ status: z.ZodEnum<{ OPTIMAL: "OPTIMAL"; FEASIBLE: "FEASIBLE"; INFEASIBLE: "INFEASIBLE"; TIMEOUT: "TIMEOUT"; ERROR: "ERROR"; }>; values: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>; statistics: z.ZodOptional<z.ZodObject<{ solveTimeMs: z.ZodOptional<z.ZodNumber>; conflicts: z.ZodOptional<z.ZodNumber>; branches: z.ZodOptional<z.ZodNumber>; }, z.core.$strip>>; error: z.ZodOptional<z.ZodString>; solutionInfo: z.ZodOptional<z.ZodString>; softViolations: z.ZodOptional<z.ZodArray<z.ZodObject<{ constraintId: z.ZodString; violationAmount: z.ZodNumber; targetValue: z.ZodNumber; actualValue: z.ZodNumber; }, z.core.$strip>>>; }, z.core.$strip>`
|
|
1748
2059
|
|
|
1749
2060
|
|
|
2061
|
+
### SolverStatusSchema
|
|
2062
|
+
**Type:** `z.ZodEnum<{ OPTIMAL: "OPTIMAL"; FEASIBLE: "FEASIBLE"; INFEASIBLE: "INFEASIBLE"; TIMEOUT: "TIMEOUT"; ERROR: "ERROR"; }>`
|
|
2063
|
+
|
|
2064
|
+
|
|
1750
2065
|
### builtInCpsatRuleFactories
|
|
1751
2066
|
**Type:** `[Complex type: __type]`
|
|
1752
2067
|
|
|
@@ -1767,7 +2082,7 @@ Weight hierarchy (highest to lowest priority):
|
|
|
1767
2082
|
**Example:**
|
|
1768
2083
|
Using weights in a custom rule
|
|
1769
2084
|
```ts
|
|
1770
|
-
import { OBJECTIVE_WEIGHTS } from "
|
|
2085
|
+
import { OBJECTIVE_WEIGHTS } from "dabke";
|
|
1771
2086
|
|
|
1772
2087
|
// Prefer senior staff with same weight as employee-assignment-priority
|
|
1773
2088
|
b.addPenalty(assignment, -OBJECTIVE_WEIGHTS.ASSIGNMENT_PREFERENCE);
|
|
@@ -1847,10 +2162,6 @@ b.addPenalty(assignment, -2 * OBJECTIVE_WEIGHTS.ASSIGNMENT_PREFERENCE);
|
|
|
1847
2162
|
**Type:** `z.ZodObject<{ timeLimitSeconds: z.ZodOptional<z.ZodNumber>; solutionLimit: z.ZodOptional<z.ZodNumber>; }, z.core.$strip>`
|
|
1848
2163
|
|
|
1849
2164
|
|
|
1850
|
-
### SolverStatusSchema
|
|
1851
|
-
**Type:** `z.ZodEnum<{ OPTIMAL: "OPTIMAL"; FEASIBLE: "FEASIBLE"; INFEASIBLE: "INFEASIBLE"; TIMEOUT: "TIMEOUT"; ERROR: "ERROR"; }>`
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
2165
|
### SolverStatisticsSchema
|
|
1855
2166
|
**Type:** `z.ZodObject<{ solveTimeMs: z.ZodOptional<z.ZodNumber>; conflicts: z.ZodOptional<z.ZodNumber>; branches: z.ZodOptional<z.ZodNumber>; }, z.core.$strip>`
|
|
1856
2167
|
|
|
@@ -1892,9 +2203,6 @@ builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
|
1892
2203
|
|
|
1893
2204
|
Adds objective weight to prefer or avoid assigning team members.
|
|
1894
2205
|
|
|
1895
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
1896
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
1897
|
-
|
|
1898
2206
|
**Example:**
|
|
1899
2207
|
Prefer specific team members
|
|
1900
2208
|
```ts
|
|
@@ -1914,17 +2222,7 @@ preference: "low",
|
|
|
1914
2222
|
});
|
|
1915
2223
|
```
|
|
1916
2224
|
|
|
1917
|
-
**
|
|
1918
|
-
Prefer experienced staff on weekends
|
|
1919
|
-
```ts
|
|
1920
|
-
createEmployeeAssignmentPriorityRule({
|
|
1921
|
-
skillIds: ["senior"],
|
|
1922
|
-
dayOfWeek: ["saturday", "sunday"],
|
|
1923
|
-
preference: "high",
|
|
1924
|
-
});
|
|
1925
|
-
```
|
|
1926
|
-
|
|
1927
|
-
**Config:** `{ preference: "high" | "low"; employeeIds?: string[] | undefined; roleIds?: string[] | undefined; skillIds?: string[] | undefined; dateRange?: { start: string; end: string; } | undefined; specificDates?: string[] | undefined; dayOfWeek?: ("monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday")[] | undefined; recurringPeriods?: { name: string; startMonth: number; startDay: number; endMonth: number; endDay: number; }[] | undefined; }`
|
|
2225
|
+
**Config:** `({ preference: "high" | "low"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
1928
2226
|
|
|
1929
2227
|
### location-preference
|
|
1930
2228
|
|
|
@@ -1934,15 +2232,14 @@ Prefers assigning a person to shift patterns matching a specific location.
|
|
|
1934
2232
|
|
|
1935
2233
|
**Example:**
|
|
1936
2234
|
```ts
|
|
1937
|
-
|
|
2235
|
+
createLocationPreferenceRule({
|
|
1938
2236
|
locationId: "terrace",
|
|
1939
2237
|
priority: "HIGH",
|
|
1940
2238
|
employeeIds: ["alice"],
|
|
1941
2239
|
});
|
|
1942
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
1943
2240
|
```
|
|
1944
2241
|
|
|
1945
|
-
**Config:** `{ locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
2242
|
+
**Config:** `{ locationId: string; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1946
2243
|
|
|
1947
2244
|
### max-consecutive-days
|
|
1948
2245
|
|
|
@@ -1952,14 +2249,10 @@ Limits how many consecutive days a person can be assigned.
|
|
|
1952
2249
|
|
|
1953
2250
|
**Example:**
|
|
1954
2251
|
```ts
|
|
1955
|
-
|
|
1956
|
-
days: 5,
|
|
1957
|
-
priority: "MANDATORY",
|
|
1958
|
-
});
|
|
1959
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
2252
|
+
createMaxConsecutiveDaysRule({ days: 5, priority: "MANDATORY" });
|
|
1960
2253
|
```
|
|
1961
2254
|
|
|
1962
|
-
**Config:** `{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
2255
|
+
**Config:** `{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
1963
2256
|
|
|
1964
2257
|
### max-hours-day
|
|
1965
2258
|
|
|
@@ -1967,9 +2260,6 @@ builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
|
1967
2260
|
|
|
1968
2261
|
Limits how many hours a person can work in a single day.
|
|
1969
2262
|
|
|
1970
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
1971
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
1972
|
-
|
|
1973
2263
|
**Example:**
|
|
1974
2264
|
Limit everyone to 8 hours per day
|
|
1975
2265
|
```ts
|
|
@@ -1990,7 +2280,7 @@ priority: "MANDATORY",
|
|
|
1990
2280
|
});
|
|
1991
2281
|
```
|
|
1992
2282
|
|
|
1993
|
-
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
2283
|
+
**Config:** `({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
1994
2284
|
|
|
1995
2285
|
### max-hours-week
|
|
1996
2286
|
|
|
@@ -1998,17 +2288,10 @@ priority: "MANDATORY",
|
|
|
1998
2288
|
|
|
1999
2289
|
Caps total hours a person can work within each scheduling week.
|
|
2000
2290
|
|
|
2001
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
2002
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
2003
|
-
Time scoping filters which days within each week count toward the limit.
|
|
2004
|
-
|
|
2005
2291
|
**Example:**
|
|
2006
2292
|
Limit everyone to 40 hours per week
|
|
2007
2293
|
```ts
|
|
2008
|
-
createMaxHoursWeekRule({
|
|
2009
|
-
hours: 40,
|
|
2010
|
-
priority: "HIGH",
|
|
2011
|
-
});
|
|
2294
|
+
createMaxHoursWeekRule({ hours: 40, priority: "HIGH" });
|
|
2012
2295
|
```
|
|
2013
2296
|
|
|
2014
2297
|
**Example:**
|
|
@@ -2019,13 +2302,12 @@ roleIds: ["student"],
|
|
|
2019
2302
|
hours: 20,
|
|
2020
2303
|
recurringPeriods: [
|
|
2021
2304
|
{ name: "fall-term", startMonth: 9, startDay: 1, endMonth: 12, endDay: 15 },
|
|
2022
|
-
{ name: "spring-term", startMonth: 1, startDay: 15, endMonth: 5, endDay: 31 },
|
|
2023
2305
|
],
|
|
2024
2306
|
priority: "MANDATORY",
|
|
2025
2307
|
});
|
|
2026
2308
|
```
|
|
2027
2309
|
|
|
2028
|
-
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
2310
|
+
**Config:** `({ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
2029
2311
|
|
|
2030
2312
|
### max-shifts-day
|
|
2031
2313
|
|
|
@@ -2033,14 +2315,11 @@ priority: "MANDATORY",
|
|
|
2033
2315
|
|
|
2034
2316
|
Limits how many shifts a person can work in a single day.
|
|
2035
2317
|
|
|
2036
|
-
|
|
2318
|
+
Controls the maximum number of distinct shift assignments per day,
|
|
2037
2319
|
regardless of shift duration. For limiting total hours worked, use `max-hours-day`.
|
|
2038
2320
|
|
|
2039
|
-
Supports entity scoping (people, roles, skills) and time scoping
|
|
2040
|
-
(date ranges, specific dates, days of week, recurring periods).
|
|
2041
|
-
|
|
2042
2321
|
**Example:**
|
|
2043
|
-
Limit to one shift per day
|
|
2322
|
+
Limit to one shift per day
|
|
2044
2323
|
```ts
|
|
2045
2324
|
createMaxShiftsDayRule({
|
|
2046
2325
|
shifts: 1,
|
|
@@ -2048,16 +2327,6 @@ priority: "MANDATORY",
|
|
|
2048
2327
|
});
|
|
2049
2328
|
```
|
|
2050
2329
|
|
|
2051
|
-
**Example:**
|
|
2052
|
-
Allow up to two shifts per day for part-time workers
|
|
2053
|
-
```ts
|
|
2054
|
-
createMaxShiftsDayRule({
|
|
2055
|
-
roleIds: ["part-time"],
|
|
2056
|
-
shifts: 2,
|
|
2057
|
-
priority: "HIGH",
|
|
2058
|
-
});
|
|
2059
|
-
```
|
|
2060
|
-
|
|
2061
2330
|
**Example:**
|
|
2062
2331
|
Students can work 2 shifts on weekends only
|
|
2063
2332
|
```ts
|
|
@@ -2069,7 +2338,7 @@ priority: "MANDATORY",
|
|
|
2069
2338
|
});
|
|
2070
2339
|
```
|
|
2071
2340
|
|
|
2072
|
-
**Config:** `{ shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
2341
|
+
**Config:** `({ shifts: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">) & OptionalTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
2073
2342
|
|
|
2074
2343
|
### min-consecutive-days
|
|
2075
2344
|
|
|
@@ -2080,14 +2349,10 @@ number of consecutive days.
|
|
|
2080
2349
|
|
|
2081
2350
|
**Example:**
|
|
2082
2351
|
```ts
|
|
2083
|
-
|
|
2084
|
-
days: 3,
|
|
2085
|
-
priority: "MANDATORY",
|
|
2086
|
-
});
|
|
2087
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
2352
|
+
createMinConsecutiveDaysRule({ days: 3, priority: "MANDATORY" });
|
|
2088
2353
|
```
|
|
2089
2354
|
|
|
2090
|
-
**Config:** `{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
2355
|
+
**Config:** `{ days: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
2091
2356
|
|
|
2092
2357
|
### min-hours-day
|
|
2093
2358
|
|
|
@@ -2097,14 +2362,10 @@ Ensures a person works at least a minimum number of hours per day.
|
|
|
2097
2362
|
|
|
2098
2363
|
**Example:**
|
|
2099
2364
|
```ts
|
|
2100
|
-
|
|
2101
|
-
hours: 6,
|
|
2102
|
-
priority: "MANDATORY",
|
|
2103
|
-
});
|
|
2104
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
2365
|
+
createMinHoursDayRule({ hours: 6, priority: "MANDATORY" });
|
|
2105
2366
|
```
|
|
2106
2367
|
|
|
2107
|
-
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
2368
|
+
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
2108
2369
|
|
|
2109
2370
|
### min-hours-week
|
|
2110
2371
|
|
|
@@ -2114,14 +2375,10 @@ Enforces a minimum total number of hours per scheduling week.
|
|
|
2114
2375
|
|
|
2115
2376
|
**Example:**
|
|
2116
2377
|
```ts
|
|
2117
|
-
|
|
2118
|
-
hours: 30,
|
|
2119
|
-
priority: "HIGH",
|
|
2120
|
-
});
|
|
2121
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
2378
|
+
createMinHoursWeekRule({ hours: 30, priority: "HIGH" });
|
|
2122
2379
|
```
|
|
2123
2380
|
|
|
2124
|
-
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined;
|
|
2381
|
+
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; weekStartsOn?: "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday" | undefined; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
2125
2382
|
|
|
2126
2383
|
### min-rest-between-shifts
|
|
2127
2384
|
|
|
@@ -2131,14 +2388,10 @@ Enforces a minimum rest period between any two shifts a person works.
|
|
|
2131
2388
|
|
|
2132
2389
|
**Example:**
|
|
2133
2390
|
```ts
|
|
2134
|
-
|
|
2135
|
-
hours: 10,
|
|
2136
|
-
priority: "MANDATORY",
|
|
2137
|
-
});
|
|
2138
|
-
builder = new ModelBuilder({ ...config, rules: [rule] });
|
|
2391
|
+
createMinRestBetweenShiftsRule({ hours: 10, priority: "MANDATORY" });
|
|
2139
2392
|
```
|
|
2140
2393
|
|
|
2141
|
-
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
|
|
2394
|
+
**Config:** `{ hours: number; priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; } & EntityScopeType<"employees" | "roles" | "skills">`
|
|
2142
2395
|
|
|
2143
2396
|
### time-off
|
|
2144
2397
|
|
|
@@ -2184,5 +2437,5 @@ priority: "MANDATORY",
|
|
|
2184
2437
|
});
|
|
2185
2438
|
```
|
|
2186
2439
|
|
|
2187
|
-
**Config:** `{ priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined;
|
|
2440
|
+
**Config:** `({ priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY"; startTime?: { hours: number; minutes: number; } | undefined; endTime?: { hours: number; minutes: number; } | undefined; } & EntityScopeType<"employees" | "roles" | "skills">) & RequiredTimeScopeType<"dateRange" | "specificDates" | "dayOfWeek" | "recurring">`
|
|
2188
2441
|
|