dabke 0.83.0 → 0.84.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 (330) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +22 -27
  3. package/dist/client.d.ts +39 -3
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js.map +1 -1
  6. package/dist/client.schemas.d.ts +118 -18
  7. package/dist/client.schemas.d.ts.map +1 -1
  8. package/dist/client.schemas.js +110 -6
  9. package/dist/client.schemas.js.map +1 -1
  10. package/dist/client.types.d.ts +63 -7
  11. package/dist/client.types.d.ts.map +1 -1
  12. package/dist/client.types.js.map +1 -1
  13. package/dist/cpsat/cost.d.ts +5 -2
  14. package/dist/cpsat/cost.d.ts.map +1 -1
  15. package/dist/cpsat/cost.js +13 -6
  16. package/dist/cpsat/cost.js.map +1 -1
  17. package/dist/cpsat/model-builder.d.ts +42 -61
  18. package/dist/cpsat/model-builder.d.ts.map +1 -1
  19. package/dist/cpsat/model-builder.js +451 -56
  20. package/dist/cpsat/model-builder.js.map +1 -1
  21. package/dist/cpsat/response.d.ts +19 -7
  22. package/dist/cpsat/response.d.ts.map +1 -1
  23. package/dist/cpsat/response.js +48 -9
  24. package/dist/cpsat/response.js.map +1 -1
  25. package/dist/cpsat/rule-descriptor.d.ts +250 -0
  26. package/dist/cpsat/rule-descriptor.d.ts.map +1 -0
  27. package/dist/cpsat/rule-descriptor.js +51 -0
  28. package/dist/cpsat/rule-descriptor.js.map +1 -0
  29. package/dist/cpsat/rules/artifacts.d.ts +9 -0
  30. package/dist/cpsat/rules/artifacts.d.ts.map +1 -0
  31. package/dist/cpsat/rules/artifacts.js +31 -0
  32. package/dist/cpsat/rules/artifacts.js.map +1 -0
  33. package/dist/cpsat/rules/assign-together.d.ts +18 -20
  34. package/dist/cpsat/rules/assign-together.d.ts.map +1 -1
  35. package/dist/cpsat/rules/assign-together.js +90 -54
  36. package/dist/cpsat/rules/assign-together.js.map +1 -1
  37. package/dist/cpsat/rules/assigned-day.d.ts +12 -0
  38. package/dist/cpsat/rules/assigned-day.d.ts.map +1 -0
  39. package/dist/cpsat/rules/assigned-day.js +43 -0
  40. package/dist/cpsat/rules/assigned-day.js.map +1 -0
  41. package/dist/cpsat/rules/assignment-priority.d.ts +15 -29
  42. package/dist/cpsat/rules/assignment-priority.d.ts.map +1 -1
  43. package/dist/cpsat/rules/assignment-priority.js +47 -50
  44. package/dist/cpsat/rules/assignment-priority.js.map +1 -1
  45. package/dist/cpsat/rules/assignment-terms.d.ts +6 -0
  46. package/dist/cpsat/rules/assignment-terms.d.ts.map +1 -0
  47. package/dist/cpsat/rules/assignment-terms.js +19 -0
  48. package/dist/cpsat/rules/assignment-terms.js.map +1 -0
  49. package/dist/cpsat/rules/concurrent-intervals.d.ts +19 -0
  50. package/dist/cpsat/rules/concurrent-intervals.d.ts.map +1 -0
  51. package/dist/cpsat/rules/concurrent-intervals.js +57 -0
  52. package/dist/cpsat/rules/concurrent-intervals.js.map +1 -0
  53. package/dist/cpsat/rules/cost-utils.d.ts +1 -3
  54. package/dist/cpsat/rules/cost-utils.d.ts.map +1 -1
  55. package/dist/cpsat/rules/cost-utils.js +0 -7
  56. package/dist/cpsat/rules/cost-utils.js.map +1 -1
  57. package/dist/cpsat/rules/day-cost-multiplier.d.ts +10 -10
  58. package/dist/cpsat/rules/day-cost-multiplier.d.ts.map +1 -1
  59. package/dist/cpsat/rules/day-cost-multiplier.js +88 -77
  60. package/dist/cpsat/rules/day-cost-multiplier.js.map +1 -1
  61. package/dist/cpsat/rules/day-cost-surcharge.d.ts +10 -10
  62. package/dist/cpsat/rules/day-cost-surcharge.d.ts.map +1 -1
  63. package/dist/cpsat/rules/day-cost-surcharge.js +76 -65
  64. package/dist/cpsat/rules/day-cost-surcharge.js.map +1 -1
  65. package/dist/cpsat/rules/index.d.ts +30 -24
  66. package/dist/cpsat/rules/index.d.ts.map +1 -1
  67. package/dist/cpsat/rules/index.js +30 -24
  68. package/dist/cpsat/rules/index.js.map +1 -1
  69. package/dist/cpsat/rules/location-preference.d.ts +14 -21
  70. package/dist/cpsat/rules/location-preference.d.ts.map +1 -1
  71. package/dist/cpsat/rules/location-preference.js +45 -45
  72. package/dist/cpsat/rules/location-preference.js.map +1 -1
  73. package/dist/cpsat/rules/max-concurrent-assignments.d.ts +46 -0
  74. package/dist/cpsat/rules/max-concurrent-assignments.d.ts.map +1 -0
  75. package/dist/cpsat/rules/max-concurrent-assignments.js +121 -0
  76. package/dist/cpsat/rules/max-concurrent-assignments.js.map +1 -0
  77. package/dist/cpsat/rules/max-consecutive-days.d.ts +18 -17
  78. package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -1
  79. package/dist/cpsat/rules/max-consecutive-days.js +67 -66
  80. package/dist/cpsat/rules/max-consecutive-days.js.map +1 -1
  81. package/dist/cpsat/rules/max-days-of-week-per-period.d.ts +45 -0
  82. package/dist/cpsat/rules/max-days-of-week-per-period.d.ts.map +1 -0
  83. package/dist/cpsat/rules/max-days-of-week-per-period.js +95 -0
  84. package/dist/cpsat/rules/max-days-of-week-per-period.js.map +1 -0
  85. package/dist/cpsat/rules/max-days-week.d.ts +17 -31
  86. package/dist/cpsat/rules/max-days-week.d.ts.map +1 -1
  87. package/dist/cpsat/rules/max-days-week.js +69 -81
  88. package/dist/cpsat/rules/max-days-week.js.map +1 -1
  89. package/dist/cpsat/rules/max-hours-day.d.ts +14 -31
  90. package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -1
  91. package/dist/cpsat/rules/max-hours-day.js +56 -72
  92. package/dist/cpsat/rules/max-hours-day.js.map +1 -1
  93. package/dist/cpsat/rules/max-hours-week.d.ts +15 -31
  94. package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -1
  95. package/dist/cpsat/rules/max-hours-week.js +60 -75
  96. package/dist/cpsat/rules/max-hours-week.js.map +1 -1
  97. package/dist/cpsat/rules/max-shifts-day.d.ts +17 -33
  98. package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -1
  99. package/dist/cpsat/rules/max-shifts-day.js +57 -73
  100. package/dist/cpsat/rules/max-shifts-day.js.map +1 -1
  101. package/dist/cpsat/rules/min-consecutive-days.d.ts +18 -18
  102. package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -1
  103. package/dist/cpsat/rules/min-consecutive-days.js +123 -94
  104. package/dist/cpsat/rules/min-consecutive-days.js.map +1 -1
  105. package/dist/cpsat/rules/min-days-of-week-per-period.d.ts +35 -0
  106. package/dist/cpsat/rules/min-days-of-week-per-period.d.ts.map +1 -0
  107. package/dist/cpsat/rules/min-days-of-week-per-period.js +108 -0
  108. package/dist/cpsat/rules/min-days-of-week-per-period.js.map +1 -0
  109. package/dist/cpsat/rules/min-days-week.d.ts +13 -26
  110. package/dist/cpsat/rules/min-days-week.d.ts.map +1 -1
  111. package/dist/cpsat/rules/min-days-week.js +85 -74
  112. package/dist/cpsat/rules/min-days-week.js.map +1 -1
  113. package/dist/cpsat/rules/min-hours-day.d.ts +14 -17
  114. package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -1
  115. package/dist/cpsat/rules/min-hours-day.js +72 -54
  116. package/dist/cpsat/rules/min-hours-day.js.map +1 -1
  117. package/dist/cpsat/rules/min-hours-week.d.ts +15 -18
  118. package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -1
  119. package/dist/cpsat/rules/min-hours-week.js +75 -57
  120. package/dist/cpsat/rules/min-hours-week.js.map +1 -1
  121. package/dist/cpsat/rules/min-rest-between-shifts.d.ts +14 -17
  122. package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -1
  123. package/dist/cpsat/rules/min-rest-between-shifts.js +148 -138
  124. package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -1
  125. package/dist/cpsat/rules/minimize-cost.d.ts +2 -18
  126. package/dist/cpsat/rules/minimize-cost.d.ts.map +1 -1
  127. package/dist/cpsat/rules/minimize-cost.js +151 -163
  128. package/dist/cpsat/rules/minimize-cost.js.map +1 -1
  129. package/dist/cpsat/rules/must-assign.d.ts +5 -42
  130. package/dist/cpsat/rules/must-assign.d.ts.map +1 -1
  131. package/dist/cpsat/rules/must-assign.js +43 -75
  132. package/dist/cpsat/rules/must-assign.js.map +1 -1
  133. package/dist/cpsat/rules/overtime-daily-multiplier.d.ts +6 -10
  134. package/dist/cpsat/rules/overtime-daily-multiplier.d.ts.map +1 -1
  135. package/dist/cpsat/rules/overtime-daily-multiplier.js +118 -112
  136. package/dist/cpsat/rules/overtime-daily-multiplier.js.map +1 -1
  137. package/dist/cpsat/rules/overtime-daily-surcharge.d.ts +6 -11
  138. package/dist/cpsat/rules/overtime-daily-surcharge.d.ts.map +1 -1
  139. package/dist/cpsat/rules/overtime-daily-surcharge.js +104 -99
  140. package/dist/cpsat/rules/overtime-daily-surcharge.js.map +1 -1
  141. package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts +9 -21
  142. package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts.map +1 -1
  143. package/dist/cpsat/rules/overtime-tiered-multiplier.js +181 -199
  144. package/dist/cpsat/rules/overtime-tiered-multiplier.js.map +1 -1
  145. package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts +13 -12
  146. package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts.map +1 -1
  147. package/dist/cpsat/rules/overtime-weekly-multiplier.js +143 -143
  148. package/dist/cpsat/rules/overtime-weekly-multiplier.js.map +1 -1
  149. package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts +7 -11
  150. package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts.map +1 -1
  151. package/dist/cpsat/rules/overtime-weekly-surcharge.js +124 -119
  152. package/dist/cpsat/rules/overtime-weekly-surcharge.js.map +1 -1
  153. package/dist/cpsat/rules/pattern-eligibility.d.ts +6 -0
  154. package/dist/cpsat/rules/pattern-eligibility.d.ts.map +1 -0
  155. package/dist/cpsat/rules/pattern-eligibility.js +16 -0
  156. package/dist/cpsat/rules/pattern-eligibility.js.map +1 -0
  157. package/dist/cpsat/rules/pattern-time.d.ts +5 -0
  158. package/dist/cpsat/rules/pattern-time.d.ts.map +1 -0
  159. package/dist/cpsat/rules/pattern-time.js +20 -0
  160. package/dist/cpsat/rules/pattern-time.js.map +1 -0
  161. package/dist/cpsat/rules/registry.d.ts +217 -30
  162. package/dist/cpsat/rules/registry.d.ts.map +1 -1
  163. package/dist/cpsat/rules/registry.js +98 -34
  164. package/dist/cpsat/rules/registry.js.map +1 -1
  165. package/dist/cpsat/rules/resolver.d.ts +9 -7
  166. package/dist/cpsat/rules/resolver.d.ts.map +1 -1
  167. package/dist/cpsat/rules/resolver.js +19 -18
  168. package/dist/cpsat/rules/resolver.js.map +1 -1
  169. package/dist/cpsat/rules/role-preference.d.ts +24 -0
  170. package/dist/cpsat/rules/role-preference.d.ts.map +1 -0
  171. package/dist/cpsat/rules/role-preference.js +72 -0
  172. package/dist/cpsat/rules/role-preference.js.map +1 -0
  173. package/dist/cpsat/rules/rules.types.d.ts +90 -17
  174. package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
  175. package/dist/cpsat/rules/scope.types.d.ts +24 -11
  176. package/dist/cpsat/rules/scope.types.d.ts.map +1 -1
  177. package/dist/cpsat/rules/scope.types.js +14 -19
  178. package/dist/cpsat/rules/scope.types.js.map +1 -1
  179. package/dist/cpsat/rules/target-days-week.d.ts +31 -0
  180. package/dist/cpsat/rules/target-days-week.d.ts.map +1 -0
  181. package/dist/cpsat/rules/target-days-week.js +80 -0
  182. package/dist/cpsat/rules/target-days-week.js.map +1 -0
  183. package/dist/cpsat/rules/target-peak-concurrent-assignments.d.ts +33 -0
  184. package/dist/cpsat/rules/target-peak-concurrent-assignments.d.ts.map +1 -0
  185. package/dist/cpsat/rules/target-peak-concurrent-assignments.js +146 -0
  186. package/dist/cpsat/rules/target-peak-concurrent-assignments.js.map +1 -0
  187. package/dist/cpsat/rules/time-cost-surcharge.d.ts +15 -14
  188. package/dist/cpsat/rules/time-cost-surcharge.d.ts.map +1 -1
  189. package/dist/cpsat/rules/time-cost-surcharge.js +82 -96
  190. package/dist/cpsat/rules/time-cost-surcharge.js.map +1 -1
  191. package/dist/cpsat/rules/time-off.d.ts +21 -57
  192. package/dist/cpsat/rules/time-off.d.ts.map +1 -1
  193. package/dist/cpsat/rules/time-off.js +114 -127
  194. package/dist/cpsat/rules/time-off.js.map +1 -1
  195. package/dist/cpsat/rules/variables.d.ts +4 -0
  196. package/dist/cpsat/rules/variables.d.ts.map +1 -0
  197. package/dist/cpsat/rules/variables.js +10 -0
  198. package/dist/cpsat/rules/variables.js.map +1 -0
  199. package/dist/cpsat/rules.d.ts +20 -3
  200. package/dist/cpsat/rules.d.ts.map +1 -1
  201. package/dist/cpsat/rules.js +19 -2
  202. package/dist/cpsat/rules.js.map +1 -1
  203. package/dist/cpsat/semantic-time.d.ts +7 -6
  204. package/dist/cpsat/semantic-time.d.ts.map +1 -1
  205. package/dist/cpsat/semantic-time.js +15 -28
  206. package/dist/cpsat/semantic-time.js.map +1 -1
  207. package/dist/cpsat/types.d.ts +47 -4
  208. package/dist/cpsat/types.d.ts.map +1 -1
  209. package/dist/cpsat/types.js +24 -1
  210. package/dist/cpsat/types.js.map +1 -1
  211. package/dist/cpsat/utils.d.ts +23 -6
  212. package/dist/cpsat/utils.d.ts.map +1 -1
  213. package/dist/cpsat/utils.js +76 -15
  214. package/dist/cpsat/utils.js.map +1 -1
  215. package/dist/cpsat/validation-reporter.d.ts +6 -2
  216. package/dist/cpsat/validation-reporter.d.ts.map +1 -1
  217. package/dist/cpsat/validation-reporter.js +122 -10
  218. package/dist/cpsat/validation-reporter.js.map +1 -1
  219. package/dist/cpsat/validation.types.d.ts +21 -10
  220. package/dist/cpsat/validation.types.d.ts.map +1 -1
  221. package/dist/datetime.utils.d.ts +7 -13
  222. package/dist/datetime.utils.d.ts.map +1 -1
  223. package/dist/datetime.utils.js +29 -36
  224. package/dist/datetime.utils.js.map +1 -1
  225. package/dist/index.d.ts +12 -8
  226. package/dist/index.d.ts.map +1 -1
  227. package/dist/index.js +8 -3
  228. package/dist/index.js.map +1 -1
  229. package/dist/schedule/cost.d.ts +48 -60
  230. package/dist/schedule/cost.d.ts.map +1 -1
  231. package/dist/schedule/cost.js +15 -51
  232. package/dist/schedule/cost.js.map +1 -1
  233. package/dist/schedule/coverage.d.ts +57 -28
  234. package/dist/schedule/coverage.d.ts.map +1 -1
  235. package/dist/schedule/coverage.js +24 -1
  236. package/dist/schedule/coverage.js.map +1 -1
  237. package/dist/schedule/definition.d.ts +138 -19
  238. package/dist/schedule/definition.d.ts.map +1 -1
  239. package/dist/schedule/definition.js +99 -90
  240. package/dist/schedule/definition.js.map +1 -1
  241. package/dist/schedule/index.d.ts +4 -4
  242. package/dist/schedule/index.d.ts.map +1 -1
  243. package/dist/schedule/index.js +2 -2
  244. package/dist/schedule/index.js.map +1 -1
  245. package/dist/schedule/rules.d.ts +438 -113
  246. package/dist/schedule/rules.d.ts.map +1 -1
  247. package/dist/schedule/rules.js +310 -108
  248. package/dist/schedule/rules.js.map +1 -1
  249. package/dist/schedule/shift-patterns.d.ts +0 -17
  250. package/dist/schedule/shift-patterns.d.ts.map +1 -1
  251. package/dist/schedule/shift-patterns.js +0 -17
  252. package/dist/schedule/shift-patterns.js.map +1 -1
  253. package/dist/schedule/time-periods.d.ts +37 -27
  254. package/dist/schedule/time-periods.d.ts.map +1 -1
  255. package/dist/schedule/time-periods.js +37 -27
  256. package/dist/schedule/time-periods.js.map +1 -1
  257. package/dist/types.d.ts +67 -3
  258. package/dist/types.d.ts.map +1 -1
  259. package/dist/types.js +64 -0
  260. package/dist/types.js.map +1 -1
  261. package/package.json +8 -9
  262. package/solver/src/solver/models.py +41 -4
  263. package/solver/src/solver/solver.py +546 -157
  264. package/solver/tests/test_solver.py +363 -7
  265. package/src/client.schemas.ts +127 -10
  266. package/src/client.ts +3 -0
  267. package/src/client.types.ts +73 -7
  268. package/src/cpsat/cost.ts +17 -7
  269. package/src/cpsat/model-builder.ts +614 -129
  270. package/src/cpsat/response.ts +57 -13
  271. package/src/cpsat/rule-descriptor.ts +311 -0
  272. package/src/cpsat/rules/artifacts.ts +56 -0
  273. package/src/cpsat/rules/assign-together.ts +104 -69
  274. package/src/cpsat/rules/assigned-day.ts +70 -0
  275. package/src/cpsat/rules/assignment-priority.ts +54 -58
  276. package/src/cpsat/rules/assignment-terms.ts +43 -0
  277. package/src/cpsat/rules/concurrent-intervals.ts +93 -0
  278. package/src/cpsat/rules/cost-utils.ts +1 -9
  279. package/src/cpsat/rules/day-cost-multiplier.ts +101 -81
  280. package/src/cpsat/rules/day-cost-surcharge.ts +91 -70
  281. package/src/cpsat/rules/index.ts +30 -24
  282. package/src/cpsat/rules/location-preference.ts +47 -52
  283. package/src/cpsat/rules/max-concurrent-assignments.ts +170 -0
  284. package/src/cpsat/rules/max-consecutive-days.ts +74 -91
  285. package/src/cpsat/rules/max-days-of-week-per-period.ts +127 -0
  286. package/src/cpsat/rules/max-days-week.ts +89 -115
  287. package/src/cpsat/rules/max-hours-day.ts +64 -84
  288. package/src/cpsat/rules/max-hours-week.ts +74 -90
  289. package/src/cpsat/rules/max-shifts-day.ts +65 -85
  290. package/src/cpsat/rules/min-consecutive-days.ts +161 -127
  291. package/src/cpsat/rules/min-days-of-week-per-period.ts +144 -0
  292. package/src/cpsat/rules/min-days-week.ts +93 -91
  293. package/src/cpsat/rules/min-hours-day.ts +79 -58
  294. package/src/cpsat/rules/min-hours-week.ts +87 -62
  295. package/src/cpsat/rules/min-rest-between-shifts.ts +191 -178
  296. package/src/cpsat/rules/minimize-cost.ts +175 -188
  297. package/src/cpsat/rules/must-assign.ts +44 -81
  298. package/src/cpsat/rules/overtime-daily-multiplier.ts +158 -140
  299. package/src/cpsat/rules/overtime-daily-surcharge.ts +141 -126
  300. package/src/cpsat/rules/overtime-tiered-multiplier.ts +234 -253
  301. package/src/cpsat/rules/overtime-weekly-multiplier.ts +183 -175
  302. package/src/cpsat/rules/overtime-weekly-surcharge.ts +161 -150
  303. package/src/cpsat/rules/pattern-eligibility.ts +26 -0
  304. package/src/cpsat/rules/pattern-time.ts +30 -0
  305. package/src/cpsat/rules/registry.ts +140 -62
  306. package/src/cpsat/rules/resolver.ts +58 -30
  307. package/src/cpsat/rules/role-preference.ts +92 -0
  308. package/src/cpsat/rules/rules.types.ts +89 -17
  309. package/src/cpsat/rules/scope.types.ts +31 -26
  310. package/src/cpsat/rules/target-days-week.ts +105 -0
  311. package/src/cpsat/rules/target-peak-concurrent-assignments.ts +212 -0
  312. package/src/cpsat/rules/time-cost-surcharge.ts +116 -122
  313. package/src/cpsat/rules/time-off.ts +154 -163
  314. package/src/cpsat/rules/variables.ts +11 -0
  315. package/src/cpsat/rules.ts +43 -17
  316. package/src/cpsat/semantic-time.ts +29 -43
  317. package/src/cpsat/types.ts +53 -4
  318. package/src/cpsat/utils.ts +92 -20
  319. package/src/cpsat/validation-reporter.ts +170 -19
  320. package/src/cpsat/validation.types.ts +22 -11
  321. package/src/datetime.utils.ts +45 -44
  322. package/src/index.ts +64 -12
  323. package/src/schedule/cost.ts +40 -61
  324. package/src/schedule/coverage.ts +57 -28
  325. package/src/schedule/definition.ts +565 -76
  326. package/src/schedule/index.ts +23 -3
  327. package/src/schedule/rules.ts +631 -132
  328. package/src/schedule/shift-patterns.ts +0 -17
  329. package/src/schedule/time-periods.ts +37 -27
  330. package/src/types.ts +114 -2
@@ -1,50 +1,46 @@
1
- import type { DayOfWeek, SchedulingPeriod } from "./types.js";
2
-
3
- export const DAY_OF_WEEK_MAP: Record<DayOfWeek, number> = {
4
- sunday: 0, // JavaScript Date week starts on Sunday
5
- monday: 1,
6
- tuesday: 2,
7
- wednesday: 3,
8
- thursday: 4,
9
- friday: 5,
10
- saturday: 6,
11
- };
12
-
13
- const DAY_NAMES = [
14
- "sunday",
15
- "monday",
16
- "tuesday",
17
- "wednesday",
18
- "thursday",
19
- "friday",
20
- "saturday",
21
- ] as const;
1
+ import {
2
+ DAY_NAMES,
3
+ type DateString,
4
+ type DayOfWeek,
5
+ type SchedulingDay,
6
+ type SchedulingPeriod,
7
+ } from "./types.js";
22
8
 
23
9
  /**
24
- * Helper to get the day of week name from a Date (UTC).
25
- * Use this when working with date strings like "2026-01-10" that are timezone-agnostic.
10
+ * Builds a {@link SchedulingDay} from an existing UTC `Date`, avoiding a
11
+ * redundant `new Date()` call. Used internally by {@link resolveDaysFromPeriod}
12
+ * where the loop already maintains a `Date` cursor.
26
13
  */
27
- export function toDayOfWeekUTC(date: Date): DayOfWeek {
28
- // getUTCDay() always returns 0-6
29
- return DAY_NAMES[date.getUTCDay()] as DayOfWeek;
14
+ function schedulingDayFromDate(date: Date, iso: DateString): SchedulingDay {
15
+ const dayOfWeek = DAY_NAMES[date.getUTCDay()]!;
16
+ const month = date.getUTCMonth() + 1;
17
+ const dayOfMonth = date.getUTCDate();
18
+ return {
19
+ iso,
20
+ dayOfWeek,
21
+ month,
22
+ dayOfMonth,
23
+ yearMonth: iso.slice(0, 7),
24
+ epochDay: Math.floor(date.getTime() / 86_400_000),
25
+ };
30
26
  }
31
27
 
32
28
  /**
33
- * Computes the list of day strings (YYYY-MM-DD) from a SchedulingPeriod.
29
+ * Computes the list of {@link SchedulingDay} values from a {@link SchedulingPeriod}.
34
30
  *
35
31
  * Generates all days between start and end (inclusive), applying optional
36
32
  * dayOfWeek and dates filters. Filters compose: a day must pass all
37
33
  * specified filters to be included.
38
34
  *
39
35
  * @param period - The scheduling period specification
40
- * @returns Array of day strings in YYYY-MM-DD format, sorted chronologically
36
+ * @returns Array of scheduling days, sorted chronologically
41
37
  *
42
38
  * @example All days in range
43
39
  * ```typescript
44
40
  * const days = resolveDaysFromPeriod({
45
41
  * dateRange: { start: '2025-02-03', end: '2025-02-05' },
46
42
  * });
47
- * // Returns: ['2025-02-03', '2025-02-04', '2025-02-05']
43
+ * // Returns days for 2025-02-03, 2025-02-04, 2025-02-05
48
44
  * ```
49
45
  *
50
46
  * @example Day-of-week filter
@@ -53,7 +49,7 @@ export function toDayOfWeekUTC(date: Date): DayOfWeek {
53
49
  * dateRange: { start: '2025-02-03', end: '2025-02-09' },
54
50
  * dayOfWeek: ['wednesday', 'friday'],
55
51
  * });
56
- * // Returns: ['2025-02-05', '2025-02-07']
52
+ * // Returns days for 2025-02-05, 2025-02-07
57
53
  * ```
58
54
  *
59
55
  * @example Specific dates filter
@@ -62,31 +58,36 @@ export function toDayOfWeekUTC(date: Date): DayOfWeek {
62
58
  * dateRange: { start: '2025-02-03', end: '2025-02-10' },
63
59
  * dates: ['2025-02-05', '2025-02-07'],
64
60
  * });
65
- * // Returns: ['2025-02-05', '2025-02-07']
61
+ * // Returns days for 2025-02-05, 2025-02-07
66
62
  * ```
67
63
  */
68
- export function resolveDaysFromPeriod(period: SchedulingPeriod): string[] {
64
+ export function resolveDaysFromPeriod(period: SchedulingPeriod): SchedulingDay[] {
69
65
  const { dateRange, dayOfWeek, dates } = period;
70
- const allowedDays = dayOfWeek ? new Set(dayOfWeek) : null;
71
- const allowedDates = dates ? new Set(dates) : null;
66
+ const allowedDays: Set<DayOfWeek> | null = dayOfWeek ? new Set(dayOfWeek) : null;
67
+ const allowedDates: Set<string> | null = dates ? new Set(dates) : null;
72
68
 
73
69
  const startDate = new Date(`${dateRange.start}T00:00:00Z`);
74
70
  const endDate = new Date(`${dateRange.end}T00:00:00Z`);
75
- const result: string[] = [];
71
+ const result: SchedulingDay[] = [];
76
72
 
77
- const current = new Date(startDate);
78
- while (current <= endDate) {
73
+ for (
74
+ let currentTime = startDate.getTime(), endTime = endDate.getTime();
75
+ currentTime <= endTime;
76
+ currentTime += 24 * 60 * 60 * 1000
77
+ ) {
78
+ const current = new Date(currentTime);
79
79
  const year = current.getUTCFullYear();
80
80
  const month = (current.getUTCMonth() + 1).toString().padStart(2, "0");
81
- const day = current.getUTCDate().toString().padStart(2, "0");
82
- const iso = `${year}-${month}-${day}`;
83
- const dow = toDayOfWeekUTC(current);
81
+ const d = current.getUTCDate().toString().padStart(2, "0");
82
+ const iso = `${year}-${month}-${d}` as DateString;
83
+ const day = schedulingDayFromDate(current, iso);
84
84
 
85
- if ((!allowedDays || allowedDays.has(dow)) && (!allowedDates || allowedDates.has(iso))) {
86
- result.push(iso);
85
+ if (
86
+ (!allowedDays || allowedDays.has(day.dayOfWeek)) &&
87
+ (!allowedDates || allowedDates.has(iso))
88
+ ) {
89
+ result.push(day);
87
90
  }
88
-
89
- current.setUTCDate(current.getUTCDate() + 1);
90
91
  }
91
92
 
92
93
  return result;
package/src/index.ts CHANGED
@@ -36,9 +36,9 @@
36
36
  // Time primitives
37
37
  // ============================================================================
38
38
 
39
- export type { TimeOfDay, DayOfWeek, SchedulingPeriod } from "./types.js";
39
+ export type { DateString, TimeOfDay, DayOfWeek, SchedulingDay, SchedulingPeriod } from "./types.js";
40
40
 
41
- export { DayOfWeekSchema } from "./types.js";
41
+ export { schedulingDay, DAY_OF_WEEK_INDEX, DayOfWeekSchema } from "./types.js";
42
42
 
43
43
  // ============================================================================
44
44
  // Solver client
@@ -51,13 +51,27 @@ export type {
51
51
  SolverRequest,
52
52
  SolverResponse,
53
53
  SolverStatus,
54
- SoftConstraintViolation,
54
+ SolverMode,
55
+ SolverDiagnosticMode,
56
+ SolverObjectiveStage,
57
+ SolverStageResult,
58
+ SolverSoftConstraintViolation,
59
+ SolverHardConstraintConflict,
55
60
  FetcherLike,
56
61
  } from "./client.types.js";
57
62
 
58
63
  export { SOLVER_STATUS } from "./client.types.js";
59
64
 
60
- export { SolverRequestSchema, SolverResponseSchema, SolverStatusSchema } from "./client.schemas.js";
65
+ export {
66
+ SolverModeSchema,
67
+ SolverDiagnosticModeSchema,
68
+ SolverObjectiveStageSchema,
69
+ SolverRequestSchema,
70
+ SolverResponseSchema,
71
+ SolverStageResultSchema,
72
+ SolverStatusSchema,
73
+ SolverHardConstraintConflictSchema,
74
+ } from "./client.schemas.js";
61
75
 
62
76
  // ============================================================================
63
77
  // Model builder
@@ -65,14 +79,27 @@ export { SolverRequestSchema, SolverResponseSchema, SolverStatusSchema } from ".
65
79
 
66
80
  export { ModelBuilder } from "./cpsat/model-builder.js";
67
81
 
82
+ export type { ModelBuilderConfig, CompilationResult } from "./cpsat/model-builder.js";
83
+ export type { ModelSolveStrategy } from "./cpsat/types.js";
84
+
85
+ export { compileRuleDescriptor, defineRuleDescriptor } from "./cpsat/rule-descriptor.js";
86
+
68
87
  export type {
69
- ModelBuilderConfig,
70
- CompilationResult,
71
- CompilationRule,
72
- RuleValidationContext,
88
+ CostValidationStrategy,
89
+ HardConstraintValidationStrategy,
90
+ ObjectiveValidationStrategy,
91
+ ReportHardConstraintValidationStrategy,
92
+ ReportSoftConstraintValidationStrategy,
93
+ RuleDescriptor,
94
+ RuleCompileContext,
95
+ RuleArtifact,
96
+ SkipValidationStrategy,
97
+ SoftConstraintValidationStrategy,
98
+ CompiledRule,
99
+ ValidationSkipCategory,
73
100
  CostEntry,
74
101
  CostContribution,
75
- } from "./cpsat/model-builder.js";
102
+ } from "./cpsat/rule-descriptor.js";
76
103
 
77
104
  // ============================================================================
78
105
  // Solver response parsing
@@ -94,10 +121,19 @@ export type { CostBreakdown, MemberCostDetail, CostCalculationConfig } from "./c
94
121
  // Rules (registry types)
95
122
  // ============================================================================
96
123
 
124
+ export {
125
+ assertValidCpsatRuleRegistry,
126
+ builtInCpsatRuleRegistry,
127
+ createCpsatRuleRegistry,
128
+ } from "./cpsat/rules/registry.js";
129
+
97
130
  export type {
131
+ BuiltInCpsatRuleConfigRegistry,
132
+ BuiltInCpsatRuleRegistry,
133
+ CpsatRuleConfigByName,
98
134
  CpsatRuleConfigEntry,
99
- CpsatRuleFactories,
100
- CreateCpsatRuleFunction,
135
+ CpsatRuleConfigEntryFor,
136
+ CpsatRuleRegistry,
101
137
  } from "./cpsat/rules/rules.types.js";
102
138
 
103
139
  export type { RecurringPeriod } from "./cpsat/rules/scope.types.js";
@@ -150,6 +186,7 @@ export { summarizeValidation } from "./cpsat/validation-reporter.js";
150
186
 
151
187
  export {
152
188
  schedule,
189
+ scheduleWithRuleRegistry,
153
190
  partialSchedule,
154
191
  Schedule,
155
192
  t,
@@ -162,16 +199,24 @@ export {
162
199
  minHoursPerWeek,
163
200
  maxDaysPerWeek,
164
201
  minDaysPerWeek,
202
+ targetDaysPerWeek,
165
203
  maxShiftsPerDay,
204
+ maxConcurrentAssignments,
205
+ targetPeakConcurrentAssignments,
166
206
  maxConsecutiveDays,
167
207
  minConsecutiveDays,
168
208
  minRestBetweenShifts,
169
209
  mustAssign,
170
- preference,
210
+ preferAssignment,
211
+ avoidAssignment,
212
+ preferRole,
171
213
  preferLocation,
172
214
  timeOff,
173
215
  assignTogether,
216
+ maxDaysOfWeekPerPeriod,
217
+ minDaysOfWeekPerPeriod,
174
218
  defineRule,
219
+ defineRuleFor,
175
220
  minimizeCost,
176
221
  dayMultiplier,
177
222
  daySurcharge,
@@ -192,12 +237,19 @@ export type {
192
237
  RuleEntry,
193
238
  RuleResolveContext,
194
239
  RuleOptions,
240
+ ScheduleRuleEntry,
195
241
  EntityOnlyRuleOptions,
242
+ TargetDaysPerWeekOptions,
196
243
  TimeOffOptions,
197
244
  AssignTogetherOptions,
245
+ MaxConcurrentAssignmentsOptions,
246
+ TargetPeakConcurrentAssignmentsOptions,
247
+ DaysOfWeekPerPeriodOptions,
198
248
  CostRuleOptions,
199
249
  ScheduleConfig,
250
+ ScheduleWithRuleRegistryConfig,
200
251
  SolveResult,
201
252
  SolveStatus,
253
+ SolveStrategy,
202
254
  SolveOptions,
203
255
  } from "./schedule/index.js";
@@ -1,6 +1,21 @@
1
1
  /**
2
2
  * Cost optimization rules: minimize labor cost with modifiers.
3
3
  *
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * rules: [
8
+ * minimizeCost(),
9
+ * dayMultiplier(1.5, { dayOfWeek: weekend }),
10
+ * overtimeMultiplier({ after: 40, factor: 1.5 }),
11
+ * dailyOvertimeSurcharge({ after: 8, amount: 500 }),
12
+ * tieredOvertimeMultiplier([
13
+ * { after: 40, factor: 1.5 },
14
+ * { after: 48, factor: 2.0 },
15
+ * ]),
16
+ * ]
17
+ * ```
18
+ *
4
19
  * @module
5
20
  */
6
21
 
@@ -39,7 +54,10 @@ export interface CostRuleOptions {
39
54
  // Cost Rules
40
55
  // ============================================================================
41
56
 
42
- function makeCostRule(rule: string, fields: Record<string, unknown>): RuleEntry {
57
+ function makeCostRule<const Name extends string, const Fields extends object>(
58
+ rule: Name,
59
+ fields: Fields,
60
+ ): RuleEntry<Name, Omit<Fields, "_type" | "_rule">> {
43
61
  return defineRule(rule, fields);
44
62
  }
45
63
 
@@ -64,14 +82,9 @@ function makeCostRule(rule: string, fields: Record<string, unknown>): RuleEntry
64
82
  * - `dailyOvertimeSurcharge({ after, amount }, opts?)` - daily overtime surcharge
65
83
  * - `tieredOvertimeMultiplier(tiers, opts?)` - multiple overtime thresholds
66
84
  *
67
- * @example
68
- * ```ts
69
- * minimizeCost()
70
- * ```
71
- *
72
85
  * @category Cost Optimization
73
86
  */
74
- export function minimizeCost(opts?: CostRuleOptions): RuleEntry {
87
+ export function minimizeCost(opts?: CostRuleOptions): RuleEntry<"minimize-cost", CostRuleOptions> {
75
88
  return makeCostRule("minimize-cost", { ...opts });
76
89
  }
77
90
 
@@ -83,13 +96,11 @@ export function minimizeCost(opts?: CostRuleOptions): RuleEntry {
83
96
  * this rule adds only the extra portion above 1x.
84
97
  *
85
98
  * @category Cost Optimization
86
- *
87
- * @example Weekend multiplier
88
- * ```typescript
89
- * dayMultiplier(1.5, { dayOfWeek: weekend })
90
- * ```
91
99
  */
92
- export function dayMultiplier(factor: number, opts?: CostRuleOptions): RuleEntry {
100
+ export function dayMultiplier(
101
+ factor: number,
102
+ opts?: CostRuleOptions,
103
+ ): RuleEntry<"day-cost-multiplier", { factor: number } & CostRuleOptions> {
93
104
  return makeCostRule("day-cost-multiplier", { factor, ...opts });
94
105
  }
95
106
 
@@ -100,13 +111,11 @@ export function dayMultiplier(factor: number, opts?: CostRuleOptions): RuleEntry
100
111
  * The surcharge is independent of the member's base rate.
101
112
  *
102
113
  * @category Cost Optimization
103
- *
104
- * @example Weekend surcharge
105
- * ```typescript
106
- * daySurcharge(500, { dayOfWeek: weekend })
107
- * ```
108
114
  */
109
- export function daySurcharge(amountPerHour: number, opts?: CostRuleOptions): RuleEntry {
115
+ export function daySurcharge(
116
+ amountPerHour: number,
117
+ opts?: CostRuleOptions,
118
+ ): RuleEntry<"day-cost-surcharge", { amountPerHour: number } & CostRuleOptions> {
110
119
  return makeCostRule("day-cost-surcharge", { amountPerHour, ...opts });
111
120
  }
112
121
 
@@ -122,17 +131,15 @@ export function daySurcharge(amountPerHour: number, opts?: CostRuleOptions): Rul
122
131
  * @param opts - Entity and time scoping
123
132
  *
124
133
  * @category Cost Optimization
125
- *
126
- * @example Night differential
127
- * ```typescript
128
- * timeSurcharge(200, { from: t(22), until: t(6) })
129
- * ```
130
134
  */
131
135
  export function timeSurcharge(
132
136
  amountPerHour: number,
133
137
  window: { from: TimeOfDay; until: TimeOfDay },
134
138
  opts?: CostRuleOptions,
135
- ): RuleEntry {
139
+ ): RuleEntry<
140
+ "time-cost-surcharge",
141
+ { amountPerHour: number; window: { from: TimeOfDay; until: TimeOfDay } } & CostRuleOptions
142
+ > {
136
143
  return makeCostRule("time-cost-surcharge", { amountPerHour, window, ...opts });
137
144
  }
138
145
 
@@ -144,15 +151,10 @@ export function timeSurcharge(
144
151
  * counted by {@link minimizeCost}).
145
152
  *
146
153
  * @category Cost Optimization
147
- *
148
- * @example
149
- * ```typescript
150
- * overtimeMultiplier({ after: 40, factor: 1.5 })
151
- * ```
152
154
  */
153
155
  export function overtimeMultiplier(
154
156
  opts: { after: number; factor: number } & CostRuleOptions,
155
- ): RuleEntry {
157
+ ): RuleEntry<"overtime-weekly-multiplier", { after: number; factor: number } & CostRuleOptions> {
156
158
  return makeCostRule("overtime-weekly-multiplier", { ...opts });
157
159
  }
158
160
 
@@ -163,15 +165,10 @@ export function overtimeMultiplier(
163
165
  * The surcharge is independent of the member's base rate.
164
166
  *
165
167
  * @category Cost Optimization
166
- *
167
- * @example
168
- * ```typescript
169
- * overtimeSurcharge({ after: 40, amount: 1000 })
170
- * ```
171
168
  */
172
169
  export function overtimeSurcharge(
173
170
  opts: { after: number; amount: number } & CostRuleOptions,
174
- ): RuleEntry {
171
+ ): RuleEntry<"overtime-weekly-surcharge", { after: number; amount: number } & CostRuleOptions> {
175
172
  return makeCostRule("overtime-weekly-surcharge", { ...opts });
176
173
  }
177
174
 
@@ -183,15 +180,10 @@ export function overtimeSurcharge(
183
180
  * counted by {@link minimizeCost}).
184
181
  *
185
182
  * @category Cost Optimization
186
- *
187
- * @example
188
- * ```typescript
189
- * dailyOvertimeMultiplier({ after: 8, factor: 1.5 })
190
- * ```
191
183
  */
192
184
  export function dailyOvertimeMultiplier(
193
185
  opts: { after: number; factor: number } & CostRuleOptions,
194
- ): RuleEntry {
186
+ ): RuleEntry<"overtime-daily-multiplier", { after: number; factor: number } & CostRuleOptions> {
195
187
  return makeCostRule("overtime-daily-multiplier", { ...opts });
196
188
  }
197
189
 
@@ -202,15 +194,10 @@ export function dailyOvertimeMultiplier(
202
194
  * The surcharge is independent of the member's base rate.
203
195
  *
204
196
  * @category Cost Optimization
205
- *
206
- * @example
207
- * ```typescript
208
- * dailyOvertimeSurcharge({ after: 8, amount: 500 })
209
- * ```
210
197
  */
211
198
  export function dailyOvertimeSurcharge(
212
199
  opts: { after: number; amount: number } & CostRuleOptions,
213
- ): RuleEntry {
200
+ ): RuleEntry<"overtime-daily-surcharge", { after: number; amount: number } & CostRuleOptions> {
214
201
  return makeCostRule("overtime-daily-surcharge", { ...opts });
215
202
  }
216
203
 
@@ -222,21 +209,13 @@ export function dailyOvertimeSurcharge(
222
209
  * Tiers must be sorted by threshold ascending.
223
210
  *
224
211
  * @category Cost Optimization
225
- *
226
- * @example
227
- * ```typescript
228
- * // Hours 0-40: base rate
229
- * // Hours 40-48: 1.5x
230
- * // Hours 48+: 2.0x
231
- * tieredOvertimeMultiplier([
232
- * { after: 40, factor: 1.5 },
233
- * { after: 48, factor: 2.0 },
234
- * ])
235
- * ```
236
212
  */
237
213
  export function tieredOvertimeMultiplier(
238
214
  tiers: [OvertimeTier, ...OvertimeTier[]],
239
215
  opts?: CostRuleOptions,
240
- ): RuleEntry {
216
+ ): RuleEntry<
217
+ "overtime-tiered-multiplier",
218
+ { tiers: [OvertimeTier, ...OvertimeTier[]] } & CostRuleOptions
219
+ > {
241
220
  return makeCostRule("overtime-tiered-multiplier", { tiers, ...opts });
242
221
  }
@@ -1,10 +1,33 @@
1
1
  /**
2
- * Coverage definitions: staffing requirements per semantic time period.
2
+ * Coverage definitions: lower-bound staffing requirements per semantic time period.
3
+ *
4
+ * Coverage answers "what floor should apply throughout this scoped time, with
5
+ * the chosen priority?". It attaches sustained lower bounds to semantic times,
6
+ * whether those periods are
7
+ * explicit in the requirements or inferred to separate distinct business
8
+ * requirements. Coverage does not express caps, targets, fairness, or other
9
+ * assignment-shaping logic. Use rules for those concerns.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * coverage: [
14
+ * cover("lunch", "waiter", 2, { dayOfWeek: weekdays }),
15
+ * cover("lunch", "waiter", 3, { dayOfWeek: weekend }),
16
+ * cover("dinner", ["manager", "supervisor"], 1),
17
+ * cover("opening", "keyholder", 1),
18
+ *
19
+ * // Variant form: different counts by day
20
+ * cover("peak_hours", "agent",
21
+ * { count: 4 },
22
+ * { count: 2, dates: ["2025-12-24"] },
23
+ * ),
24
+ * ]
25
+ * ```
3
26
  *
4
27
  * @module
5
28
  */
6
29
 
7
- import type { DayOfWeek } from "../types.js";
30
+ import type { DateString, DayOfWeek } from "../types.js";
8
31
  import type { CoverageVariant } from "../cpsat/semantic-time.js";
9
32
  import type { Priority } from "../cpsat/types.js";
10
33
 
@@ -16,7 +39,15 @@ export type { CoverageVariant } from "../cpsat/semantic-time.js";
16
39
  * @remarks
17
40
  * Day/date scoping controls which days this coverage entry applies to.
18
41
  * An entry without `dayOfWeek` or `dates` applies every day in the
19
- * scheduling period.
42
+ * scheduling period. Scope answers where the floor applies; it does not change
43
+ * the meaning of coverage itself. `priority` controls how hard the coverage floor is.
44
+ * Use it to distinguish language like "must keep 5 staffed on Saturdays"
45
+ * from "ideally keep 5 staffed on Mondays too" without changing the
46
+ * underlying coverage shape. `skillIds` is a hard filter, not a preference.
47
+ * Use it only when the required minimum truly needs those skills throughout
48
+ * the window. If a role or skill mix is preferred rather than required, model
49
+ * that with rules such as {@link preferAssignment} instead of skill-filtered
50
+ * coverage.
20
51
  *
21
52
  * @category Coverage
22
53
  */
@@ -26,7 +57,7 @@ export interface CoverageOptions {
26
57
  /** Restrict to specific days of the week. */
27
58
  dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
28
59
  /** Restrict to specific dates (YYYY-MM-DD). */
29
- dates?: string[];
60
+ dates?: DateString[];
30
61
  /** Defaults to `"MANDATORY"`. */
31
62
  priority?: Priority;
32
63
  }
@@ -53,36 +84,34 @@ export interface CoverageEntry<T extends string = string, R extends string = str
53
84
  * Defines a staffing requirement for a semantic time period.
54
85
  *
55
86
  * @remarks
56
- * Entries for the same time and role **stack additively**.
57
- * For weekday vs weekend staffing, use mutually exclusive `dayOfWeek`
58
- * on both entries.
87
+ * Coverage always defines a lower bound that applies throughout the scoped
88
+ * semantic time, with strength controlled by `priority`. If the requirements
89
+ * also state an upper bound or productive
90
+ * cap, model that separately in `rules`, for example with
91
+ * {@link maxConcurrentAssignments}.
92
+ *
93
+ * Scope answers where the floor applies. Priority answers how strictly the
94
+ * solver should preserve that floor when trade-offs are necessary.
95
+ *
96
+ * Attach coverage to the narrowest semantic time that actually carries that
97
+ * minimum. Avoid layering a broad parent coverage window on top of narrower
98
+ * windows unless the same lower bound truly applies throughout the full span.
99
+ * If the requirements talk about hitting full occupancy at the busy point,
100
+ * prefer {@link targetPeakConcurrentAssignments} over turning that into a
101
+ * whole-window minimum. Do not infer a synthetic "peak" semantic time just to attach
102
+ * `cover(..., 5)` unless the requirements really define a sustained window
103
+ * that needs that minimum throughout.
104
+ *
105
+ * Overlapping entries for the same time and role produce independent
106
+ * constraints; the solver enforces the **max** count, not the sum.
107
+ * An unscoped entry acts as a floor that scoped entries cannot reduce.
108
+ * Use mutually exclusive scopes when different days need different coverage.
59
109
  *
60
110
  * @param timeName - Name of a declared semantic time
61
111
  * @param target - Role name (string), array of role names (OR logic), or skill name
62
112
  * @param count - Number of people needed
63
113
  * @param opts - Options: `skillIds` (AND filter), `dayOfWeek`, `dates`, `priority`
64
114
  *
65
- * @example
66
- * ```typescript
67
- * coverage: [
68
- * // 2 waiters during lunch
69
- * cover("lunch", "waiter", 2),
70
- *
71
- * // 1 manager OR supervisor during dinner
72
- * cover("dinner", ["manager", "supervisor"], 1),
73
- *
74
- * // 1 person with keyholder skill at opening
75
- * cover("opening", "keyholder", 1),
76
- *
77
- * // 1 senior waiter (role + skill AND)
78
- * cover("lunch", "waiter", 1, { skillIds: ["senior"] }),
79
- *
80
- * // Different counts by day (mutually exclusive dayOfWeek!)
81
- * cover("lunch", "waiter", 2, { dayOfWeek: weekdays }),
82
- * cover("lunch", "waiter", 3, { dayOfWeek: weekend }),
83
- * ]
84
- * ```
85
- *
86
115
  * @category Coverage
87
116
  */
88
117
  export function cover<T extends string, const R extends string>(