dabke 0.82.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 (341) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +22 -24
  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 -21
  66. package/dist/cpsat/rules/index.d.ts.map +1 -1
  67. package/dist/cpsat/rules/index.js +30 -21
  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 +30 -0
  86. package/dist/cpsat/rules/max-days-week.d.ts.map +1 -0
  87. package/dist/cpsat/rules/max-days-week.js +83 -0
  88. package/dist/cpsat/rules/max-days-week.js.map +1 -0
  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 +21 -0
  110. package/dist/cpsat/rules/min-days-week.d.ts.map +1 -0
  111. package/dist/cpsat/rules/min-days-week.js +95 -0
  112. package/dist/cpsat/rules/min-days-week.js.map +1 -0
  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 +12 -0
  130. package/dist/cpsat/rules/must-assign.d.ts.map +1 -0
  131. package/dist/cpsat/rules/must-assign.js +54 -0
  132. package/dist/cpsat/rules/must-assign.js.map +1 -0
  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 -27
  162. package/dist/cpsat/rules/registry.d.ts.map +1 -1
  163. package/dist/cpsat/rules/registry.js +98 -31
  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 +93 -17
  174. package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
  175. package/dist/cpsat/rules/scope.types.d.ts +25 -12
  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 +15 -9
  226. package/dist/index.d.ts.map +1 -1
  227. package/dist/index.js +11 -4
  228. package/dist/index.js.map +1 -1
  229. package/dist/schedule/cost.d.ts +192 -0
  230. package/dist/schedule/cost.d.ts.map +1 -0
  231. package/dist/schedule/cost.js +151 -0
  232. package/dist/schedule/cost.js.map +1 -0
  233. package/dist/schedule/coverage.d.ts +114 -0
  234. package/dist/schedule/coverage.d.ts.map +1 -0
  235. package/dist/schedule/coverage.js +56 -0
  236. package/dist/schedule/coverage.js.map +1 -0
  237. package/dist/schedule/definition.d.ts +346 -0
  238. package/dist/schedule/definition.d.ts.map +1 -0
  239. package/dist/schedule/definition.js +668 -0
  240. package/dist/schedule/definition.js.map +1 -0
  241. package/dist/schedule/index.d.ts +67 -0
  242. package/dist/schedule/index.d.ts.map +1 -0
  243. package/dist/schedule/index.js +69 -0
  244. package/dist/schedule/index.js.map +1 -0
  245. package/dist/schedule/rules.d.ts +678 -0
  246. package/dist/schedule/rules.d.ts.map +1 -0
  247. package/dist/schedule/rules.js +554 -0
  248. package/dist/schedule/rules.js.map +1 -0
  249. package/dist/schedule/shift-patterns.d.ts +17 -0
  250. package/dist/schedule/shift-patterns.d.ts.map +1 -0
  251. package/dist/schedule/shift-patterns.js +24 -0
  252. package/dist/schedule/shift-patterns.js.map +1 -0
  253. package/dist/schedule/time-periods.d.ts +79 -0
  254. package/dist/schedule/time-periods.d.ts.map +1 -0
  255. package/dist/schedule/time-periods.js +101 -0
  256. package/dist/schedule/time-periods.js.map +1 -0
  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 -14
  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 -21
  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 +117 -0
  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 +122 -0
  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 +71 -0
  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 -56
  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 +92 -17
  309. package/src/cpsat/rules/scope.types.ts +32 -27
  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 +72 -15
  323. package/src/schedule/cost.ts +221 -0
  324. package/src/schedule/coverage.ts +164 -0
  325. package/src/schedule/definition.ts +1447 -0
  326. package/src/schedule/index.ts +132 -0
  327. package/src/schedule/rules.ts +1028 -0
  328. package/src/schedule/shift-patterns.ts +29 -0
  329. package/src/schedule/time-periods.ts +120 -0
  330. package/src/types.ts +114 -2
  331. package/dist/llms.d.ts +0 -2
  332. package/dist/llms.d.ts.map +0 -1
  333. package/dist/llms.js +0 -3
  334. package/dist/llms.js.map +0 -1
  335. package/dist/schedule.d.ts +0 -917
  336. package/dist/schedule.d.ts.map +0 -1
  337. package/dist/schedule.js +0 -1323
  338. package/dist/schedule.js.map +0 -1
  339. package/llms.txt +0 -758
  340. package/src/llms.ts +0 -3
  341. package/src/schedule.ts +0 -1960
@@ -0,0 +1,57 @@
1
+ import { MINUTES_PER_DAY, normalizeEndMinutes, timeOfDayToMinutes } from "../utils.js";
2
+ import { canAssignMemberToPattern, isPatternAvailableOnDay } from "./pattern-eligibility.js";
3
+ import { assignmentVar } from "./variables.js";
4
+ export function collectConcurrentAssignmentIntervals(day, targetMembers, shiftPatterns) {
5
+ const intervals = [];
6
+ for (const pattern of shiftPatterns) {
7
+ if (!isPatternAvailableOnDay(pattern, day))
8
+ continue;
9
+ const start = timeOfDayToMinutes(pattern.startTime);
10
+ const end = normalizeEndMinutes(start, timeOfDayToMinutes(pattern.endTime));
11
+ for (const member of targetMembers) {
12
+ if (!canAssignMemberToPattern(member, pattern))
13
+ continue;
14
+ intervals.push({
15
+ start,
16
+ end,
17
+ varName: assignmentVar(member.id, pattern.id, day.iso),
18
+ });
19
+ }
20
+ }
21
+ return intervals;
22
+ }
23
+ export function resolveConcurrentWindow(intervals, startMinutes, endMinutes) {
24
+ const start = startMinutes ?? 0;
25
+ if (endMinutes !== undefined) {
26
+ return { start, end: endMinutes };
27
+ }
28
+ const latestEnd = intervals.reduce((maxEnd, interval) => Math.max(maxEnd, interval.end), 0);
29
+ return { start, end: Math.max(MINUTES_PER_DAY, latestEnd) };
30
+ }
31
+ export function buildConcurrentAssignmentSegments(intervals, windowStart, windowEnd) {
32
+ const boundaries = new Set([windowStart, windowEnd]);
33
+ for (const interval of intervals) {
34
+ const start = Math.max(interval.start, windowStart);
35
+ const end = Math.min(interval.end, windowEnd);
36
+ if (start >= end)
37
+ continue;
38
+ boundaries.add(start);
39
+ boundaries.add(end);
40
+ }
41
+ const sortedBoundaries = [...boundaries].toSorted((left, right) => left - right);
42
+ const segments = [];
43
+ for (let index = 0; index < sortedBoundaries.length - 1; index++) {
44
+ const start = sortedBoundaries[index];
45
+ const end = sortedBoundaries[index + 1];
46
+ if (start === undefined || end === undefined || start >= end)
47
+ continue;
48
+ const varNames = intervals
49
+ .filter((interval) => interval.start < end && interval.end > start)
50
+ .map((interval) => interval.varName);
51
+ if (varNames.length === 0)
52
+ continue;
53
+ segments.push({ start, end, varNames });
54
+ }
55
+ return segments;
56
+ }
57
+ //# sourceMappingURL=concurrent-intervals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrent-intervals.js","sourceRoot":"","sources":["../../../src/cpsat/rules/concurrent-intervals.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { SchedulingMember, ShiftPattern } from "../types.js";
1
+ import type { SchedulingMember } from "../types.js";
2
2
  /** Returns the hourly rate for a member, or undefined if not hourly. */
3
3
  export declare function getHourlyRate(member: SchedulingMember): number | undefined;
4
4
  /** Returns salaried pay info, or undefined if not salaried. */
@@ -6,6 +6,4 @@ export declare function getSalariedPay(member: SchedulingMember): {
6
6
  annual: number;
7
7
  hoursPerWeek: number;
8
8
  } | undefined;
9
- /** Computes shift duration in minutes from a pattern. */
10
- export declare function patternDurationMinutes(pattern: ShiftPattern): number;
11
9
  //# sourceMappingURL=cost-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cost-utils.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/cost-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGlE,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,GACvB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAItD;AAED,yDAAyD;AACzD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAIpE"}
1
+ {"version":3,"file":"cost-utils.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/cost-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAC5B,MAAM,EAAE,gBAAgB,GACvB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAItD"}
@@ -1,4 +1,3 @@
1
- import { timeOfDayToMinutes, normalizeEndMinutes } from "../utils.js";
2
1
  /** Returns the hourly rate for a member, or undefined if not hourly. */
3
2
  export function getHourlyRate(member) {
4
3
  if (!member.pay)
@@ -15,10 +14,4 @@ export function getSalariedPay(member) {
15
14
  return member.pay;
16
15
  return undefined;
17
16
  }
18
- /** Computes shift duration in minutes from a pattern. */
19
- export function patternDurationMinutes(pattern) {
20
- const start = timeOfDayToMinutes(pattern.startTime);
21
- const end = normalizeEndMinutes(start, timeOfDayToMinutes(pattern.endTime));
22
- return end - start;
23
- }
24
17
  //# sourceMappingURL=cost-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cost-utils.js","sourceRoot":"","sources":["../../../src/cpsat/rules/cost-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEtE,wEAAwE;AACxE,MAAM,UAAU,aAAa,CAAC,MAAwB;IACpD,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,YAAY,IAAI,MAAM,CAAC,GAAG;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;IAC7D,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc,CAC5B,MAAwB;IAExB,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,QAAQ,IAAI,MAAM,CAAC,GAAG;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC;IAC9C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,sBAAsB,CAAC,OAAqB;IAC1D,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,mBAAmB,CAAC,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5E,OAAO,GAAG,GAAG,KAAK,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"cost-utils.js","sourceRoot":"","sources":["../../../src/cpsat/rules/cost-utils.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,MAAM,UAAU,aAAa,CAAC,MAAwB;IACpD,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,YAAY,IAAI,MAAM,CAAC,GAAG;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;IAC7D,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc,CAC5B,MAAwB;IAExB,IAAI,CAAC,MAAM,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAClC,IAAI,QAAQ,IAAI,MAAM,CAAC,GAAG;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC;IAC9C,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -1,19 +1,19 @@
1
1
  import * as z from "zod";
2
- import type { CompilationRule } from "../model-builder.js";
3
- declare const DayCostMultiplierSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
2
+ export declare const DayCostMultiplierSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
4
3
  factor: z.ZodNumber;
5
4
  }, 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>>>;
6
- /** Configuration for {@link createDayCostMultiplierRule}. */
5
+ /** Configuration for {@link dayCostMultiplierRuleDescriptor}. */
7
6
  export type DayCostMultiplierConfig = z.infer<typeof DayCostMultiplierSchema>;
8
7
  /**
9
- * Creates a day-based rate multiplier rule.
8
+ * Low-level descriptor for the `day-cost-multiplier` rule.
10
9
  *
11
- * Multiplies the base rate for assignments on matching days. The extra cost
12
- * above 1x is added as a penalty term (the base 1x is handled by `minimizeCost()`).
10
+ * @remarks
11
+ * This artifact always contributes to post-solve cost calculation. It only adds
12
+ * solver objective terms when `minimize-cost` is active.
13
13
  *
14
- * When `minimizeCost()` is not present, no solver terms are emitted,
15
- * but the `cost()` method still contributes to post-solve calculation.
14
+ * @category Rules
16
15
  */
17
- export declare function createDayCostMultiplierRule(config: DayCostMultiplierConfig): CompilationRule;
18
- export {};
16
+ export declare const dayCostMultiplierRuleDescriptor: import("../rule-descriptor.js").RuleDescriptor<"day-cost-multiplier", ({
17
+ factor: number;
18
+ } & import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">) & import("./scope.types.js").OptionalTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">>;
19
19
  //# sourceMappingURL=day-cost-multiplier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"day-cost-multiplier.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-multiplier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAc7E,QAAA,MAAM,uBAAuB;;mfAK8C,CAAC;AAE5E,6DAA6D;AAC7D,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE9E;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,uBAAuB,GAAG,eAAe,CA8E5F"}
1
+ {"version":3,"file":"day-cost-multiplier.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-multiplier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAezB,eAAO,MAAM,uBAAuB;;mfAKuC,CAAC;AAE5E,iEAAiE;AACjE,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAE9E;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B;;8LAkG1C,CAAC"}
@@ -1,93 +1,104 @@
1
1
  import * as z from "zod";
2
+ import { defineRuleDescriptor } from "../rule-descriptor.js";
2
3
  import { COST_CATEGORY } from "../cost.js";
3
- import { entityScope, timeScope, parseEntityScope, parseTimeScope, resolveMembersFromScope, resolveActiveDaysFromScope, } from "./scope.types.js";
4
- import { getHourlyRate, patternDurationMinutes } from "./cost-utils.js";
5
- const DayCostMultiplierSchema = z
4
+ import { entityScope, parseEntityScope, parseTimeScope, resolveActiveDaysFromScope, resolveMembersFromScope, timeScope, } from "./scope.types.js";
5
+ import { getHourlyRate } from "./cost-utils.js";
6
+ import { patternDurationMinutes } from "./pattern-time.js";
7
+ export const DayCostMultiplierSchema = z
6
8
  .object({
7
9
  factor: z.number().min(1),
8
10
  })
9
11
  .and(entityScope(["members", "roles", "skills"]))
10
12
  .and(timeScope(["dateRange", "specificDates", "dayOfWeek", "recurring"]));
11
13
  /**
12
- * Creates a day-based rate multiplier rule.
14
+ * Low-level descriptor for the `day-cost-multiplier` rule.
13
15
  *
14
- * Multiplies the base rate for assignments on matching days. The extra cost
15
- * above 1x is added as a penalty term (the base 1x is handled by `minimizeCost()`).
16
+ * @remarks
17
+ * This artifact always contributes to post-solve cost calculation. It only adds
18
+ * solver objective terms when `minimize-cost` is active.
16
19
  *
17
- * When `minimizeCost()` is not present, no solver terms are emitted,
18
- * but the `cost()` method still contributes to post-solve calculation.
20
+ * @category Rules
19
21
  */
20
- export function createDayCostMultiplierRule(config) {
21
- const parsed = DayCostMultiplierSchema.parse(config);
22
- const { factor } = parsed;
23
- const entityScopeValue = parseEntityScope(parsed);
24
- const timeScopeValue = parseTimeScope(parsed);
25
- return {
26
- compile(b) {
27
- if (!b.costContext?.active)
28
- return;
29
- if (factor <= 1)
30
- return;
31
- const targetMembers = resolveMembersFromScope(entityScopeValue, b.members);
32
- const activeDays = resolveActiveDaysFromScope(timeScopeValue, b.days);
33
- if (targetMembers.length === 0 || activeDays.length === 0)
34
- return;
35
- const { normalizationFactor } = b.costContext;
36
- const extraFactor = factor - 1;
37
- for (const emp of targetMembers) {
38
- const rate = getHourlyRate(emp);
39
- if (rate === undefined)
40
- continue;
41
- for (const pattern of b.shiftPatterns) {
42
- if (!b.canAssign(emp, pattern))
22
+ export const dayCostMultiplierRuleDescriptor = defineRuleDescriptor({
23
+ name: "day-cost-multiplier",
24
+ schema: DayCostMultiplierSchema,
25
+ compile(config) {
26
+ const { factor } = config;
27
+ const entityScopeValue = parseEntityScope(config);
28
+ const timeScopeValue = parseTimeScope(config);
29
+ const validation = {
30
+ strategy: "skip",
31
+ category: "no-meaningful-feedback",
32
+ rationale: factor <= 1
33
+ ? "A 1x multiplier does not change optimization or cost accounting."
34
+ : "Day cost multipliers only affect optimization when minimize-cost is active.",
35
+ };
36
+ const costArtifact = {
37
+ kind: "cost",
38
+ validation,
39
+ compileObjective(builder) {
40
+ if (!builder.costContext?.active || factor <= 1)
41
+ return;
42
+ const targetMembers = resolveMembersFromScope(entityScopeValue, builder.members);
43
+ const activeDays = resolveActiveDaysFromScope(timeScopeValue, builder.days);
44
+ if (targetMembers.length === 0 || activeDays.length === 0)
45
+ return;
46
+ const { normalizationFactor } = builder.costContext;
47
+ const extraFactor = factor - 1;
48
+ for (const member of targetMembers) {
49
+ const rate = getHourlyRate(member);
50
+ if (rate === undefined)
43
51
  continue;
44
- for (const day of activeDays) {
45
- if (!b.patternAvailableOnDay(pattern, day))
52
+ for (const pattern of builder.shiftPatterns) {
53
+ if (!builder.canAssign(member, pattern))
46
54
  continue;
47
- const duration = patternDurationMinutes(pattern);
48
- const extraCost = (rate * extraFactor * duration) / 60;
49
- const normalizedPenalty = extraCost / normalizationFactor;
50
- b.addPenalty(b.assignment(emp.id, pattern.id, day), Math.max(1, normalizedPenalty));
55
+ for (const day of activeDays) {
56
+ if (!builder.patternAvailableOnDay(pattern, day))
57
+ continue;
58
+ const duration = patternDurationMinutes(pattern);
59
+ const extraCost = (rate * extraFactor * duration) / 60;
60
+ const normalizedPenalty = extraCost / normalizationFactor;
61
+ builder.addPenalty(builder.assignment(member.id, pattern.id, day), Math.max(1, normalizedPenalty));
62
+ }
51
63
  }
52
64
  }
53
- }
54
- },
55
- cost(assignments, members, shiftPatterns) {
56
- if (factor <= 1)
57
- return { entries: [] };
58
- const empMap = new Map(members.map((e) => [e.id, e]));
59
- const patternMap = new Map(shiftPatterns.map((p) => [p.id, p]));
60
- // Resolve which days this rule applies to from assignments
61
- const allDays = [...new Set(assignments.map((a) => a.day))].toSorted();
62
- const activeDays = new Set(resolveActiveDaysFromScope(timeScopeValue, allDays));
63
- const targetEmpIds = new Set(resolveMembersFromScope(entityScopeValue, [...empMap.values()]).map((e) => e.id));
64
- const entries = [];
65
- const extraFactor = factor - 1;
66
- for (const a of assignments) {
67
- if (!activeDays.has(a.day))
68
- continue;
69
- if (!targetEmpIds.has(a.memberId))
70
- continue;
71
- const emp = empMap.get(a.memberId);
72
- if (!emp)
73
- continue;
74
- const rate = getHourlyRate(emp);
75
- if (rate === undefined)
76
- continue;
77
- const pattern = patternMap.get(a.shiftPatternId);
78
- if (!pattern)
79
- continue;
80
- const duration = patternDurationMinutes(pattern);
81
- const amount = (rate * extraFactor * duration) / 60;
82
- entries.push({
83
- memberId: a.memberId,
84
- day: a.day,
85
- category: COST_CATEGORY.PREMIUM,
86
- amount,
87
- });
88
- }
89
- return { entries };
90
- },
91
- };
92
- }
65
+ },
66
+ calculateCost(assignments, costContext) {
67
+ if (factor <= 1)
68
+ return { entries: [] };
69
+ const memberMap = new Map(costContext.members.map((member) => [member.id, member]));
70
+ const patternMap = new Map(costContext.shiftPatterns.map((pattern) => [pattern.id, pattern]));
71
+ const activeDays = new Set(resolveActiveDaysFromScope(timeScopeValue, [...costContext.days]).map((day) => day.iso));
72
+ const targetMemberIds = new Set(resolveMembersFromScope(entityScopeValue, [...costContext.members]).map((member) => member.id));
73
+ const extraFactor = factor - 1;
74
+ const entries = [];
75
+ for (const assignment of assignments) {
76
+ if (!activeDays.has(assignment.day) || !targetMemberIds.has(assignment.memberId))
77
+ continue;
78
+ const member = memberMap.get(assignment.memberId);
79
+ if (!member)
80
+ continue;
81
+ const rate = getHourlyRate(member);
82
+ if (rate === undefined)
83
+ continue;
84
+ const pattern = patternMap.get(assignment.shiftPatternId);
85
+ if (!pattern)
86
+ continue;
87
+ const duration = patternDurationMinutes(pattern);
88
+ entries.push({
89
+ memberId: assignment.memberId,
90
+ day: assignment.day,
91
+ category: COST_CATEGORY.PREMIUM,
92
+ amount: (rate * extraFactor * duration) / 60,
93
+ });
94
+ }
95
+ return { entries };
96
+ },
97
+ };
98
+ return {
99
+ rule: "day-cost-multiplier",
100
+ artifacts: [costArtifact],
101
+ };
102
+ },
103
+ });
93
104
  //# sourceMappingURL=day-cost-multiplier.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"day-cost-multiplier.js","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-multiplier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"day-cost-multiplier.js","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-multiplier.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,19 @@
1
1
  import * as z from "zod";
2
- import type { CompilationRule } from "../model-builder.js";
3
- declare const DayCostSurchargeSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
2
+ export declare const DayCostSurchargeSchema: z.ZodIntersection<z.ZodIntersection<z.ZodObject<{
4
3
  amountPerHour: z.ZodNumber;
5
4
  }, 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>>>;
6
- /** Configuration for {@link createDayCostSurchargeRule}. */
5
+ /** Configuration for {@link dayCostSurchargeRuleDescriptor}. */
7
6
  export type DayCostSurchargeConfig = z.infer<typeof DayCostSurchargeSchema>;
8
7
  /**
9
- * Creates a day-based flat surcharge rule.
8
+ * Low-level descriptor for the `day-cost-surcharge` rule.
10
9
  *
11
- * Adds a flat extra amount per hour for assignments on matching days,
12
- * independent of the member's base rate.
10
+ * @remarks
11
+ * This artifact always contributes to post-solve cost calculation. It only adds
12
+ * solver objective terms when `minimize-cost` is active.
13
13
  *
14
- * When `minimizeCost()` is not present, no solver terms are emitted,
15
- * but the `cost()` method still contributes to post-solve calculation.
14
+ * @category Rules
16
15
  */
17
- export declare function createDayCostSurchargeRule(config: DayCostSurchargeConfig): CompilationRule;
18
- export {};
16
+ export declare const dayCostSurchargeRuleDescriptor: import("../rule-descriptor.js").RuleDescriptor<"day-cost-surcharge", ({
17
+ amountPerHour: number;
18
+ } & import("./scope.types.js").EntityScopeType<"members" | "roles" | "skills">) & import("./scope.types.js").OptionalTimeScopeType<"dateRange" | "dayOfWeek" | "specificDates" | "recurring">>;
19
19
  //# sourceMappingURL=day-cost-surcharge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"day-cost-surcharge.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-surcharge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAc7E,QAAA,MAAM,sBAAsB;;mfAK+C,CAAC;AAE5E,4DAA4D;AAC5D,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,sBAAsB,GAAG,eAAe,CAkE1F"}
1
+ {"version":3,"file":"day-cost-surcharge.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-surcharge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAczB,eAAO,MAAM,sBAAsB;;mfAKwC,CAAC;AAE5E,gEAAgE;AAChE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B;;8LAwFzC,CAAC"}
@@ -1,80 +1,91 @@
1
1
  import * as z from "zod";
2
+ import { defineRuleDescriptor } from "../rule-descriptor.js";
2
3
  import { COST_CATEGORY } from "../cost.js";
3
- import { entityScope, timeScope, parseEntityScope, parseTimeScope, resolveMembersFromScope, resolveActiveDaysFromScope, } from "./scope.types.js";
4
- import { patternDurationMinutes } from "./cost-utils.js";
5
- const DayCostSurchargeSchema = z
4
+ import { entityScope, parseEntityScope, parseTimeScope, resolveActiveDaysFromScope, resolveMembersFromScope, timeScope, } from "./scope.types.js";
5
+ import { patternDurationMinutes } from "./pattern-time.js";
6
+ export const DayCostSurchargeSchema = z
6
7
  .object({
7
8
  amountPerHour: z.number().min(0),
8
9
  })
9
10
  .and(entityScope(["members", "roles", "skills"]))
10
11
  .and(timeScope(["dateRange", "specificDates", "dayOfWeek", "recurring"]));
11
12
  /**
12
- * Creates a day-based flat surcharge rule.
13
+ * Low-level descriptor for the `day-cost-surcharge` rule.
13
14
  *
14
- * Adds a flat extra amount per hour for assignments on matching days,
15
- * independent of the member's base rate.
15
+ * @remarks
16
+ * This artifact always contributes to post-solve cost calculation. It only adds
17
+ * solver objective terms when `minimize-cost` is active.
16
18
  *
17
- * When `minimizeCost()` is not present, no solver terms are emitted,
18
- * but the `cost()` method still contributes to post-solve calculation.
19
+ * @category Rules
19
20
  */
20
- export function createDayCostSurchargeRule(config) {
21
- const parsed = DayCostSurchargeSchema.parse(config);
22
- const { amountPerHour } = parsed;
23
- const entityScopeValue = parseEntityScope(parsed);
24
- const timeScopeValue = parseTimeScope(parsed);
25
- return {
26
- compile(b) {
27
- if (!b.costContext?.active)
28
- return;
29
- if (amountPerHour <= 0)
30
- return;
31
- const targetMembers = resolveMembersFromScope(entityScopeValue, b.members);
32
- const activeDays = resolveActiveDaysFromScope(timeScopeValue, b.days);
33
- if (targetMembers.length === 0 || activeDays.length === 0)
34
- return;
35
- const { normalizationFactor } = b.costContext;
36
- for (const emp of targetMembers) {
37
- for (const pattern of b.shiftPatterns) {
38
- if (!b.canAssign(emp, pattern))
39
- continue;
40
- for (const day of activeDays) {
41
- if (!b.patternAvailableOnDay(pattern, day))
21
+ export const dayCostSurchargeRuleDescriptor = defineRuleDescriptor({
22
+ name: "day-cost-surcharge",
23
+ schema: DayCostSurchargeSchema,
24
+ compile(config) {
25
+ const { amountPerHour } = config;
26
+ const entityScopeValue = parseEntityScope(config);
27
+ const timeScopeValue = parseTimeScope(config);
28
+ const validation = {
29
+ strategy: "skip",
30
+ category: "no-meaningful-feedback",
31
+ rationale: amountPerHour <= 0
32
+ ? "A zero surcharge does not change optimization or cost accounting."
33
+ : "Day cost surcharges only affect optimization when minimize-cost is active.",
34
+ };
35
+ const costArtifact = {
36
+ kind: "cost",
37
+ validation,
38
+ compileObjective(builder) {
39
+ if (!builder.costContext?.active || amountPerHour <= 0)
40
+ return;
41
+ const targetMembers = resolveMembersFromScope(entityScopeValue, builder.members);
42
+ const activeDays = resolveActiveDaysFromScope(timeScopeValue, builder.days);
43
+ if (targetMembers.length === 0 || activeDays.length === 0)
44
+ return;
45
+ const { normalizationFactor } = builder.costContext;
46
+ for (const member of targetMembers) {
47
+ for (const pattern of builder.shiftPatterns) {
48
+ if (!builder.canAssign(member, pattern))
42
49
  continue;
43
- const duration = patternDurationMinutes(pattern);
44
- const surcharge = (amountPerHour * duration) / 60;
45
- const normalizedPenalty = surcharge / normalizationFactor;
46
- b.addPenalty(b.assignment(emp.id, pattern.id, day), Math.max(1, normalizedPenalty));
50
+ for (const day of activeDays) {
51
+ if (!builder.patternAvailableOnDay(pattern, day))
52
+ continue;
53
+ const duration = patternDurationMinutes(pattern);
54
+ const surcharge = (amountPerHour * duration) / 60;
55
+ const normalizedPenalty = surcharge / normalizationFactor;
56
+ builder.addPenalty(builder.assignment(member.id, pattern.id, day), Math.max(1, normalizedPenalty));
57
+ }
47
58
  }
48
59
  }
49
- }
50
- },
51
- cost(assignments, members, shiftPatterns) {
52
- if (amountPerHour <= 0)
53
- return { entries: [] };
54
- const patternMap = new Map(shiftPatterns.map((p) => [p.id, p]));
55
- const allDays = [...new Set(assignments.map((a) => a.day))].toSorted();
56
- const activeDays = new Set(resolveActiveDaysFromScope(timeScopeValue, allDays));
57
- const targetEmpIds = new Set(resolveMembersFromScope(entityScopeValue, [...members]).map((e) => e.id));
58
- const entries = [];
59
- for (const a of assignments) {
60
- if (!activeDays.has(a.day))
61
- continue;
62
- if (!targetEmpIds.has(a.memberId))
63
- continue;
64
- const pattern = patternMap.get(a.shiftPatternId);
65
- if (!pattern)
66
- continue;
67
- const duration = patternDurationMinutes(pattern);
68
- const amount = (amountPerHour * duration) / 60;
69
- entries.push({
70
- memberId: a.memberId,
71
- day: a.day,
72
- category: COST_CATEGORY.PREMIUM,
73
- amount,
74
- });
75
- }
76
- return { entries };
77
- },
78
- };
79
- }
60
+ },
61
+ calculateCost(assignments, costContext) {
62
+ if (amountPerHour <= 0)
63
+ return { entries: [] };
64
+ const patternMap = new Map(costContext.shiftPatterns.map((pattern) => [pattern.id, pattern]));
65
+ const activeDays = new Set(resolveActiveDaysFromScope(timeScopeValue, [...costContext.days]).map((day) => day.iso));
66
+ const targetMemberIds = new Set(resolveMembersFromScope(entityScopeValue, [...costContext.members]).map((member) => member.id));
67
+ const entries = [];
68
+ for (const assignment of assignments) {
69
+ if (!activeDays.has(assignment.day) || !targetMemberIds.has(assignment.memberId))
70
+ continue;
71
+ const pattern = patternMap.get(assignment.shiftPatternId);
72
+ if (!pattern)
73
+ continue;
74
+ const duration = patternDurationMinutes(pattern);
75
+ entries.push({
76
+ memberId: assignment.memberId,
77
+ day: assignment.day,
78
+ category: COST_CATEGORY.PREMIUM,
79
+ amount: (amountPerHour * duration) / 60,
80
+ });
81
+ }
82
+ return { entries };
83
+ },
84
+ };
85
+ return {
86
+ rule: "day-cost-surcharge",
87
+ artifacts: [costArtifact],
88
+ };
89
+ },
90
+ });
80
91
  //# sourceMappingURL=day-cost-surcharge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"day-cost-surcharge.js","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-surcharge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"day-cost-surcharge.js","sourceRoot":"","sources":["../../../src/cpsat/rules/day-cost-surcharge.ts"],"names":[],"mappings":"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"}