dabke 0.82.0 → 0.83.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 +23 -0
- package/README.md +6 -3
- package/dist/cpsat/rules/index.d.ts +3 -0
- package/dist/cpsat/rules/index.d.ts.map +1 -1
- package/dist/cpsat/rules/index.js +3 -0
- package/dist/cpsat/rules/index.js.map +1 -1
- package/dist/cpsat/rules/max-days-week.d.ts +44 -0
- package/dist/cpsat/rules/max-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/max-days-week.js +95 -0
- package/dist/cpsat/rules/max-days-week.js.map +1 -0
- package/dist/cpsat/rules/min-days-week.d.ts +34 -0
- package/dist/cpsat/rules/min-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/min-days-week.js +84 -0
- package/dist/cpsat/rules/min-days-week.js.map +1 -0
- package/dist/cpsat/rules/must-assign.d.ts +49 -0
- package/dist/cpsat/rules/must-assign.d.ts.map +1 -0
- package/dist/cpsat/rules/must-assign.js +86 -0
- package/dist/cpsat/rules/must-assign.js.map +1 -0
- package/dist/cpsat/rules/registry.d.ts +4 -1
- package/dist/cpsat/rules/registry.d.ts.map +1 -1
- package/dist/cpsat/rules/registry.js +4 -1
- package/dist/cpsat/rules/registry.js.map +1 -1
- package/dist/cpsat/rules/rules.types.d.ts +3 -0
- package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.d.ts +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/schedule/cost.d.ts +204 -0
- package/dist/schedule/cost.d.ts.map +1 -0
- package/dist/schedule/cost.js +187 -0
- package/dist/schedule/cost.js.map +1 -0
- package/dist/schedule/coverage.d.ts +85 -0
- package/dist/schedule/coverage.d.ts.map +1 -0
- package/dist/schedule/coverage.js +33 -0
- package/dist/schedule/coverage.js.map +1 -0
- package/dist/schedule/definition.d.ts +227 -0
- package/dist/schedule/definition.d.ts.map +1 -0
- package/dist/{schedule.js → schedule/definition.js} +9 -673
- package/dist/schedule/definition.js.map +1 -0
- package/dist/schedule/index.d.ts +67 -0
- package/dist/schedule/index.d.ts.map +1 -0
- package/dist/schedule/index.js +69 -0
- package/dist/schedule/index.js.map +1 -0
- package/dist/schedule/rules.d.ts +353 -0
- package/dist/schedule/rules.d.ts.map +1 -0
- package/dist/schedule/rules.js +352 -0
- package/dist/schedule/rules.js.map +1 -0
- package/dist/schedule/shift-patterns.d.ts +34 -0
- package/dist/schedule/shift-patterns.d.ts.map +1 -0
- package/dist/schedule/shift-patterns.js +41 -0
- package/dist/schedule/shift-patterns.js.map +1 -0
- package/dist/schedule/time-periods.d.ts +69 -0
- package/dist/schedule/time-periods.d.ts.map +1 -0
- package/dist/schedule/time-periods.js +91 -0
- package/dist/schedule/time-periods.js.map +1 -0
- package/package.json +4 -9
- package/src/cpsat/rules/index.ts +3 -0
- package/src/cpsat/rules/max-days-week.ts +143 -0
- package/src/cpsat/rules/min-days-week.ts +120 -0
- package/src/cpsat/rules/must-assign.ts +108 -0
- package/src/cpsat/rules/registry.ts +6 -0
- package/src/cpsat/rules/rules.types.ts +3 -0
- package/src/cpsat/rules/scope.types.ts +1 -1
- package/src/index.ts +8 -3
- package/src/schedule/cost.ts +242 -0
- package/src/schedule/coverage.ts +135 -0
- package/src/schedule/definition.ts +958 -0
- package/src/schedule/index.ts +112 -0
- package/src/schedule/rules.ts +529 -0
- package/src/schedule/shift-patterns.ts +46 -0
- package/src/schedule/time-periods.ts +110 -0
- package/dist/llms.d.ts +0 -2
- package/dist/llms.d.ts.map +0 -1
- package/dist/llms.js +0 -3
- package/dist/llms.js.map +0 -1
- package/dist/schedule.d.ts +0 -917
- package/dist/schedule.d.ts.map +0 -1
- package/dist/schedule.js.map +0 -1
- package/llms.txt +0 -758
- package/src/llms.ts +0 -3
- package/src/schedule.ts +0 -1960
package/dist/schedule.d.ts
DELETED
|
@@ -1,917 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* High-level schedule definition API.
|
|
3
|
-
*
|
|
4
|
-
* Small, composable factory functions that produce a complete scheduling
|
|
5
|
-
* configuration. Designed for LLM code generation: each concept is a single
|
|
6
|
-
* function call with per-call type safety.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* import {
|
|
11
|
-
* schedule, t, time, cover, shift,
|
|
12
|
-
* maxHoursPerDay, maxHoursPerWeek, minRestBetweenShifts,
|
|
13
|
-
* weekdays, weekend,
|
|
14
|
-
* } from "dabke";
|
|
15
|
-
*
|
|
16
|
-
* const venue = schedule({
|
|
17
|
-
* roleIds: ["cashier", "floor_lead", "stocker"],
|
|
18
|
-
* skillIds: ["keyholder"],
|
|
19
|
-
*
|
|
20
|
-
* times: {
|
|
21
|
-
* opening: time({ startTime: t(8), endTime: t(10) }),
|
|
22
|
-
* peak_hours: time(
|
|
23
|
-
* { startTime: t(11), endTime: t(14) },
|
|
24
|
-
* { startTime: t(10), endTime: t(15), dayOfWeek: weekend },
|
|
25
|
-
* ),
|
|
26
|
-
* closing: time({ startTime: t(20), endTime: t(22) }),
|
|
27
|
-
* },
|
|
28
|
-
*
|
|
29
|
-
* coverage: [
|
|
30
|
-
* cover("opening", "keyholder", 1),
|
|
31
|
-
* cover("peak_hours", "cashier", 3, { dayOfWeek: weekdays }),
|
|
32
|
-
* cover("peak_hours", "cashier", 5, { dayOfWeek: weekend }),
|
|
33
|
-
* cover("closing", "floor_lead", 1),
|
|
34
|
-
* ],
|
|
35
|
-
*
|
|
36
|
-
* shiftPatterns: [
|
|
37
|
-
* shift("morning", t(8), t(14)),
|
|
38
|
-
* shift("afternoon", t(14), t(22)),
|
|
39
|
-
* ],
|
|
40
|
-
*
|
|
41
|
-
* rules: [
|
|
42
|
-
* maxHoursPerDay(10),
|
|
43
|
-
* maxHoursPerWeek(48),
|
|
44
|
-
* minRestBetweenShifts(10),
|
|
45
|
-
* ],
|
|
46
|
-
* });
|
|
47
|
-
*
|
|
48
|
-
* const result = await venue
|
|
49
|
-
* .with([
|
|
50
|
-
* { id: "alice", roleIds: ["cashier"], skillIds: ["keyholder"] },
|
|
51
|
-
* ])
|
|
52
|
-
* .solve(client, { dateRange: { start: "2025-03-03", end: "2025-03-09" } });
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* @module
|
|
56
|
-
*/
|
|
57
|
-
import type { DayOfWeek, TimeOfDay } from "./types.js";
|
|
58
|
-
import type { SemanticTimeVariant, SemanticTimeEntry, CoverageVariant } from "./cpsat/semantic-time.js";
|
|
59
|
-
export type { CoverageVariant } from "./cpsat/semantic-time.js";
|
|
60
|
-
import type { CompilationResult } from "./cpsat/model-builder.js";
|
|
61
|
-
import { ModelBuilder } from "./cpsat/model-builder.js";
|
|
62
|
-
import type { SchedulingMember, ShiftPattern, Priority } from "./cpsat/types.js";
|
|
63
|
-
import type { CreateCpsatRuleFunction } from "./cpsat/rules/rules.types.js";
|
|
64
|
-
import type { RecurringPeriod } from "./cpsat/rules/scope.types.js";
|
|
65
|
-
import type { OvertimeTier } from "./cpsat/rules/overtime-tiered-multiplier.js";
|
|
66
|
-
import type { SolverClient } from "./client.types.js";
|
|
67
|
-
import type { ShiftAssignment } from "./cpsat/response.js";
|
|
68
|
-
import type { ScheduleValidation } from "./cpsat/validation.types.js";
|
|
69
|
-
import type { CostBreakdown } from "./cpsat/cost.js";
|
|
70
|
-
/**
|
|
71
|
-
* Creates a {@link TimeOfDay} value.
|
|
72
|
-
*
|
|
73
|
-
* @param hours - Hour component (0-23)
|
|
74
|
-
* @param minutes - Minute component (0-59)
|
|
75
|
-
*
|
|
76
|
-
* @example Hours only
|
|
77
|
-
* ```ts
|
|
78
|
-
* t(9) // { hours: 9, minutes: 0 }
|
|
79
|
-
* ```
|
|
80
|
-
*
|
|
81
|
-
* @example Hours and minutes
|
|
82
|
-
* ```ts
|
|
83
|
-
* t(17, 30) // { hours: 17, minutes: 30 }
|
|
84
|
-
* ```
|
|
85
|
-
*
|
|
86
|
-
* @category Time Periods
|
|
87
|
-
*/
|
|
88
|
-
export declare function t(hours: number, minutes?: number): TimeOfDay;
|
|
89
|
-
/**
|
|
90
|
-
* Monday through Friday.
|
|
91
|
-
*
|
|
92
|
-
* @category Time Periods
|
|
93
|
-
*/
|
|
94
|
-
export declare const weekdays: readonly ["monday", "tuesday", "wednesday", "thursday", "friday"];
|
|
95
|
-
/**
|
|
96
|
-
* Saturday and Sunday.
|
|
97
|
-
*
|
|
98
|
-
* @category Time Periods
|
|
99
|
-
*/
|
|
100
|
-
export declare const weekend: readonly ["saturday", "sunday"];
|
|
101
|
-
/**
|
|
102
|
-
* Define a named semantic time period.
|
|
103
|
-
*
|
|
104
|
-
* @remarks
|
|
105
|
-
* Each entry has `startTime`/`endTime` and optional `dayOfWeek` or `dates`
|
|
106
|
-
* scoping. Entries without scoping are the default.
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```typescript
|
|
110
|
-
* times: {
|
|
111
|
-
* // Simple: same times every day
|
|
112
|
-
* lunch: time({ startTime: t(12), endTime: t(15) }),
|
|
113
|
-
*
|
|
114
|
-
* // Variants: different times on weekends
|
|
115
|
-
* dinner: time(
|
|
116
|
-
* { startTime: t(17), endTime: t(21) },
|
|
117
|
-
* { startTime: t(18), endTime: t(22), dayOfWeek: weekend },
|
|
118
|
-
* ),
|
|
119
|
-
*
|
|
120
|
-
* // Point-in-time window (keyholder at opening)
|
|
121
|
-
* opening: time({ startTime: t(8, 30), endTime: t(9) }),
|
|
122
|
-
* }
|
|
123
|
-
* ```
|
|
124
|
-
*
|
|
125
|
-
* @privateRemarks
|
|
126
|
-
* Resolution precedence: `dates` > `dayOfWeek` > default.
|
|
127
|
-
*
|
|
128
|
-
* @category Time Periods
|
|
129
|
-
*/
|
|
130
|
-
export declare function time(...entries: [SemanticTimeVariant, ...SemanticTimeVariant[]]): SemanticTimeEntry;
|
|
131
|
-
/**
|
|
132
|
-
* Options for a {@link cover} call.
|
|
133
|
-
*
|
|
134
|
-
* @remarks
|
|
135
|
-
* Day/date scoping controls which days this coverage entry applies to.
|
|
136
|
-
* An entry without `dayOfWeek` or `dates` applies every day in the
|
|
137
|
-
* scheduling period.
|
|
138
|
-
*
|
|
139
|
-
* @category Coverage
|
|
140
|
-
*/
|
|
141
|
-
export interface CoverageOptions {
|
|
142
|
-
/** Additional skill ID filter (AND logic with the target role). */
|
|
143
|
-
skillIds?: [string, ...string[]];
|
|
144
|
-
/** Restrict to specific days of the week. */
|
|
145
|
-
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
146
|
-
/** Restrict to specific dates (YYYY-MM-DD). */
|
|
147
|
-
dates?: string[];
|
|
148
|
-
/** Defaults to `"MANDATORY"`. */
|
|
149
|
-
priority?: Priority;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* A coverage entry returned by {@link cover}.
|
|
153
|
-
*
|
|
154
|
-
* @remarks
|
|
155
|
-
* Carries the semantic time name and target type information for
|
|
156
|
-
* compile-time validation by {@link schedule}. This is an opaque
|
|
157
|
-
* token; pass it directly into the `coverage` array.
|
|
158
|
-
*/
|
|
159
|
-
export interface CoverageEntry<T extends string = string, R extends string = string> {
|
|
160
|
-
/** @internal */ readonly _type: "coverage";
|
|
161
|
-
/** @internal */ readonly timeName: T;
|
|
162
|
-
/** @internal */ readonly target: R | R[];
|
|
163
|
-
/** @internal */ readonly count: number;
|
|
164
|
-
/** @internal */ readonly options: CoverageOptions;
|
|
165
|
-
/** @internal When present, this entry uses variant-based resolution. */
|
|
166
|
-
readonly variants?: readonly CoverageVariant[];
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Defines a staffing requirement for a semantic time period.
|
|
170
|
-
*
|
|
171
|
-
* @remarks
|
|
172
|
-
* Entries for the same time and role **stack additively**.
|
|
173
|
-
* For weekday vs weekend staffing, use mutually exclusive `dayOfWeek`
|
|
174
|
-
* on both entries.
|
|
175
|
-
*
|
|
176
|
-
* @param timeName - Name of a declared semantic time
|
|
177
|
-
* @param target - Role name (string), array of role names (OR logic), or skill name
|
|
178
|
-
* @param count - Number of people needed
|
|
179
|
-
* @param opts - Options: `skillIds` (AND filter), `dayOfWeek`, `dates`, `priority`
|
|
180
|
-
*
|
|
181
|
-
* @example
|
|
182
|
-
* ```typescript
|
|
183
|
-
* coverage: [
|
|
184
|
-
* // 2 waiters during lunch
|
|
185
|
-
* cover("lunch", "waiter", 2),
|
|
186
|
-
*
|
|
187
|
-
* // 1 manager OR supervisor during dinner
|
|
188
|
-
* cover("dinner", ["manager", "supervisor"], 1),
|
|
189
|
-
*
|
|
190
|
-
* // 1 person with keyholder skill at opening
|
|
191
|
-
* cover("opening", "keyholder", 1),
|
|
192
|
-
*
|
|
193
|
-
* // 1 senior waiter (role + skill AND)
|
|
194
|
-
* cover("lunch", "waiter", 1, { skillIds: ["senior"] }),
|
|
195
|
-
*
|
|
196
|
-
* // Different counts by day (mutually exclusive dayOfWeek!)
|
|
197
|
-
* cover("lunch", "waiter", 2, { dayOfWeek: weekdays }),
|
|
198
|
-
* cover("lunch", "waiter", 3, { dayOfWeek: weekend }),
|
|
199
|
-
* ]
|
|
200
|
-
* ```
|
|
201
|
-
*
|
|
202
|
-
* @category Coverage
|
|
203
|
-
*/
|
|
204
|
-
export declare function cover<T extends string, R extends string>(timeName: T, target: R | [R, ...R[]], count: number, opts?: CoverageOptions): CoverageEntry<T, R>;
|
|
205
|
-
export declare function cover<T extends string, R extends string>(timeName: T, target: R | [R, ...R[]], ...variants: [CoverageVariant, ...CoverageVariant[]]): CoverageEntry<T, R>;
|
|
206
|
-
/**
|
|
207
|
-
* Define a shift pattern: a time slot available for employee assignment.
|
|
208
|
-
*
|
|
209
|
-
* @remarks
|
|
210
|
-
* Each pattern repeats daily unless filtered by `dayOfWeek`.
|
|
211
|
-
*
|
|
212
|
-
* @example
|
|
213
|
-
* ```typescript
|
|
214
|
-
* shiftPatterns: [
|
|
215
|
-
* shift("morning", t(11, 30), t(15)),
|
|
216
|
-
* shift("evening", t(17), t(22)),
|
|
217
|
-
*
|
|
218
|
-
* // Role-restricted shift
|
|
219
|
-
* shift("kitchen", t(6), t(14), { roleIds: ["chef", "prep_cook"] }),
|
|
220
|
-
*
|
|
221
|
-
* // Day-restricted shift
|
|
222
|
-
* shift("saturday_short", t(9), t(14), { dayOfWeek: ["saturday"] }),
|
|
223
|
-
*
|
|
224
|
-
* // Location-specific shift
|
|
225
|
-
* shift("terrace_lunch", t(12), t(16), { locationId: "terrace" }),
|
|
226
|
-
* ]
|
|
227
|
-
* ```
|
|
228
|
-
*
|
|
229
|
-
* @category Shift Patterns
|
|
230
|
-
*/
|
|
231
|
-
export declare function shift(id: string, startTime: TimeOfDay, endTime: TimeOfDay, opts?: Pick<ShiftPattern, "roleIds" | "dayOfWeek" | "locationId">): ShiftPattern;
|
|
232
|
-
/**
|
|
233
|
-
* Scoping options shared by most rule functions.
|
|
234
|
-
*
|
|
235
|
-
* @remarks
|
|
236
|
-
* Default priority is `MANDATORY`. Use `appliesTo` to scope to a
|
|
237
|
-
* role, skill, or member ID. Use time scoping options (`dayOfWeek`,
|
|
238
|
-
* `dateRange`, `dates`) to limit when the rule applies.
|
|
239
|
-
* Not all rules support all scoping options. Entity-only rules
|
|
240
|
-
* (e.g., {@link maxConsecutiveDays}) ignore time scoping.
|
|
241
|
-
*
|
|
242
|
-
* @category Rules
|
|
243
|
-
*/
|
|
244
|
-
export interface RuleOptions {
|
|
245
|
-
/** Who this rule applies to (role name, skill name, or member ID). */
|
|
246
|
-
appliesTo?: string | string[];
|
|
247
|
-
/** Restrict to specific days of the week. */
|
|
248
|
-
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
249
|
-
/** Restrict to a date range. */
|
|
250
|
-
dateRange?: {
|
|
251
|
-
start: string;
|
|
252
|
-
end: string;
|
|
253
|
-
};
|
|
254
|
-
/** Restrict to specific dates (YYYY-MM-DD). */
|
|
255
|
-
dates?: string[];
|
|
256
|
-
/** Restrict to recurring calendar periods. */
|
|
257
|
-
recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]];
|
|
258
|
-
/** Defaults to `"MANDATORY"`. */
|
|
259
|
-
priority?: Priority;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Options for rules that support entity scoping only (no time scoping).
|
|
263
|
-
*
|
|
264
|
-
* @remarks
|
|
265
|
-
* Used by rules whose semantics are inherently per-day or per-week
|
|
266
|
-
* (e.g., {@link minHoursPerDay}, {@link maxConsecutiveDays}) and cannot
|
|
267
|
-
* be meaningfully restricted to a date range or day of week.
|
|
268
|
-
*
|
|
269
|
-
* @category Rules
|
|
270
|
-
*/
|
|
271
|
-
export interface EntityOnlyRuleOptions {
|
|
272
|
-
/** Who this rule applies to (role name, skill name, or member ID). */
|
|
273
|
-
appliesTo?: string | string[];
|
|
274
|
-
/** Defaults to `"MANDATORY"`. */
|
|
275
|
-
priority?: Priority;
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Options for {@link timeOff}.
|
|
279
|
-
*
|
|
280
|
-
* @remarks
|
|
281
|
-
* At least one time scoping field is required (`dayOfWeek`, `dateRange`,
|
|
282
|
-
* `dates`, or `recurringPeriods`). Use `from`/`until` to block only part
|
|
283
|
-
* of a day.
|
|
284
|
-
*
|
|
285
|
-
* @category Rules
|
|
286
|
-
*/
|
|
287
|
-
export interface TimeOffOptions {
|
|
288
|
-
/** Who this rule applies to (role name, skill name, or member ID). */
|
|
289
|
-
appliesTo?: string | string[];
|
|
290
|
-
/** Off from this time until end of day. */
|
|
291
|
-
from?: TimeOfDay;
|
|
292
|
-
/** Off from start of day until this time. */
|
|
293
|
-
until?: TimeOfDay;
|
|
294
|
-
/** Restrict to specific days of the week. */
|
|
295
|
-
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
296
|
-
/** Restrict to a date range. */
|
|
297
|
-
dateRange?: {
|
|
298
|
-
start: string;
|
|
299
|
-
end: string;
|
|
300
|
-
};
|
|
301
|
-
/** Restrict to specific dates (YYYY-MM-DD). */
|
|
302
|
-
dates?: string[];
|
|
303
|
-
/** Restrict to recurring calendar periods. */
|
|
304
|
-
recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]];
|
|
305
|
-
/** Defaults to `"MANDATORY"`. */
|
|
306
|
-
priority?: Priority;
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Options for {@link assignTogether}.
|
|
310
|
-
*
|
|
311
|
-
* @category Rules
|
|
312
|
-
*/
|
|
313
|
-
export interface AssignTogetherOptions {
|
|
314
|
-
/** Defaults to `"MANDATORY"`. */
|
|
315
|
-
priority?: Priority;
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Options for cost rules.
|
|
319
|
-
*
|
|
320
|
-
* Cost rules are objective terms, not constraints. The `priority` field from
|
|
321
|
-
* {@link RuleOptions} does not apply.
|
|
322
|
-
*
|
|
323
|
-
* @category Cost Optimization
|
|
324
|
-
*/
|
|
325
|
-
export interface CostRuleOptions {
|
|
326
|
-
/** Who this rule applies to (role name, skill name, or member ID). */
|
|
327
|
-
appliesTo?: string | string[];
|
|
328
|
-
/** Restrict to specific days of the week. */
|
|
329
|
-
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
330
|
-
/** Restrict to a date range. */
|
|
331
|
-
dateRange?: {
|
|
332
|
-
start: string;
|
|
333
|
-
end: string;
|
|
334
|
-
};
|
|
335
|
-
/** Restrict to specific dates (YYYY-MM-DD). */
|
|
336
|
-
dates?: string[];
|
|
337
|
-
/** Restrict to recurring calendar periods. */
|
|
338
|
-
recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]];
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Context passed to a rule's resolve function during compilation.
|
|
342
|
-
*
|
|
343
|
-
* Contains the declared roles, skills, and member IDs so the resolver
|
|
344
|
-
* can translate user-facing fields (like `appliesTo`) into internal
|
|
345
|
-
* scoping fields.
|
|
346
|
-
*
|
|
347
|
-
* @category Rules
|
|
348
|
-
*/
|
|
349
|
-
export interface RuleResolveContext {
|
|
350
|
-
readonly roles: ReadonlySet<string>;
|
|
351
|
-
readonly skills: ReadonlySet<string>;
|
|
352
|
-
readonly memberIds: ReadonlySet<string>;
|
|
353
|
-
}
|
|
354
|
-
interface RuleEntryBase {
|
|
355
|
-
readonly _type: "rule";
|
|
356
|
-
readonly _rule: string;
|
|
357
|
-
/**
|
|
358
|
-
* Optional custom resolver. When present, `resolveRules()` calls this
|
|
359
|
-
* instead of the default translation path. Built-in rules that need
|
|
360
|
-
* special field mapping (e.g., `timeOff`, `assignTogether`) attach one;
|
|
361
|
-
* all other rules use the default resolver.
|
|
362
|
-
*/
|
|
363
|
-
readonly _resolve?: (ctx: RuleResolveContext) => Record<string, unknown> & {
|
|
364
|
-
name: string;
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
/**
|
|
368
|
-
* An opaque rule entry returned by rule functions.
|
|
369
|
-
*
|
|
370
|
-
* @remarks
|
|
371
|
-
* Pass these directly into the `rules` array of {@link ScheduleConfig}.
|
|
372
|
-
* The internal fields are resolved during compilation.
|
|
373
|
-
*/
|
|
374
|
-
export type RuleEntry = RuleEntryBase & Record<string, unknown>;
|
|
375
|
-
/**
|
|
376
|
-
* Creates a rule entry for use in {@link ScheduleConfig.rules}.
|
|
377
|
-
*
|
|
378
|
-
* Built-in rules use the helpers (`maxHoursPerDay`, `timeOff`, etc.).
|
|
379
|
-
* Custom rules can use `defineRule` to create entries that plug into the
|
|
380
|
-
* same resolution and compilation pipeline.
|
|
381
|
-
*
|
|
382
|
-
* @param name - Rule name. Must match a key in the rule factory registry.
|
|
383
|
-
* @param fields - Rule-specific configuration fields.
|
|
384
|
-
* @param resolve - Optional custom resolver. When omitted, the default
|
|
385
|
-
* resolution applies: `appliesTo` is mapped to `roleIds`/`skillIds`/`memberIds`,
|
|
386
|
-
* `dates` is renamed to `specificDates`, and all other fields pass through.
|
|
387
|
-
*
|
|
388
|
-
* @category Rules
|
|
389
|
-
*/
|
|
390
|
-
export declare function defineRule(name: string, fields: Record<string, unknown>, resolve?: (ctx: RuleResolveContext) => Record<string, unknown> & {
|
|
391
|
-
name: string;
|
|
392
|
-
}): RuleEntry;
|
|
393
|
-
/**
|
|
394
|
-
* Limits hours per day.
|
|
395
|
-
*
|
|
396
|
-
* @example
|
|
397
|
-
* ```typescript
|
|
398
|
-
* maxHoursPerDay(10)
|
|
399
|
-
* maxHoursPerDay(4, { appliesTo: "student", dayOfWeek: weekdays })
|
|
400
|
-
* ```
|
|
401
|
-
*
|
|
402
|
-
* @category Rules
|
|
403
|
-
*/
|
|
404
|
-
export declare function maxHoursPerDay(hours: number, opts?: RuleOptions): RuleEntry;
|
|
405
|
-
/**
|
|
406
|
-
* Limits hours per scheduling week.
|
|
407
|
-
*
|
|
408
|
-
* @example
|
|
409
|
-
* ```typescript
|
|
410
|
-
* maxHoursPerWeek(48)
|
|
411
|
-
* maxHoursPerWeek(20, { appliesTo: "student" })
|
|
412
|
-
* ```
|
|
413
|
-
*
|
|
414
|
-
* @category Rules
|
|
415
|
-
*/
|
|
416
|
-
export declare function maxHoursPerWeek(hours: number, opts?: RuleOptions): RuleEntry;
|
|
417
|
-
/**
|
|
418
|
-
* Minimum hours when assigned on a day.
|
|
419
|
-
*
|
|
420
|
-
* @example
|
|
421
|
-
* ```typescript
|
|
422
|
-
* minHoursPerDay(4)
|
|
423
|
-
* ```
|
|
424
|
-
*
|
|
425
|
-
* @category Rules
|
|
426
|
-
*/
|
|
427
|
-
export declare function minHoursPerDay(hours: number, opts?: EntityOnlyRuleOptions): RuleEntry;
|
|
428
|
-
/**
|
|
429
|
-
* Minimum hours per scheduling week.
|
|
430
|
-
*
|
|
431
|
-
* @example
|
|
432
|
-
* ```typescript
|
|
433
|
-
* minHoursPerWeek(20, { priority: "HIGH" })
|
|
434
|
-
* ```
|
|
435
|
-
*
|
|
436
|
-
* @category Rules
|
|
437
|
-
*/
|
|
438
|
-
export declare function minHoursPerWeek(hours: number, opts?: EntityOnlyRuleOptions): RuleEntry;
|
|
439
|
-
/**
|
|
440
|
-
* Maximum distinct shifts per day.
|
|
441
|
-
*
|
|
442
|
-
* @example
|
|
443
|
-
* ```typescript
|
|
444
|
-
* maxShiftsPerDay(1)
|
|
445
|
-
* maxShiftsPerDay(2, { appliesTo: "student", dayOfWeek: weekend })
|
|
446
|
-
* ```
|
|
447
|
-
*
|
|
448
|
-
* @category Rules
|
|
449
|
-
*/
|
|
450
|
-
export declare function maxShiftsPerDay(shifts: number, opts?: RuleOptions): RuleEntry;
|
|
451
|
-
/**
|
|
452
|
-
* Maximum consecutive working days.
|
|
453
|
-
*
|
|
454
|
-
* @example
|
|
455
|
-
* ```typescript
|
|
456
|
-
* maxConsecutiveDays(5)
|
|
457
|
-
* ```
|
|
458
|
-
*
|
|
459
|
-
* @category Rules
|
|
460
|
-
*/
|
|
461
|
-
export declare function maxConsecutiveDays(days: number, opts?: EntityOnlyRuleOptions): RuleEntry;
|
|
462
|
-
/**
|
|
463
|
-
* Once working, continue for at least this many consecutive days.
|
|
464
|
-
*
|
|
465
|
-
* @example
|
|
466
|
-
* ```typescript
|
|
467
|
-
* minConsecutiveDays(2, { priority: "HIGH" })
|
|
468
|
-
* ```
|
|
469
|
-
*
|
|
470
|
-
* @category Rules
|
|
471
|
-
*/
|
|
472
|
-
export declare function minConsecutiveDays(days: number, opts?: EntityOnlyRuleOptions): RuleEntry;
|
|
473
|
-
/**
|
|
474
|
-
* Minimum rest hours between shifts.
|
|
475
|
-
*
|
|
476
|
-
* @example
|
|
477
|
-
* ```typescript
|
|
478
|
-
* minRestBetweenShifts(10)
|
|
479
|
-
* ```
|
|
480
|
-
*
|
|
481
|
-
* @category Rules
|
|
482
|
-
*/
|
|
483
|
-
export declare function minRestBetweenShifts(hours: number, opts?: EntityOnlyRuleOptions): RuleEntry;
|
|
484
|
-
/**
|
|
485
|
-
* Prefer (`"high"`) or avoid (`"low"`) assigning. Requires `appliesTo`.
|
|
486
|
-
*
|
|
487
|
-
* @example
|
|
488
|
-
* ```typescript
|
|
489
|
-
* preference("high", { appliesTo: "waiter" })
|
|
490
|
-
* preference("low", { appliesTo: "student", dayOfWeek: weekdays })
|
|
491
|
-
* ```
|
|
492
|
-
*
|
|
493
|
-
* @category Rules
|
|
494
|
-
*/
|
|
495
|
-
export declare function preference(level: "high" | "low", opts?: Omit<RuleOptions, "priority">): RuleEntry;
|
|
496
|
-
/**
|
|
497
|
-
* Prefer assigning to shifts at a specific location. Requires `appliesTo`.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* ```typescript
|
|
501
|
-
* preferLocation("terrace", { appliesTo: "alice" })
|
|
502
|
-
* ```
|
|
503
|
-
*
|
|
504
|
-
* @category Rules
|
|
505
|
-
*/
|
|
506
|
-
export declare function preferLocation(locationId: string, opts?: EntityOnlyRuleOptions): RuleEntry;
|
|
507
|
-
/**
|
|
508
|
-
* Tells the solver to minimize total labor cost.
|
|
509
|
-
*
|
|
510
|
-
* @remarks
|
|
511
|
-
* Without this rule, cost modifiers only affect post-solve calculation.
|
|
512
|
-
* When present, the solver actively prefers cheaper assignments.
|
|
513
|
-
*
|
|
514
|
-
* For hourly members, penalizes each assignment proportionally to cost.
|
|
515
|
-
* For salaried members, adds a fixed weekly salary cost when they have
|
|
516
|
-
* any assignment that week (zero marginal cost up to contracted hours).
|
|
517
|
-
*
|
|
518
|
-
* Cost modifiers adjust the calculation:
|
|
519
|
-
* - `dayMultiplier(factor, opts?)` - multiply base rate on specific days
|
|
520
|
-
* - `daySurcharge(amount, opts?)` - flat extra per hour on specific days
|
|
521
|
-
* - `timeSurcharge(amount, window, opts?)` - flat extra per hour during a time window
|
|
522
|
-
* - `overtimeMultiplier({ after, factor }, opts?)` - weekly overtime multiplier
|
|
523
|
-
* - `overtimeSurcharge({ after, amount }, opts?)` - weekly overtime surcharge
|
|
524
|
-
* - `dailyOvertimeMultiplier({ after, factor }, opts?)` - daily overtime multiplier
|
|
525
|
-
* - `dailyOvertimeSurcharge({ after, amount }, opts?)` - daily overtime surcharge
|
|
526
|
-
* - `tieredOvertimeMultiplier(tiers, opts?)` - multiple overtime thresholds
|
|
527
|
-
*
|
|
528
|
-
* @example
|
|
529
|
-
* ```ts
|
|
530
|
-
* minimizeCost()
|
|
531
|
-
* ```
|
|
532
|
-
*
|
|
533
|
-
* @category Cost Optimization
|
|
534
|
-
*/
|
|
535
|
-
export declare function minimizeCost(opts?: CostRuleOptions): RuleEntry;
|
|
536
|
-
/**
|
|
537
|
-
* Multiplies the base rate for assignments on specified days.
|
|
538
|
-
*
|
|
539
|
-
* @remarks
|
|
540
|
-
* The base cost (1x) is already counted by {@link minimizeCost};
|
|
541
|
-
* this rule adds only the extra portion above 1x.
|
|
542
|
-
*
|
|
543
|
-
* @category Cost Optimization
|
|
544
|
-
*
|
|
545
|
-
* @example Weekend multiplier
|
|
546
|
-
* ```typescript
|
|
547
|
-
* dayMultiplier(1.5, { dayOfWeek: weekend })
|
|
548
|
-
* ```
|
|
549
|
-
*/
|
|
550
|
-
export declare function dayMultiplier(factor: number, opts?: CostRuleOptions): RuleEntry;
|
|
551
|
-
/**
|
|
552
|
-
* Adds a flat extra amount per hour for assignments on specified days.
|
|
553
|
-
*
|
|
554
|
-
* @remarks
|
|
555
|
-
* The surcharge is independent of the member's base rate.
|
|
556
|
-
*
|
|
557
|
-
* @category Cost Optimization
|
|
558
|
-
*
|
|
559
|
-
* @example Weekend surcharge
|
|
560
|
-
* ```typescript
|
|
561
|
-
* daySurcharge(500, { dayOfWeek: weekend })
|
|
562
|
-
* ```
|
|
563
|
-
*/
|
|
564
|
-
export declare function daySurcharge(amountPerHour: number, opts?: CostRuleOptions): RuleEntry;
|
|
565
|
-
/**
|
|
566
|
-
* Adds a flat surcharge per hour for the portion of a shift that overlaps a time-of-day window.
|
|
567
|
-
*
|
|
568
|
-
* @remarks
|
|
569
|
-
* The window supports overnight spans (e.g., 22:00-06:00). The surcharge
|
|
570
|
-
* is independent of the member's base rate.
|
|
571
|
-
*
|
|
572
|
-
* @param amountPerHour - Flat surcharge per hour in smallest currency unit
|
|
573
|
-
* @param window - Time-of-day window
|
|
574
|
-
* @param opts - Entity and time scoping
|
|
575
|
-
*
|
|
576
|
-
* @category Cost Optimization
|
|
577
|
-
*
|
|
578
|
-
* @example Night differential
|
|
579
|
-
* ```typescript
|
|
580
|
-
* timeSurcharge(200, { from: t(22), until: t(6) })
|
|
581
|
-
* ```
|
|
582
|
-
*/
|
|
583
|
-
export declare function timeSurcharge(amountPerHour: number, window: {
|
|
584
|
-
from: TimeOfDay;
|
|
585
|
-
until: TimeOfDay;
|
|
586
|
-
}, opts?: CostRuleOptions): RuleEntry;
|
|
587
|
-
/**
|
|
588
|
-
* Applies a multiplier to hours beyond a weekly threshold.
|
|
589
|
-
*
|
|
590
|
-
* @remarks
|
|
591
|
-
* Only the extra portion above 1x is added (the base cost is already
|
|
592
|
-
* counted by {@link minimizeCost}).
|
|
593
|
-
*
|
|
594
|
-
* @category Cost Optimization
|
|
595
|
-
*
|
|
596
|
-
* @example
|
|
597
|
-
* ```typescript
|
|
598
|
-
* overtimeMultiplier({ after: 40, factor: 1.5 })
|
|
599
|
-
* ```
|
|
600
|
-
*/
|
|
601
|
-
export declare function overtimeMultiplier(opts: {
|
|
602
|
-
after: number;
|
|
603
|
-
factor: number;
|
|
604
|
-
} & CostRuleOptions): RuleEntry;
|
|
605
|
-
/**
|
|
606
|
-
* Adds a flat surcharge per hour beyond a weekly threshold.
|
|
607
|
-
*
|
|
608
|
-
* @remarks
|
|
609
|
-
* The surcharge is independent of the member's base rate.
|
|
610
|
-
*
|
|
611
|
-
* @category Cost Optimization
|
|
612
|
-
*
|
|
613
|
-
* @example
|
|
614
|
-
* ```typescript
|
|
615
|
-
* overtimeSurcharge({ after: 40, amount: 1000 })
|
|
616
|
-
* ```
|
|
617
|
-
*/
|
|
618
|
-
export declare function overtimeSurcharge(opts: {
|
|
619
|
-
after: number;
|
|
620
|
-
amount: number;
|
|
621
|
-
} & CostRuleOptions): RuleEntry;
|
|
622
|
-
/**
|
|
623
|
-
* Applies a multiplier to hours beyond a daily threshold.
|
|
624
|
-
*
|
|
625
|
-
* @remarks
|
|
626
|
-
* Only the extra portion above 1x is added (the base cost is already
|
|
627
|
-
* counted by {@link minimizeCost}).
|
|
628
|
-
*
|
|
629
|
-
* @category Cost Optimization
|
|
630
|
-
*
|
|
631
|
-
* @example
|
|
632
|
-
* ```typescript
|
|
633
|
-
* dailyOvertimeMultiplier({ after: 8, factor: 1.5 })
|
|
634
|
-
* ```
|
|
635
|
-
*/
|
|
636
|
-
export declare function dailyOvertimeMultiplier(opts: {
|
|
637
|
-
after: number;
|
|
638
|
-
factor: number;
|
|
639
|
-
} & CostRuleOptions): RuleEntry;
|
|
640
|
-
/**
|
|
641
|
-
* Adds a flat surcharge per hour beyond a daily threshold.
|
|
642
|
-
*
|
|
643
|
-
* @remarks
|
|
644
|
-
* The surcharge is independent of the member's base rate.
|
|
645
|
-
*
|
|
646
|
-
* @category Cost Optimization
|
|
647
|
-
*
|
|
648
|
-
* @example
|
|
649
|
-
* ```typescript
|
|
650
|
-
* dailyOvertimeSurcharge({ after: 8, amount: 500 })
|
|
651
|
-
* ```
|
|
652
|
-
*/
|
|
653
|
-
export declare function dailyOvertimeSurcharge(opts: {
|
|
654
|
-
after: number;
|
|
655
|
-
amount: number;
|
|
656
|
-
} & CostRuleOptions): RuleEntry;
|
|
657
|
-
/**
|
|
658
|
-
* Applies multiple overtime thresholds with increasing multipliers.
|
|
659
|
-
*
|
|
660
|
-
* @remarks
|
|
661
|
-
* Each tier applies only to the hours between its threshold and the next.
|
|
662
|
-
* Tiers must be sorted by threshold ascending.
|
|
663
|
-
*
|
|
664
|
-
* @category Cost Optimization
|
|
665
|
-
*
|
|
666
|
-
* @example
|
|
667
|
-
* ```typescript
|
|
668
|
-
* // Hours 0-40: base rate
|
|
669
|
-
* // Hours 40-48: 1.5x
|
|
670
|
-
* // Hours 48+: 2.0x
|
|
671
|
-
* tieredOvertimeMultiplier([
|
|
672
|
-
* { after: 40, factor: 1.5 },
|
|
673
|
-
* { after: 48, factor: 2.0 },
|
|
674
|
-
* ])
|
|
675
|
-
* ```
|
|
676
|
-
*/
|
|
677
|
-
export declare function tieredOvertimeMultiplier(tiers: [OvertimeTier, ...OvertimeTier[]], opts?: CostRuleOptions): RuleEntry;
|
|
678
|
-
/**
|
|
679
|
-
* Block assignments during specified periods.
|
|
680
|
-
* Requires at least one time scope (`dayOfWeek`, `dateRange`, `dates`, or `from`/`until`).
|
|
681
|
-
*
|
|
682
|
-
* @example
|
|
683
|
-
* ```typescript
|
|
684
|
-
* // Full days off
|
|
685
|
-
* timeOff({ appliesTo: "alice", dateRange: { start: "2024-02-01", end: "2024-02-05" } })
|
|
686
|
-
*
|
|
687
|
-
* // Every weekend off
|
|
688
|
-
* timeOff({ appliesTo: "mauro", dayOfWeek: weekend })
|
|
689
|
-
*
|
|
690
|
-
* // Wednesday afternoons off
|
|
691
|
-
* timeOff({ appliesTo: "student", dayOfWeek: ["wednesday"], from: t(14) })
|
|
692
|
-
* ```
|
|
693
|
-
*
|
|
694
|
-
* @category Rules
|
|
695
|
-
*/
|
|
696
|
-
export declare function timeOff(opts: TimeOffOptions): RuleEntry;
|
|
697
|
-
/**
|
|
698
|
-
* Members work the same shifts on days they are both assigned.
|
|
699
|
-
*
|
|
700
|
-
* @example
|
|
701
|
-
* ```typescript
|
|
702
|
-
* assignTogether(["alice", "bob"])
|
|
703
|
-
* assignTogether(["alice", "bob", "charlie"], { priority: "HIGH" })
|
|
704
|
-
* ```
|
|
705
|
-
*
|
|
706
|
-
* @category Rules
|
|
707
|
-
*/
|
|
708
|
-
export declare function assignTogether(memberIds: [string, string, ...string[]], opts?: AssignTogetherOptions): RuleEntry;
|
|
709
|
-
/** A value that can be passed to {@link Schedule.with}. */
|
|
710
|
-
type WithArg = Schedule | SchedulingMember[];
|
|
711
|
-
/** Status of a solve attempt, using idiomatic lowercase TypeScript literals. */
|
|
712
|
-
export type SolveStatus = "optimal" | "feasible" | "infeasible" | "no_solution";
|
|
713
|
-
/**
|
|
714
|
-
* Result of {@link Schedule.solve}.
|
|
715
|
-
*
|
|
716
|
-
* @category Schedule Definition
|
|
717
|
-
*/
|
|
718
|
-
export interface SolveResult {
|
|
719
|
-
/** Outcome of the solve attempt. */
|
|
720
|
-
status: SolveStatus;
|
|
721
|
-
/** Shift assignments (empty when infeasible or no solution). */
|
|
722
|
-
assignments: ShiftAssignment[];
|
|
723
|
-
/** Validation diagnostics from compilation. */
|
|
724
|
-
validation: ScheduleValidation;
|
|
725
|
-
/** Cost breakdown (present when cost rules are used and a solution is found). */
|
|
726
|
-
cost?: CostBreakdown;
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Options for {@link Schedule.solve} and {@link Schedule.compile}.
|
|
730
|
-
*
|
|
731
|
-
* @category Schedule Definition
|
|
732
|
-
*/
|
|
733
|
-
export interface SolveOptions {
|
|
734
|
-
/** The date range to schedule. */
|
|
735
|
-
dateRange: {
|
|
736
|
-
start: string;
|
|
737
|
-
end: string;
|
|
738
|
-
};
|
|
739
|
-
/**
|
|
740
|
-
* Fixed assignments from a prior solve (e.g., rolling schedule).
|
|
741
|
-
* These are injected as fixed variables in the solver.
|
|
742
|
-
*
|
|
743
|
-
* Not yet implemented. Providing pinned assignments throws an error.
|
|
744
|
-
*/
|
|
745
|
-
pinned?: ShiftAssignment[];
|
|
746
|
-
}
|
|
747
|
-
/**
|
|
748
|
-
* Configuration for {@link schedule}.
|
|
749
|
-
*
|
|
750
|
-
* @remarks
|
|
751
|
-
* Coverage entries for the same semantic time and target stack additively.
|
|
752
|
-
* An unscoped entry applies every day; adding a weekend-only entry on top
|
|
753
|
-
* doubles the count on those days. Use mutually exclusive `dayOfWeek` on
|
|
754
|
-
* both entries to avoid stacking. See {@link cover} for details.
|
|
755
|
-
*
|
|
756
|
-
* `roleIds`, `times`, `coverage`, and `shiftPatterns` are required.
|
|
757
|
-
* These four fields form the minimum solvable schedule.
|
|
758
|
-
*
|
|
759
|
-
* @category Schedule Definition
|
|
760
|
-
*/
|
|
761
|
-
export interface ScheduleConfig<R extends readonly string[] = readonly string[], S extends readonly string[] = readonly string[], T extends Record<string, SemanticTimeEntry> = Record<string, SemanticTimeEntry>> {
|
|
762
|
-
/** Declared role IDs. */
|
|
763
|
-
roleIds: R;
|
|
764
|
-
/** Declared skill IDs. */
|
|
765
|
-
skillIds?: S;
|
|
766
|
-
/** Named semantic time periods. */
|
|
767
|
-
times: T;
|
|
768
|
-
/** Staffing requirements per time period (entries stack additively). */
|
|
769
|
-
coverage: CoverageEntry<keyof T & string, R[number] | NonNullable<S>[number]>[];
|
|
770
|
-
/** Available shift patterns. */
|
|
771
|
-
shiftPatterns: ShiftPattern[];
|
|
772
|
-
/** Scheduling rules and constraints. */
|
|
773
|
-
rules?: RuleEntry[];
|
|
774
|
-
/**
|
|
775
|
-
* Custom rule factories. Keys are rule names, values are functions
|
|
776
|
-
* that take a config object and return a {@link CompilationRule}.
|
|
777
|
-
* Built-in rule names cannot be overridden.
|
|
778
|
-
*/
|
|
779
|
-
ruleFactories?: Record<string, CreateCpsatRuleFunction>;
|
|
780
|
-
/** Team members (typically added via `.with()` at runtime). */
|
|
781
|
-
members?: SchedulingMember[];
|
|
782
|
-
/** Days of the week the business operates (inclusion filter). */
|
|
783
|
-
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
784
|
-
/** Which day starts the week for weekly rules. Defaults to `"monday"`. */
|
|
785
|
-
weekStartsOn?: DayOfWeek;
|
|
786
|
-
}
|
|
787
|
-
/** Internal representation of a fully merged schedule. */
|
|
788
|
-
interface MergedScheduleConfig {
|
|
789
|
-
roleIds: string[];
|
|
790
|
-
skillIds: string[];
|
|
791
|
-
times: Record<string, SemanticTimeEntry>;
|
|
792
|
-
coverage: CoverageEntry[];
|
|
793
|
-
shiftPatterns: ShiftPattern[];
|
|
794
|
-
rules: RuleEntry[];
|
|
795
|
-
ruleFactories: Record<string, CreateCpsatRuleFunction>;
|
|
796
|
-
members: SchedulingMember[];
|
|
797
|
-
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
798
|
-
weekStartsOn?: DayOfWeek;
|
|
799
|
-
}
|
|
800
|
-
/**
|
|
801
|
-
* An immutable schedule definition.
|
|
802
|
-
*
|
|
803
|
-
* Created by {@link schedule}, composed via {@link Schedule.with},
|
|
804
|
-
* and solved via {@link Schedule.solve}.
|
|
805
|
-
*
|
|
806
|
-
* @category Schedule Definition
|
|
807
|
-
*/
|
|
808
|
-
export declare class Schedule {
|
|
809
|
-
#private;
|
|
810
|
-
/** @internal */
|
|
811
|
-
constructor(config: MergedScheduleConfig);
|
|
812
|
-
/** @internal Returns a defensive copy of the config for merging. */
|
|
813
|
-
_getConfig(): MergedScheduleConfig;
|
|
814
|
-
/** Declared role IDs. */
|
|
815
|
-
get roleIds(): readonly string[];
|
|
816
|
-
/** Declared skill IDs. */
|
|
817
|
-
get skillIds(): readonly string[];
|
|
818
|
-
/** Names of declared semantic times. */
|
|
819
|
-
get timeNames(): readonly string[];
|
|
820
|
-
/** Shift pattern IDs. */
|
|
821
|
-
get shiftPatternIds(): readonly string[];
|
|
822
|
-
/** Internal rule identifiers in kebab-case. */
|
|
823
|
-
get ruleNames(): readonly string[];
|
|
824
|
-
/**
|
|
825
|
-
* Merges schedules or members onto this schedule, returning a new
|
|
826
|
-
* immutable `Schedule`. The original is untouched.
|
|
827
|
-
*
|
|
828
|
-
* Accepts any mix of `Schedule` instances and `SchedulingMember[]` arrays.
|
|
829
|
-
*
|
|
830
|
-
* Merge semantics (when merging schedules):
|
|
831
|
-
* - Roles: union (additive)
|
|
832
|
-
* - Skills: union (additive)
|
|
833
|
-
* - Times: additive; error on name collision
|
|
834
|
-
* - Coverage: additive
|
|
835
|
-
* - Shift patterns: additive; error on ID collision
|
|
836
|
-
* - Rules: additive
|
|
837
|
-
* - Members: additive; error on duplicate ID
|
|
838
|
-
*
|
|
839
|
-
* Validation runs eagerly: role/skill disjointness, coverage targets
|
|
840
|
-
* referencing declared roles/skills, member role references, etc.
|
|
841
|
-
*/
|
|
842
|
-
with(...args: WithArg[]): Schedule;
|
|
843
|
-
/**
|
|
844
|
-
* Compiles, validates, solves, and parses in one call.
|
|
845
|
-
*
|
|
846
|
-
* @param client - Solver client (e.g., `new HttpSolverClient(fetch, url)`)
|
|
847
|
-
* @param options - Date range and optional pinned assignments
|
|
848
|
-
*/
|
|
849
|
-
solve(client: SolverClient, options: SolveOptions): Promise<SolveResult>;
|
|
850
|
-
/**
|
|
851
|
-
* Diagnostic escape hatch. Compiles the schedule without solving.
|
|
852
|
-
*
|
|
853
|
-
* @param options - Date range and optional pinned assignments
|
|
854
|
-
*/
|
|
855
|
-
compile(options: SolveOptions): CompilationResult & {
|
|
856
|
-
builder: ModelBuilder;
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
/**
|
|
860
|
-
* Create a schedule definition.
|
|
861
|
-
*
|
|
862
|
-
* Returns an immutable {@link Schedule} that can be composed via `.with()`
|
|
863
|
-
* and solved via `.solve()`.
|
|
864
|
-
*
|
|
865
|
-
* @example
|
|
866
|
-
* ```typescript
|
|
867
|
-
* const venue = schedule({
|
|
868
|
-
* roleIds: ["waiter", "runner", "manager"],
|
|
869
|
-
* skillIds: ["senior"],
|
|
870
|
-
* times: {
|
|
871
|
-
* lunch: time({ startTime: t(12), endTime: t(15) }),
|
|
872
|
-
* dinner: time(
|
|
873
|
-
* { startTime: t(17), endTime: t(21) },
|
|
874
|
-
* { startTime: t(18), endTime: t(22), dayOfWeek: weekend },
|
|
875
|
-
* ),
|
|
876
|
-
* },
|
|
877
|
-
* coverage: [
|
|
878
|
-
* cover("lunch", "waiter", 2),
|
|
879
|
-
* cover("dinner", "waiter", 4, { dayOfWeek: weekdays }),
|
|
880
|
-
* cover("dinner", "waiter", 5, { dayOfWeek: weekend }),
|
|
881
|
-
* cover("dinner", "manager", 1),
|
|
882
|
-
* ],
|
|
883
|
-
* shiftPatterns: [
|
|
884
|
-
* shift("lunch_shift", t(11, 30), t(15)),
|
|
885
|
-
* shift("evening", t(17), t(22)),
|
|
886
|
-
* ],
|
|
887
|
-
* rules: [
|
|
888
|
-
* maxHoursPerDay(10),
|
|
889
|
-
* maxHoursPerWeek(48),
|
|
890
|
-
* minRestBetweenShifts(11),
|
|
891
|
-
* ],
|
|
892
|
-
* });
|
|
893
|
-
* ```
|
|
894
|
-
*
|
|
895
|
-
* @category Schedule Definition
|
|
896
|
-
*/
|
|
897
|
-
export declare function schedule<const R extends readonly string[], const S extends readonly string[], const T extends Record<string, SemanticTimeEntry>>(config: ScheduleConfig<R, S, T>): Schedule;
|
|
898
|
-
/**
|
|
899
|
-
* Create a partial schedule for composition via `.with()`.
|
|
900
|
-
*
|
|
901
|
-
* Unlike {@link schedule}, all fields are optional. Use this for
|
|
902
|
-
* schedules that layer rules, coverage, or other config onto a
|
|
903
|
-
* complete base schedule.
|
|
904
|
-
*
|
|
905
|
-
* @example
|
|
906
|
-
* ```typescript
|
|
907
|
-
* const companyPolicy = partialSchedule({
|
|
908
|
-
* rules: [maxHoursPerWeek(40), minRestBetweenShifts(11)],
|
|
909
|
-
* });
|
|
910
|
-
*
|
|
911
|
-
* const ready = venue.with(companyPolicy, teamMembers);
|
|
912
|
-
* ```
|
|
913
|
-
*
|
|
914
|
-
* @category Schedule Definition
|
|
915
|
-
*/
|
|
916
|
-
export declare function partialSchedule(config: Partial<ScheduleConfig>): Schedule;
|
|
917
|
-
//# sourceMappingURL=schedule.d.ts.map
|