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
@@ -0,0 +1,146 @@
1
+ import * as z from "zod";
2
+ import { defineRuleDescriptor } from "../rule-descriptor.js";
3
+ import { targetPeakPriorityToPenalty } from "../utils.js";
4
+ import { boolVariable, hardConstraint, intVariable, reportValidation, skipValidation, softConstraint, } from "./artifacts.js";
5
+ import { buildConcurrentAssignmentSegments, collectConcurrentAssignmentIntervals, resolveConcurrentWindow, } from "./concurrent-intervals.js";
6
+ import { entityScope, parseEntityScope, parseTimeScope, resolveActiveDaysFromScope, resolveMembersFromScope, ruleGroup, SoftPrioritySchema, timeScope, } from "./scope.types.js";
7
+ export const TargetPeakConcurrentAssignmentsSchema = z
8
+ .object({
9
+ assignments: z.number().int().min(0),
10
+ priority: SoftPrioritySchema.default("HIGH"),
11
+ })
12
+ .and(entityScope(["members", "roles", "skills"]))
13
+ .and(timeScope(["dateRange", "specificDates", "dayOfWeek", "recurring"]));
14
+ /** @internal */
15
+ export const TARGET_PEAK_CONCURRENT_ASSIGNMENTS_OBJECTIVE_STAGE_ID = "__dabke_target_peak_concurrent_assignments__";
16
+ /**
17
+ * Low-level descriptor for the `target-peak-concurrent-assignments` rule.
18
+ *
19
+ * @remarks
20
+ * Softly targets the daily peak number of concurrent targeted assignments
21
+ * within the scoped day set. This is not a lower bound across the whole day.
22
+ * Use {@link import("../../schedule/coverage.js").cover} for whole-window
23
+ * minimum staffing, and pair this rule with
24
+ * {@link import("./max-concurrent-assignments.js").maxConcurrentAssignmentsRuleDescriptor}
25
+ * when the same value is also a hard capacity cap.
26
+ *
27
+ * @category Rules
28
+ */
29
+ export const targetPeakConcurrentAssignmentsRuleDescriptor = defineRuleDescriptor({
30
+ name: "target-peak-concurrent-assignments",
31
+ schema: TargetPeakConcurrentAssignmentsSchema,
32
+ compile(config, ctx) {
33
+ const { assignments, priority } = config;
34
+ if (assignments === 0) {
35
+ return { rule: "target-peak-concurrent-assignments", artifacts: [] };
36
+ }
37
+ const entityScopeValue = parseEntityScope(config);
38
+ const timeScopeValue = parseTimeScope(config);
39
+ const targetMembers = resolveMembersFromScope(entityScopeValue, [...ctx.members]);
40
+ const activeDays = resolveActiveDaysFromScope(timeScopeValue, [...ctx.days]);
41
+ if (activeDays.length === 0) {
42
+ return { rule: "target-peak-concurrent-assignments", artifacts: [] };
43
+ }
44
+ const group = ruleGroup(`target-peak-concurrent-assignments:${assignments}`, `Target peak ${assignments} concurrent assignment${assignments === 1 ? "" : "s"}`, entityScopeValue, timeScopeValue);
45
+ const artifacts = activeDays.flatMap((day) => {
46
+ const dayContext = { days: [day.iso], memberIds: targetMembers.map((member) => member.id) };
47
+ const intervals = collectConcurrentAssignmentIntervals(day, targetMembers, ctx.shiftPatterns);
48
+ const window = resolveConcurrentWindow(intervals);
49
+ const segments = buildConcurrentAssignmentSegments(intervals, window.start, window.end);
50
+ const dayKey = `${group.key}:${day.iso}`;
51
+ const shortfallVar = `${dayKey}:shortfall`;
52
+ if (segments.length === 0) {
53
+ return [
54
+ intVariable(shortfallVar, 0, assignments),
55
+ hardConstraint({
56
+ group,
57
+ description: `Fix peak-target shortfall to ${assignments} on ${day.iso} because no eligible assignments exist`,
58
+ context: dayContext,
59
+ validation: skipValidation("scaffolding", "Peak-target shortfall is fixed when no eligible assignments can contribute to the daily peak."),
60
+ terms: [{ var: shortfallVar, coeff: 1 }],
61
+ comparator: "==",
62
+ targetValue: assignments,
63
+ }),
64
+ softConstraint({
65
+ stage: TARGET_PEAK_CONCURRENT_ASSIGNMENTS_OBJECTIVE_STAGE_ID,
66
+ group,
67
+ description: `Target peak ${assignments} concurrent assignment${assignments === 1 ? "" : "s"} on ${day.iso}`,
68
+ context: dayContext,
69
+ validation: reportValidation(),
70
+ terms: [{ var: shortfallVar, coeff: 1 }],
71
+ comparator: "<=",
72
+ targetValue: 0,
73
+ penalty: targetPeakPriorityToPenalty(priority),
74
+ constraintId: `${dayKey}:shortfall`,
75
+ }),
76
+ ];
77
+ }
78
+ const witnessVars = segments.map((segment) => ({
79
+ segmentStart: segment.start,
80
+ name: `${dayKey}:${segment.start}:witness`,
81
+ }));
82
+ const helperArtifacts = [
83
+ intVariable(shortfallVar, 0, assignments),
84
+ ...witnessVars.map(({ name }) => boolVariable(name)),
85
+ hardConstraint({
86
+ group,
87
+ description: `Select exactly one peak segment witness on ${day.iso}`,
88
+ context: dayContext,
89
+ validation: skipValidation("scaffolding", "Peak-target witness selection is an internal helper for day-level peak targeting."),
90
+ terms: witnessVars.map(({ name }) => ({ var: name, coeff: 1 })),
91
+ comparator: "==",
92
+ targetValue: 1,
93
+ }),
94
+ ];
95
+ const linkageArtifacts = segments.map((segment) => {
96
+ const witnessVar = witnessVars.find((witness) => witness.segmentStart === segment.start)?.name;
97
+ if (!witnessVar) {
98
+ throw new Error(`Missing peak-target witness variable for segment ${segment.start} on ${day.iso}`);
99
+ }
100
+ return hardConstraint({
101
+ group,
102
+ description: `Link peak-target shortfall to segment ${formatTimeRange(segment.start, segment.end)} on ${day.iso}`,
103
+ context: dayContext,
104
+ validation: skipValidation("scaffolding", "Peak-target segment linkage is an internal helper that selects the best segment on a day."),
105
+ terms: [
106
+ ...segment.varNames.map((varName) => ({ var: varName, coeff: 1 })),
107
+ { var: witnessVar, coeff: -assignments },
108
+ { var: shortfallVar, coeff: 1 },
109
+ ],
110
+ comparator: ">=",
111
+ targetValue: 0,
112
+ });
113
+ });
114
+ const shortfallArtifact = softConstraint({
115
+ stage: TARGET_PEAK_CONCURRENT_ASSIGNMENTS_OBJECTIVE_STAGE_ID,
116
+ group,
117
+ description: `Target peak ${assignments} concurrent assignment${assignments === 1 ? "" : "s"} on ${day.iso}`,
118
+ context: dayContext,
119
+ validation: reportValidation(),
120
+ terms: [{ var: shortfallVar, coeff: 1 }],
121
+ comparator: "<=",
122
+ targetValue: 0,
123
+ penalty: targetPeakPriorityToPenalty(priority),
124
+ constraintId: `${dayKey}:shortfall`,
125
+ });
126
+ const dayArtifacts = [];
127
+ dayArtifacts.push(...helperArtifacts, ...linkageArtifacts, shortfallArtifact);
128
+ return dayArtifacts;
129
+ });
130
+ return {
131
+ rule: "target-peak-concurrent-assignments",
132
+ artifacts,
133
+ };
134
+ },
135
+ });
136
+ function formatTimeRange(startMinutes, endMinutes) {
137
+ return `${formatClockMinutes(startMinutes)}-${formatClockMinutes(endMinutes)}`;
138
+ }
139
+ function formatClockMinutes(totalMinutes) {
140
+ const minutesPerDay = 24 * 60;
141
+ const normalized = ((totalMinutes % minutesPerDay) + minutesPerDay) % minutesPerDay;
142
+ const hours = Math.floor(normalized / 60);
143
+ const minutes = normalized % 60;
144
+ return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
145
+ }
146
+ //# sourceMappingURL=target-peak-concurrent-assignments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-peak-concurrent-assignments.js","sourceRoot":"","sources":["../../../src/cpsat/rules/target-peak-concurrent-assignments.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import * as z from "zod";
2
- import type { CompilationRule } from "../model-builder.js";
3
- declare const TimeCostSurchargeSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
2
+ export declare const TimeCostSurchargeSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
4
3
  amountPerHour: z.ZodNumber;
5
4
  window: z.ZodObject<{
6
5
  from: z.ZodObject<{
@@ -13,17 +12,19 @@ declare const TimeCostSurchargeSchema: z.ZodIntersection<z.ZodIntersection<z.Zod
13
12
  }, z.core.$strip>;
14
13
  }, z.core.$strip>;
15
14
  }, z.core.$strip>, z.ZodType<import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">, unknown, z.core.$ZodTypeInternals<import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">, unknown>>>, z.ZodType<import("./scope.types.js").OptionalTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">, unknown, z.core.$ZodTypeInternals<import("./scope.types.js").OptionalTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">, unknown>>>;
16
- /** Configuration for {@link createTimeCostSurchargeRule}. */
15
+ /** Configuration for {@link timeCostSurchargeRuleDescriptor}. */
17
16
  export type TimeCostSurchargeConfig = z.infer<typeof TimeCostSurchargeSchema>;
18
- /**
19
- * Creates a time-of-day surcharge rule (e.g., night differential).
20
- *
21
- * Adds a flat surcharge per hour for the portion of a shift that overlaps
22
- * a time-of-day window. Independent of the member's base rate.
23
- *
24
- * When `minimizeCost()` is not present, no solver terms are emitted,
25
- * but the `cost()` method still contributes to post-solve calculation.
26
- */
27
- export declare function createTimeCostSurchargeRule(config: TimeCostSurchargeConfig): CompilationRule;
28
- export {};
17
+ export declare const timeCostSurchargeRuleDescriptor: import("../rule-descriptor.js").RuleDescriptor<"time-cost-surcharge", ({
18
+ amountPerHour: number;
19
+ window: {
20
+ from: {
21
+ hours: number;
22
+ minutes: number;
23
+ };
24
+ until: {
25
+ hours: number;
26
+ minutes: number;
27
+ };
28
+ };
29
+ } & import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">) & import("./scope.types.js").OptionalTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">>;
29
30
  //# sourceMappingURL=time-cost-surcharge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"time-cost-surcharge.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/time-cost-surcharge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAoB7E,QAAA,MAAM,uBAAuB;;;;;;;;;;;;mfAS8C,CAAC;AAE5E,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AA4C9E;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,uBAAuB,GAAG,eAAe,CAmF5F"}
1
+ {"version":3,"file":"time-cost-surcharge.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/time-cost-surcharge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAoBzB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;mfASuC,CAAC;AAE5E,iEAAiE;AACjE,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE9E,eAAO,MAAM,+BAA+B;;;;;;;;;;;;8LAqG1C,CAAC"}
@@ -1,12 +1,13 @@
1
1
  import * as z from "zod";
2
+ import { defineRuleDescriptor } from "../rule-descriptor.js";
2
3
  import { COST_CATEGORY } from "../cost.js";
3
- import { timeOfDayToMinutes, normalizeEndMinutes, MINUTES_PER_DAY } from "../utils.js";
4
- import { entityScope, timeScope, parseEntityScope, parseTimeScope, resolveMembersFromScope, resolveActiveDaysFromScope, } from "./scope.types.js";
4
+ import { MINUTES_PER_DAY, normalizeEndMinutes, timeOfDayToMinutes } from "../utils.js";
5
+ import { entityScope, parseEntityScope, parseTimeScope, resolveActiveDaysFromScope, resolveMembersFromScope, timeScope, } from "./scope.types.js";
5
6
  const TimeOfDaySchema = z.object({
6
7
  hours: z.number().int().min(0).max(23),
7
8
  minutes: z.number().int().min(0).max(59),
8
9
  });
9
- const TimeCostSurchargeSchema = z
10
+ export const TimeCostSurchargeSchema = z
10
11
  .object({
11
12
  amountPerHour: z.number().min(0),
12
13
  window: z.object({
@@ -16,110 +17,95 @@ const TimeCostSurchargeSchema = z
16
17
  })
17
18
  .and(entityScope(["members", "roles", "skills"]))
18
19
  .and(timeScope(["dateRange", "specificDates", "dayOfWeek", "recurring"]));
19
- /**
20
- * Computes the overlap in minutes between a shift and a time-of-day window.
21
- *
22
- * Handles overnight windows (e.g., 22:00-06:00) and overnight shifts.
23
- */
20
+ export const timeCostSurchargeRuleDescriptor = defineRuleDescriptor({
21
+ name: "time-cost-surcharge",
22
+ schema: TimeCostSurchargeSchema,
23
+ compile(config) {
24
+ const { amountPerHour, window } = config;
25
+ const entityScopeValue = parseEntityScope(config);
26
+ const timeScopeValue = parseTimeScope(config);
27
+ const validation = {
28
+ strategy: "skip",
29
+ category: "no-meaningful-feedback",
30
+ rationale: amountPerHour <= 0
31
+ ? "A zero time surcharge does not change optimization or cost accounting."
32
+ : "Time cost surcharges only affect optimization when minimize-cost is active.",
33
+ };
34
+ const costArtifact = {
35
+ kind: "cost",
36
+ validation,
37
+ compileObjective(builder) {
38
+ if (!builder.costContext?.active || amountPerHour <= 0)
39
+ return;
40
+ const targetMembers = resolveMembersFromScope(entityScopeValue, builder.members);
41
+ const activeDays = resolveActiveDaysFromScope(timeScopeValue, builder.days);
42
+ if (targetMembers.length === 0 || activeDays.length === 0)
43
+ return;
44
+ const { normalizationFactor } = builder.costContext;
45
+ for (const member of targetMembers) {
46
+ for (const pattern of builder.shiftPatterns) {
47
+ if (!builder.canAssign(member, pattern))
48
+ continue;
49
+ const overlapMinutes = computeOverlapMinutes(pattern.startTime, pattern.endTime, window.from, window.until);
50
+ if (overlapMinutes <= 0)
51
+ continue;
52
+ const surcharge = (amountPerHour * overlapMinutes) / 60;
53
+ const normalizedPenalty = surcharge / normalizationFactor;
54
+ for (const day of activeDays) {
55
+ if (!builder.patternAvailableOnDay(pattern, day))
56
+ continue;
57
+ builder.addPenalty(builder.assignment(member.id, pattern.id, day), Math.max(1, normalizedPenalty));
58
+ }
59
+ }
60
+ }
61
+ },
62
+ calculateCost(assignments, costContext) {
63
+ if (amountPerHour <= 0)
64
+ return { entries: [] };
65
+ const patternMap = new Map(costContext.shiftPatterns.map((pattern) => [pattern.id, pattern]));
66
+ const activeDays = new Set(resolveActiveDaysFromScope(timeScopeValue, [...costContext.days]).map((day) => day.iso));
67
+ const targetMemberIds = new Set(resolveMembersFromScope(entityScopeValue, [...costContext.members]).map((member) => member.id));
68
+ const entries = [];
69
+ for (const assignment of assignments) {
70
+ if (!activeDays.has(assignment.day) || !targetMemberIds.has(assignment.memberId))
71
+ continue;
72
+ const pattern = patternMap.get(assignment.shiftPatternId);
73
+ if (!pattern)
74
+ continue;
75
+ const overlapMinutes = computeOverlapMinutes(pattern.startTime, pattern.endTime, window.from, window.until);
76
+ if (overlapMinutes <= 0)
77
+ continue;
78
+ entries.push({
79
+ memberId: assignment.memberId,
80
+ day: assignment.day,
81
+ category: COST_CATEGORY.PREMIUM,
82
+ amount: (amountPerHour * overlapMinutes) / 60,
83
+ });
84
+ }
85
+ return { entries };
86
+ },
87
+ };
88
+ return {
89
+ rule: "time-cost-surcharge",
90
+ artifacts: [costArtifact],
91
+ };
92
+ },
93
+ });
24
94
  function computeOverlapMinutes(shiftStart, shiftEnd, windowFrom, windowUntil) {
25
95
  const sStart = timeOfDayToMinutes(shiftStart);
26
96
  const sEnd = normalizeEndMinutes(sStart, timeOfDayToMinutes(shiftEnd));
27
97
  const wFrom = timeOfDayToMinutes(windowFrom);
28
98
  const wUntil = timeOfDayToMinutes(windowUntil);
29
- // Expand window: if overnight (e.g., 22:00-06:00), wUntil < wFrom
30
- // Represent as two intervals or one extended interval
31
- let totalOverlap = 0;
32
99
  if (wFrom < wUntil) {
33
- // Normal window (e.g., 14:00-18:00)
34
- totalOverlap = rangeOverlap(sStart, sEnd, wFrom, wUntil);
35
- }
36
- else {
37
- // Overnight window (e.g., 22:00-06:00)
38
- // Split into [wFrom, MINUTES_PER_DAY) and [0, wUntil)
39
- // But shift may also span overnight, so use extended ranges
40
- totalOverlap += rangeOverlap(sStart, sEnd, wFrom, MINUTES_PER_DAY);
41
- totalOverlap += rangeOverlap(sStart, sEnd, MINUTES_PER_DAY, MINUTES_PER_DAY + wUntil);
42
- // Also check if shift overlaps [0, wUntil) in the same day
43
- totalOverlap += rangeOverlap(sStart, sEnd, 0, wUntil);
100
+ return rangeOverlap(sStart, sEnd, wFrom, wUntil);
44
101
  }
45
- return totalOverlap;
102
+ return (rangeOverlap(sStart, sEnd, wFrom, MINUTES_PER_DAY) +
103
+ rangeOverlap(sStart, sEnd, MINUTES_PER_DAY, MINUTES_PER_DAY + wUntil) +
104
+ rangeOverlap(sStart, sEnd, 0, wUntil));
46
105
  }
47
106
  function rangeOverlap(aStart, aEnd, bStart, bEnd) {
48
107
  const start = Math.max(aStart, bStart);
49
108
  const end = Math.min(aEnd, bEnd);
50
109
  return Math.max(0, end - start);
51
110
  }
52
- /**
53
- * Creates a time-of-day surcharge rule (e.g., night differential).
54
- *
55
- * Adds a flat surcharge per hour for the portion of a shift that overlaps
56
- * a time-of-day window. Independent of the member's base rate.
57
- *
58
- * When `minimizeCost()` is not present, no solver terms are emitted,
59
- * but the `cost()` method still contributes to post-solve calculation.
60
- */
61
- export function createTimeCostSurchargeRule(config) {
62
- const parsed = TimeCostSurchargeSchema.parse(config);
63
- const { amountPerHour, window } = parsed;
64
- const entityScopeValue = parseEntityScope(parsed);
65
- const timeScopeValue = parseTimeScope(parsed);
66
- return {
67
- compile(b) {
68
- if (!b.costContext?.active)
69
- return;
70
- if (amountPerHour <= 0)
71
- return;
72
- const targetMembers = resolveMembersFromScope(entityScopeValue, b.members);
73
- const activeDays = resolveActiveDaysFromScope(timeScopeValue, b.days);
74
- if (targetMembers.length === 0 || activeDays.length === 0)
75
- return;
76
- const { normalizationFactor } = b.costContext;
77
- for (const emp of targetMembers) {
78
- for (const pattern of b.shiftPatterns) {
79
- if (!b.canAssign(emp, pattern))
80
- continue;
81
- const overlapMinutes = computeOverlapMinutes(pattern.startTime, pattern.endTime, window.from, window.until);
82
- if (overlapMinutes <= 0)
83
- continue;
84
- const surcharge = (amountPerHour * overlapMinutes) / 60;
85
- const normalizedPenalty = surcharge / normalizationFactor;
86
- for (const day of activeDays) {
87
- if (!b.patternAvailableOnDay(pattern, day))
88
- continue;
89
- b.addPenalty(b.assignment(emp.id, pattern.id, day), Math.max(1, normalizedPenalty));
90
- }
91
- }
92
- }
93
- },
94
- cost(assignments, members, shiftPatterns) {
95
- if (amountPerHour <= 0)
96
- return { entries: [] };
97
- const patternMap = new Map(shiftPatterns.map((p) => [p.id, p]));
98
- const allDays = [...new Set(assignments.map((a) => a.day))].toSorted();
99
- const activeDays = new Set(resolveActiveDaysFromScope(timeScopeValue, allDays));
100
- const targetEmpIds = new Set(resolveMembersFromScope(entityScopeValue, [...members]).map((e) => e.id));
101
- const entries = [];
102
- for (const a of assignments) {
103
- if (!activeDays.has(a.day))
104
- continue;
105
- if (!targetEmpIds.has(a.memberId))
106
- continue;
107
- const pattern = patternMap.get(a.shiftPatternId);
108
- if (!pattern)
109
- continue;
110
- const overlapMinutes = computeOverlapMinutes(pattern.startTime, pattern.endTime, window.from, window.until);
111
- if (overlapMinutes <= 0)
112
- continue;
113
- const amount = (amountPerHour * overlapMinutes) / 60;
114
- entries.push({
115
- memberId: a.memberId,
116
- day: a.day,
117
- category: COST_CATEGORY.PREMIUM,
118
- amount,
119
- });
120
- }
121
- return { entries };
122
- },
123
- };
124
- }
125
111
  //# sourceMappingURL=time-cost-surcharge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"time-cost-surcharge.js","sourceRoot":"","sources":["../../../src/cpsat/rules/time-cost-surcharge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"time-cost-surcharge.js","sourceRoot":"","sources":["../../../src/cpsat/rules/time-cost-surcharge.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,11 @@
1
1
  import * as z from "zod";
2
- import type { CompilationRule } from "../model-builder.js";
3
- declare const TimeOffSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
4
- priority: z.ZodDefault<z.ZodUnion<readonly [z.ZodLiteral<"LOW">, z.ZodLiteral<"MEDIUM">, z.ZodLiteral<"HIGH">, z.ZodLiteral<"MANDATORY">]>>;
2
+ export declare const TimeOffSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
3
+ priority: z.ZodDefault<z.ZodEnum<{
4
+ LOW: "LOW";
5
+ MEDIUM: "MEDIUM";
6
+ HIGH: "HIGH";
7
+ MANDATORY: "MANDATORY";
8
+ }>>;
5
9
  startTime: z.ZodOptional<z.ZodObject<{
6
10
  hours: z.ZodNumber;
7
11
  minutes: z.ZodNumber;
@@ -12,63 +16,23 @@ declare const TimeOffSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
12
16
  }, z.core.$strip>>;
13
17
  }, z.core.$strip>, z.ZodType<import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">, unknown, z.core.$ZodTypeInternals<import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">, unknown>>>, z.ZodType<import("./scope.types.js").RequiredTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">, unknown, z.core.$ZodTypeInternals<import("./scope.types.js").RequiredTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">, unknown>>>;
14
18
  /**
15
- * Configuration for {@link createTimeOffRule}.
16
- *
17
- * - `priority` (required): how strictly the solver enforces this rule
18
- * - `startTime` (optional): start of the time-off window within each day; must be paired with `endTime`
19
- * - `endTime` (optional): end of the time-off window within each day; must be paired with `startTime`
20
- *
21
- * Entity scoping (at most one):
22
- * - `memberIds`: restrict to specific members
23
- * - `roleIds`: restrict to members with matching roles
24
- * - `skillIds`: restrict to members with matching skills
25
- *
26
- * Time scoping (exactly one required):
27
- * - `dateRange`: contiguous date range
28
- * - `specificDates`: specific dates
29
- * - `dayOfWeek`: days of the week
30
- * - `recurringPeriods`: recurring calendar periods
19
+ * Configuration for {@link timeOffRuleDescriptor}.
31
20
  */
32
21
  export type TimeOffConfig = z.infer<typeof TimeOffSchema>;
33
22
  /**
34
- * Blocks or penalizes assignments during specified time periods.
35
- *
36
- * Supports entity scoping (people, roles, skills) and time scoping
37
- * (date ranges, specific dates, days of week, recurring periods).
38
- * Optionally supports partial-day time-off with startTime/endTime.
39
- *
40
- * @param config - See {@link TimeOffConfig}
41
- * @example Full day vacation
42
- * ```ts
43
- * createTimeOffRule({
44
- * memberIds: ["alice"],
45
- * dateRange: { start: "2024-02-01", end: "2024-02-05" },
46
- * priority: "MANDATORY",
47
- * });
48
- * ```
49
- *
50
- * @example Every Wednesday afternoon off for students
51
- * ```ts
52
- * createTimeOffRule({
53
- * roleIds: ["student"],
54
- * dayOfWeek: ["wednesday"],
55
- * startTime: { hours: 14, minutes: 0 },
56
- * endTime: { hours: 23, minutes: 59 },
57
- * priority: "MANDATORY",
58
- * });
59
- * ```
23
+ * Low-level descriptor for the `time-off` rule.
60
24
  *
61
- * @example Specific date, partial day
62
- * ```ts
63
- * createTimeOffRule({
64
- * memberIds: ["bob"],
65
- * specificDates: ["2024-03-15"],
66
- * startTime: { hours: 16, minutes: 0 },
67
- * endTime: { hours: 23, minutes: 59 },
68
- * priority: "MANDATORY",
69
- * });
70
- * ```
25
+ * @category Rules
71
26
  */
72
- export declare function createTimeOffRule(config: TimeOffConfig): CompilationRule;
73
- export {};
27
+ export declare const timeOffRuleDescriptor: import("../rule-descriptor.js").RuleDescriptor<"time-off", ({
28
+ priority: "LOW" | "MEDIUM" | "HIGH" | "MANDATORY";
29
+ startTime?: {
30
+ hours: number;
31
+ minutes: number;
32
+ } | undefined;
33
+ endTime?: {
34
+ hours: number;
35
+ minutes: number;
36
+ } | undefined;
37
+ } & import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">) & import("./scope.types.js").RequiredTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">>;
74
38
  //# sourceMappingURL=time-off.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"time-off.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/time-off.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,qBAAqB,CAAC;AAoBlF,QAAA,MAAM,aAAa;;;;;;;;;;mfAiBhB,CAAC;AAEJ;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CA4GxE"}
1
+ {"version":3,"file":"time-off.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/time-off.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AA0BzB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;mfAiBvB,CAAC;AAEJ;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;8LA+HhC,CAAC"}