dabke 0.81.1 → 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.
Files changed (231) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +45 -27
  3. package/dist/client.d.ts +20 -2
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +4 -1
  6. package/dist/client.js.map +1 -1
  7. package/dist/client.types.d.ts +9 -0
  8. package/dist/client.types.d.ts.map +1 -1
  9. package/dist/client.types.js +1 -0
  10. package/dist/client.types.js.map +1 -1
  11. package/dist/cpsat/model-builder.d.ts +9 -0
  12. package/dist/cpsat/model-builder.d.ts.map +1 -1
  13. package/dist/cpsat/model-builder.js +36 -34
  14. package/dist/cpsat/model-builder.js.map +1 -1
  15. package/dist/cpsat/response.d.ts +13 -1
  16. package/dist/cpsat/response.d.ts.map +1 -1
  17. package/dist/cpsat/response.js +4 -0
  18. package/dist/cpsat/response.js.map +1 -1
  19. package/dist/cpsat/rules/cost-utils.d.ts +11 -0
  20. package/dist/cpsat/rules/cost-utils.d.ts.map +1 -0
  21. package/dist/cpsat/rules/cost-utils.js +24 -0
  22. package/dist/cpsat/rules/cost-utils.js.map +1 -0
  23. package/dist/cpsat/rules/day-cost-multiplier.d.ts.map +1 -1
  24. package/dist/cpsat/rules/day-cost-multiplier.js +3 -14
  25. package/dist/cpsat/rules/day-cost-multiplier.js.map +1 -1
  26. package/dist/cpsat/rules/day-cost-surcharge.d.ts.map +1 -1
  27. package/dist/cpsat/rules/day-cost-surcharge.js +3 -7
  28. package/dist/cpsat/rules/day-cost-surcharge.js.map +1 -1
  29. package/dist/cpsat/rules/index.d.ts +3 -0
  30. package/dist/cpsat/rules/index.d.ts.map +1 -1
  31. package/dist/cpsat/rules/index.js +3 -0
  32. package/dist/cpsat/rules/index.js.map +1 -1
  33. package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -1
  34. package/dist/cpsat/rules/max-consecutive-days.js +16 -2
  35. package/dist/cpsat/rules/max-consecutive-days.js.map +1 -1
  36. package/dist/cpsat/rules/max-days-week.d.ts +44 -0
  37. package/dist/cpsat/rules/max-days-week.d.ts.map +1 -0
  38. package/dist/cpsat/rules/max-days-week.js +95 -0
  39. package/dist/cpsat/rules/max-days-week.js.map +1 -0
  40. package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -1
  41. package/dist/cpsat/rules/max-hours-day.js +15 -2
  42. package/dist/cpsat/rules/max-hours-day.js.map +1 -1
  43. package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -1
  44. package/dist/cpsat/rules/max-hours-week.js +16 -2
  45. package/dist/cpsat/rules/max-hours-week.js.map +1 -1
  46. package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -1
  47. package/dist/cpsat/rules/max-shifts-day.js +15 -2
  48. package/dist/cpsat/rules/max-shifts-day.js.map +1 -1
  49. package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -1
  50. package/dist/cpsat/rules/min-consecutive-days.js +15 -2
  51. package/dist/cpsat/rules/min-consecutive-days.js.map +1 -1
  52. package/dist/cpsat/rules/min-days-week.d.ts +34 -0
  53. package/dist/cpsat/rules/min-days-week.d.ts.map +1 -0
  54. package/dist/cpsat/rules/min-days-week.js +84 -0
  55. package/dist/cpsat/rules/min-days-week.js.map +1 -0
  56. package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -1
  57. package/dist/cpsat/rules/min-hours-day.js +15 -2
  58. package/dist/cpsat/rules/min-hours-day.js.map +1 -1
  59. package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -1
  60. package/dist/cpsat/rules/min-hours-week.js +16 -2
  61. package/dist/cpsat/rules/min-hours-week.js.map +1 -1
  62. package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -1
  63. package/dist/cpsat/rules/min-rest-between-shifts.js +72 -2
  64. package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -1
  65. package/dist/cpsat/rules/minimize-cost.d.ts.map +1 -1
  66. package/dist/cpsat/rules/minimize-cost.js +2 -23
  67. package/dist/cpsat/rules/minimize-cost.js.map +1 -1
  68. package/dist/cpsat/rules/must-assign.d.ts +49 -0
  69. package/dist/cpsat/rules/must-assign.d.ts.map +1 -0
  70. package/dist/cpsat/rules/must-assign.js +86 -0
  71. package/dist/cpsat/rules/must-assign.js.map +1 -0
  72. package/dist/cpsat/rules/overtime-daily-multiplier.d.ts.map +1 -1
  73. package/dist/cpsat/rules/overtime-daily-multiplier.js +1 -12
  74. package/dist/cpsat/rules/overtime-daily-multiplier.js.map +1 -1
  75. package/dist/cpsat/rules/overtime-daily-surcharge.d.ts.map +1 -1
  76. package/dist/cpsat/rules/overtime-daily-surcharge.js +1 -5
  77. package/dist/cpsat/rules/overtime-daily-surcharge.js.map +1 -1
  78. package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts +5 -1
  79. package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts.map +1 -1
  80. package/dist/cpsat/rules/overtime-tiered-multiplier.js +1 -12
  81. package/dist/cpsat/rules/overtime-tiered-multiplier.js.map +1 -1
  82. package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts.map +1 -1
  83. package/dist/cpsat/rules/overtime-weekly-multiplier.js +1 -12
  84. package/dist/cpsat/rules/overtime-weekly-multiplier.js.map +1 -1
  85. package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts.map +1 -1
  86. package/dist/cpsat/rules/overtime-weekly-surcharge.js +1 -5
  87. package/dist/cpsat/rules/overtime-weekly-surcharge.js.map +1 -1
  88. package/dist/cpsat/rules/registry.d.ts +28 -2
  89. package/dist/cpsat/rules/registry.d.ts.map +1 -1
  90. package/dist/cpsat/rules/registry.js +4 -1
  91. package/dist/cpsat/rules/registry.js.map +1 -1
  92. package/dist/cpsat/rules/resolver.js +2 -2
  93. package/dist/cpsat/rules/resolver.js.map +1 -1
  94. package/dist/cpsat/rules/rules.types.d.ts +3 -0
  95. package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
  96. package/dist/cpsat/rules/scope.types.d.ts +18 -1
  97. package/dist/cpsat/rules/scope.types.d.ts.map +1 -1
  98. package/dist/cpsat/rules/scope.types.js +59 -16
  99. package/dist/cpsat/rules/scope.types.js.map +1 -1
  100. package/dist/cpsat/rules/time-cost-surcharge.d.ts.map +1 -1
  101. package/dist/cpsat/rules/time-cost-surcharge.js +2 -1
  102. package/dist/cpsat/rules/time-cost-surcharge.js.map +1 -1
  103. package/dist/cpsat/rules/time-off.d.ts.map +1 -1
  104. package/dist/cpsat/rules/time-off.js +6 -3
  105. package/dist/cpsat/rules/time-off.js.map +1 -1
  106. package/dist/cpsat/semantic-time.d.ts +44 -42
  107. package/dist/cpsat/semantic-time.d.ts.map +1 -1
  108. package/dist/cpsat/semantic-time.js +64 -46
  109. package/dist/cpsat/semantic-time.js.map +1 -1
  110. package/dist/cpsat/types.d.ts +37 -27
  111. package/dist/cpsat/types.d.ts.map +1 -1
  112. package/dist/cpsat/utils.d.ts.map +1 -1
  113. package/dist/cpsat/utils.js +7 -12
  114. package/dist/cpsat/utils.js.map +1 -1
  115. package/dist/cpsat/validation-reporter.d.ts +10 -7
  116. package/dist/cpsat/validation-reporter.d.ts.map +1 -1
  117. package/dist/cpsat/validation-reporter.js +44 -72
  118. package/dist/cpsat/validation-reporter.js.map +1 -1
  119. package/dist/cpsat/validation.types.d.ts +54 -44
  120. package/dist/cpsat/validation.types.d.ts.map +1 -1
  121. package/dist/cpsat/validation.types.js +15 -10
  122. package/dist/cpsat/validation.types.js.map +1 -1
  123. package/dist/datetime.utils.d.ts +3 -203
  124. package/dist/datetime.utils.d.ts.map +1 -1
  125. package/dist/datetime.utils.js +1 -288
  126. package/dist/datetime.utils.js.map +1 -1
  127. package/dist/index.d.ts +14 -83
  128. package/dist/index.d.ts.map +1 -1
  129. package/dist/index.js +11 -83
  130. package/dist/index.js.map +1 -1
  131. package/dist/schedule/cost.d.ts +204 -0
  132. package/dist/schedule/cost.d.ts.map +1 -0
  133. package/dist/schedule/cost.js +187 -0
  134. package/dist/schedule/cost.js.map +1 -0
  135. package/dist/schedule/coverage.d.ts +85 -0
  136. package/dist/schedule/coverage.d.ts.map +1 -0
  137. package/dist/schedule/coverage.js +33 -0
  138. package/dist/schedule/coverage.js.map +1 -0
  139. package/dist/schedule/definition.d.ts +227 -0
  140. package/dist/schedule/definition.d.ts.map +1 -0
  141. package/dist/schedule/definition.js +659 -0
  142. package/dist/schedule/definition.js.map +1 -0
  143. package/dist/schedule/index.d.ts +67 -0
  144. package/dist/schedule/index.d.ts.map +1 -0
  145. package/dist/schedule/index.js +69 -0
  146. package/dist/schedule/index.js.map +1 -0
  147. package/dist/schedule/rules.d.ts +353 -0
  148. package/dist/schedule/rules.d.ts.map +1 -0
  149. package/dist/schedule/rules.js +352 -0
  150. package/dist/schedule/rules.js.map +1 -0
  151. package/dist/schedule/shift-patterns.d.ts +34 -0
  152. package/dist/schedule/shift-patterns.d.ts.map +1 -0
  153. package/dist/schedule/shift-patterns.js +41 -0
  154. package/dist/schedule/shift-patterns.js.map +1 -0
  155. package/dist/schedule/time-periods.d.ts +69 -0
  156. package/dist/schedule/time-periods.d.ts.map +1 -0
  157. package/dist/schedule/time-periods.js +91 -0
  158. package/dist/schedule/time-periods.js.map +1 -0
  159. package/dist/types.d.ts +14 -78
  160. package/dist/types.d.ts.map +1 -1
  161. package/dist/types.js.map +1 -1
  162. package/package.json +4 -9
  163. package/solver/src/solver/app.py +1 -1
  164. package/solver/src/solver/solver.py +7 -4
  165. package/src/client.ts +6 -8
  166. package/src/client.types.ts +9 -0
  167. package/src/cpsat/model-builder.ts +44 -35
  168. package/src/cpsat/response.ts +13 -1
  169. package/src/cpsat/rules/cost-utils.ts +25 -0
  170. package/src/cpsat/rules/day-cost-multiplier.ts +3 -14
  171. package/src/cpsat/rules/day-cost-surcharge.ts +3 -8
  172. package/src/cpsat/rules/index.ts +3 -0
  173. package/src/cpsat/rules/max-consecutive-days.ts +17 -0
  174. package/src/cpsat/rules/max-days-week.ts +143 -0
  175. package/src/cpsat/rules/max-hours-day.ts +21 -1
  176. package/src/cpsat/rules/max-hours-week.ts +22 -1
  177. package/src/cpsat/rules/max-shifts-day.ts +21 -1
  178. package/src/cpsat/rules/min-consecutive-days.ts +16 -1
  179. package/src/cpsat/rules/min-days-week.ts +120 -0
  180. package/src/cpsat/rules/min-hours-day.ts +16 -1
  181. package/src/cpsat/rules/min-hours-week.ts +17 -1
  182. package/src/cpsat/rules/min-rest-between-shifts.ts +92 -2
  183. package/src/cpsat/rules/minimize-cost.ts +2 -29
  184. package/src/cpsat/rules/must-assign.ts +108 -0
  185. package/src/cpsat/rules/overtime-daily-multiplier.ts +1 -12
  186. package/src/cpsat/rules/overtime-daily-surcharge.ts +1 -6
  187. package/src/cpsat/rules/overtime-tiered-multiplier.ts +6 -13
  188. package/src/cpsat/rules/overtime-weekly-multiplier.ts +1 -12
  189. package/src/cpsat/rules/overtime-weekly-surcharge.ts +1 -6
  190. package/src/cpsat/rules/registry.ts +8 -2
  191. package/src/cpsat/rules/resolver.ts +2 -2
  192. package/src/cpsat/rules/rules.types.ts +3 -0
  193. package/src/cpsat/rules/scope.types.ts +73 -20
  194. package/src/cpsat/rules/time-cost-surcharge.ts +2 -1
  195. package/src/cpsat/rules/time-off.ts +6 -2
  196. package/src/cpsat/semantic-time.ts +115 -91
  197. package/src/cpsat/types.ts +37 -27
  198. package/src/cpsat/utils.ts +8 -12
  199. package/src/cpsat/validation-reporter.ts +51 -82
  200. package/src/cpsat/validation.types.ts +72 -47
  201. package/src/datetime.utils.ts +3 -334
  202. package/src/index.ts +35 -107
  203. package/src/schedule/cost.ts +242 -0
  204. package/src/schedule/coverage.ts +135 -0
  205. package/src/schedule/definition.ts +958 -0
  206. package/src/schedule/index.ts +112 -0
  207. package/src/schedule/rules.ts +529 -0
  208. package/src/schedule/shift-patterns.ts +46 -0
  209. package/src/schedule/time-periods.ts +110 -0
  210. package/src/types.ts +14 -88
  211. package/dist/errors.d.ts +0 -12
  212. package/dist/errors.d.ts.map +0 -1
  213. package/dist/errors.js +0 -17
  214. package/dist/errors.js.map +0 -1
  215. package/dist/llms.d.ts +0 -2
  216. package/dist/llms.d.ts.map +0 -1
  217. package/dist/llms.js +0 -3
  218. package/dist/llms.js.map +0 -1
  219. package/dist/schedule.d.ts +0 -724
  220. package/dist/schedule.d.ts.map +0 -1
  221. package/dist/schedule.js +0 -899
  222. package/dist/schedule.js.map +0 -1
  223. package/dist/validation.d.ts +0 -105
  224. package/dist/validation.d.ts.map +0 -1
  225. package/dist/validation.js +0 -130
  226. package/dist/validation.js.map +0 -1
  227. package/llms.txt +0 -925
  228. package/src/errors.ts +0 -17
  229. package/src/llms.ts +0 -3
  230. package/src/schedule.ts +0 -1419
  231. package/src/validation.ts +0 -188
@@ -1,724 +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
- * defineSchedule, t, time, cover, shift,
12
- * maxHoursPerDay, maxHoursPerWeek, minRestBetweenShifts,
13
- * weekdays, weekend,
14
- * } from "dabke";
15
- *
16
- * export default defineSchedule({
17
- * roles: ["cashier", "floor_lead", "stocker"],
18
- * skills: ["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
- *
49
- * @module
50
- */
51
- import type { DayOfWeek, SchedulingPeriod, TimeOfDay } from "./types.js";
52
- import type { SemanticTimeVariant, SemanticTimeEntry, CoverageVariant } from "./cpsat/semantic-time.js";
53
- export type { CoverageVariant } from "./cpsat/semantic-time.js";
54
- import type { ModelBuilderConfig } from "./cpsat/model-builder.js";
55
- import type { SchedulingMember, ShiftPattern, Priority } from "./cpsat/types.js";
56
- import type { CpsatRuleName } from "./cpsat/rules/rules.types.js";
57
- import type { RecurringPeriod } from "./cpsat/rules/scope.types.js";
58
- import type { OvertimeTier } from "./cpsat/rules/overtime-tiered-multiplier.js";
59
- /**
60
- * Creates a {@link TimeOfDay} value.
61
- *
62
- * @param hours - Hour component (0-23)
63
- * @param minutes - Minute component (0-59)
64
- *
65
- * @example Hours only
66
- * ```ts
67
- * t(9) // { hours: 9, minutes: 0 }
68
- * ```
69
- *
70
- * @example Hours and minutes
71
- * ```ts
72
- * t(17, 30) // { hours: 17, minutes: 30 }
73
- * ```
74
- */
75
- export declare function t(hours: number, minutes?: number): TimeOfDay;
76
- /** Monday through Friday. */
77
- export declare const weekdays: readonly DayOfWeek[];
78
- /** Saturday and Sunday. */
79
- export declare const weekend: readonly DayOfWeek[];
80
- /**
81
- * Defines a named time window.
82
- *
83
- * @remarks
84
- * A semantic time is any recurring period you need to reference:
85
- * service hours, delivery windows, peak periods, weekly events. Times
86
- * may overlap (e.g., "dinner" 18:00-22:00 and "happy_hour"
87
- * 17:30-18:30, or "lunch" 12:00-14:00 with "peak_lunch"
88
- * 13:00-13:30). Coverage and rules reference these names; each
89
- * generates independent constraints.
90
- *
91
- * Every argument is a {@link SemanticTimeVariant} with `startTime`/`endTime`
92
- * and optional `dayOfWeek`/`dates` scoping. An entry without scoping is the
93
- * default (applies when no scoped entry matches). At most one default is
94
- * allowed. If no default, the time only exists on the scoped days.
95
- *
96
- * Resolution precedence: `dates` > `dayOfWeek` > default.
97
- *
98
- * @example Every day
99
- * ```typescript
100
- * day_shift: time({ startTime: t(7), endTime: t(15) }),
101
- * ```
102
- *
103
- * @example Default with weekend variant
104
- * ```typescript
105
- * peak_hours: time(
106
- * { startTime: t(9), endTime: t(17) },
107
- * { startTime: t(10), endTime: t(15), dayOfWeek: weekend },
108
- * ),
109
- * ```
110
- *
111
- * @example No default (specific days only)
112
- * ```typescript
113
- * happy_hour: time(
114
- * { startTime: t(16), endTime: t(18), dayOfWeek: ["monday", "tuesday"] },
115
- * { startTime: t(17), endTime: t(19), dayOfWeek: ["friday"] },
116
- * ),
117
- * ```
118
- */
119
- export declare function time(...entries: [SemanticTimeVariant, ...SemanticTimeVariant[]]): SemanticTimeEntry;
120
- /**
121
- * Options for a {@link cover} call.
122
- *
123
- * @remarks
124
- * Day/date scoping controls which days this coverage entry applies to.
125
- * An entry without `dayOfWeek` or `dates` applies every day in the
126
- * scheduling period.
127
- */
128
- export interface CoverageOptions {
129
- /** Additional skill filter (AND logic with the target role). */
130
- skills?: [string, ...string[]];
131
- /** Restrict to specific days of the week. */
132
- dayOfWeek?: readonly DayOfWeek[];
133
- /** Restrict to specific dates (YYYY-MM-DD). */
134
- dates?: string[];
135
- /** Defaults to `"MANDATORY"`. */
136
- priority?: Priority;
137
- }
138
- /**
139
- * A coverage entry returned by {@link cover}.
140
- *
141
- * @remarks
142
- * Carries the semantic time name and target type information for
143
- * compile-time validation by {@link defineSchedule}. This is an opaque
144
- * token; pass it directly into the `coverage` array.
145
- */
146
- export interface CoverageEntry<T extends string = string, R extends string = string> {
147
- /** @internal */ readonly _type: "coverage";
148
- /** @internal */ readonly timeName: T;
149
- /** @internal */ readonly target: R | R[];
150
- /** @internal */ readonly count: number;
151
- /** @internal */ readonly options: CoverageOptions;
152
- /** @internal When present, this entry uses variant-based resolution. */
153
- readonly variants?: readonly CoverageVariant[];
154
- }
155
- /**
156
- * Defines a staffing requirement for a semantic time period.
157
- *
158
- * @remarks
159
- * Two call forms are supported:
160
- *
161
- * **Simple form** `cover(time, target, count, opts?)` creates a single
162
- * constraint. Use `dayOfWeek`/`dates` in `opts` to restrict which days
163
- * it applies to.
164
- *
165
- * **Variant form** `cover(time, target, ...variants)` accepts one or more
166
- * {@link CoverageVariant} entries with day-specific counts. For each
167
- * scheduling day, exactly one variant is selected using the same
168
- * precedence as {@link time}: `dates` > `dayOfWeek` > default (unscoped).
169
- * At most one variant may be unscoped (the default). Days with no matching
170
- * variant produce no coverage. See {@link CoverageVariant} for the entry
171
- * shape.
172
- *
173
- * **Target resolution.** The `target` parameter is resolved against declared
174
- * `roles` and `skills`:
175
- *
176
- * - Single string: matched against roles first, then skills.
177
- * - Array of strings: OR logic (any of the listed roles).
178
- * - With `skills` option (simple form only): role AND skill(s) filter.
179
- *
180
- * @param timeName - Name of a declared semantic time
181
- * @param target - Role name, skill name, or array of role names (OR)
182
- * @param count - Number of people needed (simple form)
183
- * @param opts - See {@link CoverageOptions} (simple form)
184
- *
185
- * @example Basic role coverage
186
- * ```ts
187
- * cover("day_shift", "nurse", 3)
188
- * ```
189
- *
190
- * @example OR logic (any of the listed roles)
191
- * ```ts
192
- * cover("day_shift", ["manager", "team_lead"], 1)
193
- * ```
194
- *
195
- * @example Skill-based coverage
196
- * ```ts
197
- * cover("night_shift", "keyholder", 1)
198
- * ```
199
- *
200
- * @example Role with skill filter (role AND skill)
201
- * ```ts
202
- * cover("day_shift", "nurse", 1, { skills: ["charge_nurse"] })
203
- * ```
204
- *
205
- * @example Day-of-week scoping (simple form)
206
- * ```ts
207
- * cover("peak_hours", "cashier", 3, { dayOfWeek: weekdays }),
208
- * cover("peak_hours", "cashier", 5, { dayOfWeek: weekend }),
209
- * ```
210
- *
211
- * @example Default with date override (variant form)
212
- * ```ts
213
- * cover("peak_hours", "agent",
214
- * { count: 4 },
215
- * { count: 2, dates: ["2025-12-24"] },
216
- * )
217
- * ```
218
- *
219
- * @example Weekday vs weekend with holiday override (variant form)
220
- * ```ts
221
- * cover("peak_hours", "agent",
222
- * { count: 3, dayOfWeek: weekdays },
223
- * { count: 5, dayOfWeek: weekend },
224
- * { count: 8, dates: ["2025-12-31"] },
225
- * )
226
- * ```
227
- */
228
- export declare function cover<T extends string, R extends string>(timeName: T, target: R | [R, ...R[]], count: number, opts?: CoverageOptions): CoverageEntry<T, R>;
229
- export declare function cover<T extends string, R extends string>(timeName: T, target: R | [R, ...R[]], ...variants: [CoverageVariant, ...CoverageVariant[]]): CoverageEntry<T, R>;
230
- /**
231
- * Creates a {@link ShiftPattern} (time slot template).
232
- *
233
- * @remarks
234
- * Shift patterns define when people can work: the concrete time slots
235
- * the solver may assign members to. Each pattern repeats across all
236
- * scheduling days unless filtered by `dayOfWeek` or `roles`.
237
- *
238
- * @example
239
- * ```typescript
240
- * shift("early", t(6), t(14)),
241
- * shift("day", t(9), t(17)),
242
- * shift("night", t(22), t(6), { roles: ["nurse", "doctor"] }),
243
- * ```
244
- */
245
- export declare function shift(id: string, startTime: TimeOfDay, endTime: TimeOfDay, opts?: Pick<ShiftPattern, "roles" | "dayOfWeek" | "locationId">): ShiftPattern;
246
- /**
247
- * Scoping options shared by most rule functions.
248
- *
249
- * @remarks
250
- * Each rule function returns an opaque {@link RuleEntry} for the `rules`
251
- * array. Most accept a `RuleOptions` parameter for scoping and priority.
252
- *
253
- * **Entity scoping.** `appliesTo` targets a role name, skill name, or
254
- * member ID. It is resolved against declared roles first, then skills,
255
- * then runtime member IDs. The namespaces are guaranteed disjoint by
256
- * validation. Unscoped rules apply to all members.
257
- *
258
- * **Time scoping.** `dayOfWeek`, `dateRange`, `dates`, and
259
- * `recurringPeriods` narrow when the rule is active. Unscoped rules
260
- * apply to every day in the scheduling period.
261
- *
262
- * **Priority.** Defaults to `MANDATORY` (hard constraint the solver
263
- * must satisfy). Use `LOW`, `MEDIUM`, or `HIGH` for soft preferences
264
- * the solver may violate when necessary.
265
- */
266
- export interface RuleOptions {
267
- /** Who this rule applies to (role name, skill name, or member ID). */
268
- appliesTo?: string | string[];
269
- /** Restrict to specific days of the week. */
270
- dayOfWeek?: readonly DayOfWeek[];
271
- /** Restrict to a date range. */
272
- dateRange?: {
273
- start: string;
274
- end: string;
275
- };
276
- /** Restrict to specific dates (YYYY-MM-DD). */
277
- dates?: string[];
278
- /** Restrict to recurring calendar periods. */
279
- recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]];
280
- /** Defaults to `"MANDATORY"`. */
281
- priority?: Priority;
282
- }
283
- /**
284
- * Options for rules that support entity scoping only (no time scoping).
285
- *
286
- * @remarks
287
- * Used by rules whose semantics are inherently per-day or per-week
288
- * (e.g., {@link minHoursPerDay}, {@link maxConsecutiveDays}) and cannot
289
- * be meaningfully restricted to a date range or day of week.
290
- */
291
- export interface EntityOnlyRuleOptions {
292
- /** Who this rule applies to (role name, skill name, or member ID). */
293
- appliesTo?: string | string[];
294
- /** Defaults to `"MANDATORY"`. */
295
- priority?: Priority;
296
- }
297
- /**
298
- * Options for {@link timeOff}.
299
- *
300
- * @remarks
301
- * At least one time scoping field is required (`dayOfWeek`, `dateRange`,
302
- * `dates`, or `recurringPeriods`). Use `from`/`until` to block only part
303
- * of a day.
304
- */
305
- export interface TimeOffOptions {
306
- /** Who this rule applies to (role name, skill name, or member ID). */
307
- appliesTo?: string | string[];
308
- /** Off from this time until end of day. */
309
- from?: TimeOfDay;
310
- /** Off from start of day until this time. */
311
- until?: TimeOfDay;
312
- /** Restrict to specific days of the week. */
313
- dayOfWeek?: readonly DayOfWeek[];
314
- /** Restrict to a date range. */
315
- dateRange?: {
316
- start: string;
317
- end: string;
318
- };
319
- /** Restrict to specific dates (YYYY-MM-DD). */
320
- dates?: string[];
321
- /** Restrict to recurring calendar periods. */
322
- recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]];
323
- /** Defaults to `"MANDATORY"`. */
324
- priority?: Priority;
325
- }
326
- /** Options for {@link assignTogether}. */
327
- export interface AssignTogetherOptions {
328
- /** Defaults to `"MANDATORY"`. */
329
- priority?: Priority;
330
- }
331
- /**
332
- * Options for cost rules.
333
- *
334
- * Cost rules are objective terms, not constraints. The `priority` field from
335
- * {@link RuleOptions} does not apply.
336
- */
337
- export interface CostRuleOptions {
338
- /** Who this rule applies to (role name, skill name, or member ID). */
339
- appliesTo?: string | string[];
340
- /** Restrict to specific days of the week. */
341
- dayOfWeek?: DayOfWeek[];
342
- /** Restrict to a date range. */
343
- dateRange?: {
344
- start: string;
345
- end: string;
346
- };
347
- /** Restrict to specific dates (YYYY-MM-DD). */
348
- dates?: string[];
349
- /** Restrict to recurring calendar periods. */
350
- recurringPeriods?: [RecurringPeriod, ...RecurringPeriod[]];
351
- }
352
- interface RuleEntryBase {
353
- readonly _type: "rule";
354
- readonly _rule: CpsatRuleName;
355
- }
356
- /**
357
- * An opaque rule entry returned by rule functions.
358
- *
359
- * @remarks
360
- * Pass these directly into the `rules` array of {@link ScheduleConfig} or
361
- * the `runtimeRules` array of {@link RuntimeArgs}. The internal fields are
362
- * resolved during {@link ScheduleDefinition.createSchedulerConfig}.
363
- */
364
- export type RuleEntry = RuleEntryBase & Record<string, unknown>;
365
- /**
366
- * Limits how many hours a person can work in a single day.
367
- *
368
- * @example Global limit
369
- * ```ts
370
- * maxHoursPerDay(10)
371
- * ```
372
- *
373
- * @example Scoped to a role
374
- * ```ts
375
- * maxHoursPerDay(6, { appliesTo: "student" })
376
- * ```
377
- */
378
- export declare function maxHoursPerDay(hours: number, opts?: RuleOptions): RuleEntry;
379
- /**
380
- * Caps total hours a person can work within each scheduling week.
381
- *
382
- * @example Global cap
383
- * ```ts
384
- * maxHoursPerWeek(48)
385
- * ```
386
- *
387
- * @example Part-time cap for a skill group
388
- * ```ts
389
- * maxHoursPerWeek(20, { appliesTo: "part_time" })
390
- * ```
391
- */
392
- export declare function maxHoursPerWeek(hours: number, opts?: RuleOptions): RuleEntry;
393
- /**
394
- * Ensures a person works at least a minimum number of hours per day when assigned.
395
- *
396
- * @example
397
- * ```ts
398
- * minHoursPerDay(4)
399
- * ```
400
- */
401
- export declare function minHoursPerDay(hours: number, opts?: EntityOnlyRuleOptions): RuleEntry;
402
- /**
403
- * Enforces a minimum total number of hours per scheduling week.
404
- *
405
- * @example Guaranteed minimum for full-time members
406
- * ```ts
407
- * minHoursPerWeek(30, { appliesTo: "full_time" })
408
- * ```
409
- */
410
- export declare function minHoursPerWeek(hours: number, opts?: EntityOnlyRuleOptions): RuleEntry;
411
- /**
412
- * Limits how many shifts a person can work in a single day.
413
- *
414
- * @example One shift per day
415
- * ```ts
416
- * maxShiftsPerDay(1)
417
- * ```
418
- */
419
- export declare function maxShiftsPerDay(shifts: number, opts?: RuleOptions): RuleEntry;
420
- /**
421
- * Limits how many consecutive days a person can be assigned.
422
- *
423
- * @example Five-day work week limit
424
- * ```ts
425
- * maxConsecutiveDays(5)
426
- * ```
427
- */
428
- export declare function maxConsecutiveDays(days: number, opts?: EntityOnlyRuleOptions): RuleEntry;
429
- /**
430
- * Requires a minimum stretch of consecutive working days once assigned.
431
- *
432
- * @example
433
- * ```ts
434
- * minConsecutiveDays(2)
435
- * ```
436
- */
437
- export declare function minConsecutiveDays(days: number, opts?: EntityOnlyRuleOptions): RuleEntry;
438
- /**
439
- * Enforces a minimum rest period between any two shifts a person works.
440
- *
441
- * @example EU Working Time Directive (11 hours)
442
- * ```ts
443
- * minRestBetweenShifts(11)
444
- * ```
445
- */
446
- export declare function minRestBetweenShifts(hours: number, opts?: EntityOnlyRuleOptions): RuleEntry;
447
- /**
448
- * Adds objective weight to prefer or avoid assigning team members.
449
- *
450
- * @param level - `"high"` to prefer assigning, `"low"` to avoid
451
- * @param opts - Entity and time scoping (no priority; preference is the priority mechanism)
452
- *
453
- * @example Prefer assigning full-time staff
454
- * ```ts
455
- * preference("high", { appliesTo: "full_time" })
456
- * ```
457
- *
458
- * @example Avoid assigning a specific member on weekends
459
- * ```ts
460
- * preference("low", { appliesTo: "alice", dayOfWeek: weekend })
461
- * ```
462
- */
463
- export declare function preference(level: "high" | "low", opts?: Omit<RuleOptions, "priority">): RuleEntry;
464
- /**
465
- * Prefers assigning a person to shift patterns at a specific location.
466
- *
467
- * @example
468
- * ```ts
469
- * preferLocation("north_wing", { appliesTo: "alice" })
470
- * ```
471
- */
472
- export declare function preferLocation(locationId: string, opts?: EntityOnlyRuleOptions): RuleEntry;
473
- /**
474
- * Tells the solver to minimize total labor cost.
475
- *
476
- * @remarks
477
- * Without this rule, cost modifiers only affect post-solve calculation.
478
- * When present, the solver actively prefers cheaper assignments.
479
- *
480
- * For hourly members, penalizes each assignment proportionally to cost.
481
- * For salaried members, adds a fixed weekly salary cost when they have
482
- * any assignment that week (zero marginal cost up to contracted hours).
483
- *
484
- * @example
485
- * ```ts
486
- * minimizeCost()
487
- * ```
488
- */
489
- export declare function minimizeCost(opts?: CostRuleOptions): RuleEntry;
490
- /**
491
- * Multiplies the base rate for assignments on specified days.
492
- *
493
- * @remarks
494
- * The base cost (1x) is already counted by {@link minimizeCost};
495
- * this rule adds only the extra portion above 1x.
496
- *
497
- * @example Weekend multiplier
498
- * ```typescript
499
- * dayMultiplier(1.5, { dayOfWeek: weekend })
500
- * ```
501
- */
502
- export declare function dayMultiplier(factor: number, opts?: CostRuleOptions): RuleEntry;
503
- /**
504
- * Adds a flat extra amount per hour for assignments on specified days.
505
- *
506
- * @remarks
507
- * The surcharge is independent of the member's base rate.
508
- *
509
- * @example Weekend surcharge
510
- * ```typescript
511
- * daySurcharge(500, { dayOfWeek: weekend })
512
- * ```
513
- */
514
- export declare function daySurcharge(amountPerHour: number, opts?: CostRuleOptions): RuleEntry;
515
- /**
516
- * Adds a flat surcharge per hour for the portion of a shift that overlaps a time-of-day window.
517
- *
518
- * @remarks
519
- * The window supports overnight spans (e.g., 22:00-06:00). The surcharge
520
- * is independent of the member's base rate.
521
- *
522
- * @param amountPerHour - Flat surcharge per hour in smallest currency unit
523
- * @param window - Time-of-day window
524
- * @param opts - Entity and time scoping
525
- *
526
- * @example Night differential
527
- * ```typescript
528
- * timeSurcharge(200, { from: t(22), until: t(6) })
529
- * ```
530
- */
531
- export declare function timeSurcharge(amountPerHour: number, window: {
532
- from: TimeOfDay;
533
- until: TimeOfDay;
534
- }, opts?: CostRuleOptions): RuleEntry;
535
- /**
536
- * Applies a multiplier to hours beyond a weekly threshold.
537
- *
538
- * @remarks
539
- * Only the extra portion above 1x is added (the base cost is already
540
- * counted by {@link minimizeCost}).
541
- *
542
- * @example
543
- * ```typescript
544
- * overtimeMultiplier({ after: 40, factor: 1.5 })
545
- * ```
546
- */
547
- export declare function overtimeMultiplier(opts: {
548
- after: number;
549
- factor: number;
550
- } & CostRuleOptions): RuleEntry;
551
- /**
552
- * Adds a flat surcharge per hour beyond a weekly threshold.
553
- *
554
- * @remarks
555
- * The surcharge is independent of the member's base rate.
556
- *
557
- * @example
558
- * ```typescript
559
- * overtimeSurcharge({ after: 40, amount: 1000 })
560
- * ```
561
- */
562
- export declare function overtimeSurcharge(opts: {
563
- after: number;
564
- amount: number;
565
- } & CostRuleOptions): RuleEntry;
566
- /**
567
- * Applies a multiplier to hours beyond a daily threshold.
568
- *
569
- * @remarks
570
- * Only the extra portion above 1x is added (the base cost is already
571
- * counted by {@link minimizeCost}).
572
- *
573
- * @example
574
- * ```typescript
575
- * dailyOvertimeMultiplier({ after: 8, factor: 1.5 })
576
- * ```
577
- */
578
- export declare function dailyOvertimeMultiplier(opts: {
579
- after: number;
580
- factor: number;
581
- } & CostRuleOptions): RuleEntry;
582
- /**
583
- * Adds a flat surcharge per hour beyond a daily threshold.
584
- *
585
- * @remarks
586
- * The surcharge is independent of the member's base rate.
587
- *
588
- * @example
589
- * ```typescript
590
- * dailyOvertimeSurcharge({ after: 8, amount: 500 })
591
- * ```
592
- */
593
- export declare function dailyOvertimeSurcharge(opts: {
594
- after: number;
595
- amount: number;
596
- } & CostRuleOptions): RuleEntry;
597
- /**
598
- * Applies multiple overtime thresholds with increasing multipliers.
599
- *
600
- * @remarks
601
- * Each tier applies only to the hours between its threshold and the next.
602
- * Tiers must be sorted by threshold ascending.
603
- *
604
- * @example
605
- * ```typescript
606
- * // Hours 0-40: base rate
607
- * // Hours 40-48: 1.5x
608
- * // Hours 48+: 2.0x
609
- * tieredOvertimeMultiplier([
610
- * { after: 40, factor: 1.5 },
611
- * { after: 48, factor: 2.0 },
612
- * ])
613
- * ```
614
- */
615
- export declare function tieredOvertimeMultiplier(tiers: [OvertimeTier, ...OvertimeTier[]], opts?: CostRuleOptions): RuleEntry;
616
- /**
617
- * Blocks or penalizes assignments during specified time periods.
618
- *
619
- * @remarks
620
- * At least one time scoping field is required (`dayOfWeek`, `dateRange`,
621
- * `dates`, or `recurringPeriods`).
622
- *
623
- * Use `from` for "off from this time until end of day" and `until` for
624
- * "off from start of day until this time."
625
- *
626
- * @example
627
- * ```typescript
628
- * timeOff({ appliesTo: "mauro", dayOfWeek: weekend }),
629
- * timeOff({ appliesTo: "student", dayOfWeek: ["wednesday"], from: t(14) }),
630
- * timeOff({ appliesTo: "alice", dateRange: { start: "2024-02-01", end: "2024-02-05" } }),
631
- * ```
632
- */
633
- export declare function timeOff(opts: TimeOffOptions): RuleEntry;
634
- /**
635
- * Encourages or enforces that team members work the same shifts on a day.
636
- *
637
- * @example
638
- * ```typescript
639
- * assignTogether(["alice", "bob"], { priority: "HIGH" }),
640
- * ```
641
- */
642
- export declare function assignTogether(members: [string, string, ...string[]], opts?: AssignTogetherOptions): RuleEntry;
643
- /**
644
- * Runtime arguments passed to {@link ScheduleDefinition.createSchedulerConfig}.
645
- *
646
- * @remarks
647
- * Separates data known at runtime (team roster, date range, ad-hoc rules)
648
- * from the static schedule definition. Runtime rules are merged after the
649
- * definition's own rules and undergo the same `appliesTo` resolution.
650
- */
651
- export interface RuntimeArgs {
652
- /** The scheduling period (date range + optional filters). */
653
- schedulingPeriod: SchedulingPeriod;
654
- /** Team members available for this scheduling run. */
655
- members: SchedulingMember[];
656
- /** Ad-hoc rules injected at runtime (e.g., vacation, holiday closures). */
657
- runtimeRules?: RuleEntry[];
658
- }
659
- /** Result of {@link defineSchedule}. */
660
- export interface ScheduleDefinition {
661
- /** Produce a {@link ModelBuilderConfig} for the solver. */
662
- createSchedulerConfig(args: RuntimeArgs): ModelBuilderConfig;
663
- /** Declared role names. */
664
- readonly roles: readonly string[];
665
- /** Declared skill names. */
666
- readonly skills: readonly string[];
667
- /** Names of declared semantic times. */
668
- readonly timeNames: readonly string[];
669
- /** Shift pattern IDs. */
670
- readonly shiftPatternIds: readonly string[];
671
- /** Internal rule identifiers in kebab-case (e.g., "max-hours-day", "time-off"). */
672
- readonly ruleNames: readonly string[];
673
- }
674
- /**
675
- * Configuration for {@link defineSchedule}.
676
- *
677
- * @remarks
678
- * Coverage entries for the same semantic time and target stack additively.
679
- * An unscoped entry applies every day; adding a weekend-only entry on top
680
- * doubles the count on those days. Use mutually exclusive `dayOfWeek` on
681
- * both entries to avoid stacking. See {@link cover} for details.
682
- */
683
- export interface ScheduleConfig<R extends readonly string[], S extends readonly string[], T extends Record<string, SemanticTimeEntry>> {
684
- /** Declared role names. */
685
- roles: R;
686
- /** Declared skill names. */
687
- skills?: S;
688
- /** Named semantic time periods. */
689
- times: T;
690
- /** Staffing requirements per time period (entries stack additively). */
691
- coverage: CoverageEntry<keyof T & string, R[number] | NonNullable<S>[number]>[];
692
- /** Available shift patterns. */
693
- shiftPatterns: ShiftPattern[];
694
- /** Scheduling rules and constraints. */
695
- rules?: RuleEntry[];
696
- /** Days of the week the business operates (inclusion filter). */
697
- dayOfWeek?: readonly DayOfWeek[];
698
- /** Which day starts the week for weekly rules. Defaults to `"monday"`. */
699
- weekStartsOn?: DayOfWeek;
700
- }
701
- /**
702
- * Defines a complete schedule configuration.
703
- *
704
- * @remarks
705
- * Validates the static config at call time (role/skill disjointness, coverage
706
- * targets, shift pattern roles). Returns a {@link ScheduleDefinition} whose
707
- * `createSchedulerConfig` method validates runtime data (member IDs,
708
- * `appliesTo` resolution) and produces a {@link ModelBuilderConfig}.
709
- *
710
- * @example
711
- * ```typescript
712
- * import { defineSchedule, t, time, cover, shift, maxHoursPerDay } from "dabke";
713
- *
714
- * export default defineSchedule({
715
- * roles: ["agent", "supervisor"],
716
- * times: { peak: time({ startTime: t(9), endTime: t(17) }) },
717
- * coverage: [cover("peak", "agent", 4)],
718
- * shiftPatterns: [shift("day", t(9), t(17))],
719
- * rules: [maxHoursPerDay(8)],
720
- * });
721
- * ```
722
- */
723
- export declare function defineSchedule<const R extends readonly string[], const S extends readonly string[], const T extends Record<string, SemanticTimeEntry>>(config: ScheduleConfig<R, S, T>): ScheduleDefinition;
724
- //# sourceMappingURL=schedule.d.ts.map