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.
- package/CHANGELOG.md +21 -0
- package/README.md +22 -27
- package/dist/client.d.ts +39 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/client.schemas.d.ts +118 -18
- package/dist/client.schemas.d.ts.map +1 -1
- package/dist/client.schemas.js +110 -6
- package/dist/client.schemas.js.map +1 -1
- package/dist/client.types.d.ts +63 -7
- package/dist/client.types.d.ts.map +1 -1
- package/dist/client.types.js.map +1 -1
- package/dist/cpsat/cost.d.ts +5 -2
- package/dist/cpsat/cost.d.ts.map +1 -1
- package/dist/cpsat/cost.js +13 -6
- package/dist/cpsat/cost.js.map +1 -1
- package/dist/cpsat/model-builder.d.ts +42 -61
- package/dist/cpsat/model-builder.d.ts.map +1 -1
- package/dist/cpsat/model-builder.js +451 -56
- package/dist/cpsat/model-builder.js.map +1 -1
- package/dist/cpsat/response.d.ts +19 -7
- package/dist/cpsat/response.d.ts.map +1 -1
- package/dist/cpsat/response.js +48 -9
- package/dist/cpsat/response.js.map +1 -1
- package/dist/cpsat/rule-descriptor.d.ts +250 -0
- package/dist/cpsat/rule-descriptor.d.ts.map +1 -0
- package/dist/cpsat/rule-descriptor.js +51 -0
- package/dist/cpsat/rule-descriptor.js.map +1 -0
- package/dist/cpsat/rules/artifacts.d.ts +9 -0
- package/dist/cpsat/rules/artifacts.d.ts.map +1 -0
- package/dist/cpsat/rules/artifacts.js +31 -0
- package/dist/cpsat/rules/artifacts.js.map +1 -0
- package/dist/cpsat/rules/assign-together.d.ts +18 -20
- package/dist/cpsat/rules/assign-together.d.ts.map +1 -1
- package/dist/cpsat/rules/assign-together.js +90 -54
- package/dist/cpsat/rules/assign-together.js.map +1 -1
- package/dist/cpsat/rules/assigned-day.d.ts +12 -0
- package/dist/cpsat/rules/assigned-day.d.ts.map +1 -0
- package/dist/cpsat/rules/assigned-day.js +43 -0
- package/dist/cpsat/rules/assigned-day.js.map +1 -0
- package/dist/cpsat/rules/assignment-priority.d.ts +15 -29
- package/dist/cpsat/rules/assignment-priority.d.ts.map +1 -1
- package/dist/cpsat/rules/assignment-priority.js +47 -50
- package/dist/cpsat/rules/assignment-priority.js.map +1 -1
- package/dist/cpsat/rules/assignment-terms.d.ts +6 -0
- package/dist/cpsat/rules/assignment-terms.d.ts.map +1 -0
- package/dist/cpsat/rules/assignment-terms.js +19 -0
- package/dist/cpsat/rules/assignment-terms.js.map +1 -0
- package/dist/cpsat/rules/concurrent-intervals.d.ts +19 -0
- package/dist/cpsat/rules/concurrent-intervals.d.ts.map +1 -0
- package/dist/cpsat/rules/concurrent-intervals.js +57 -0
- package/dist/cpsat/rules/concurrent-intervals.js.map +1 -0
- package/dist/cpsat/rules/cost-utils.d.ts +1 -3
- package/dist/cpsat/rules/cost-utils.d.ts.map +1 -1
- package/dist/cpsat/rules/cost-utils.js +0 -7
- package/dist/cpsat/rules/cost-utils.js.map +1 -1
- package/dist/cpsat/rules/day-cost-multiplier.d.ts +10 -10
- package/dist/cpsat/rules/day-cost-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/day-cost-multiplier.js +88 -77
- package/dist/cpsat/rules/day-cost-multiplier.js.map +1 -1
- package/dist/cpsat/rules/day-cost-surcharge.d.ts +10 -10
- package/dist/cpsat/rules/day-cost-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/day-cost-surcharge.js +76 -65
- package/dist/cpsat/rules/day-cost-surcharge.js.map +1 -1
- package/dist/cpsat/rules/index.d.ts +30 -24
- package/dist/cpsat/rules/index.d.ts.map +1 -1
- package/dist/cpsat/rules/index.js +30 -24
- package/dist/cpsat/rules/index.js.map +1 -1
- package/dist/cpsat/rules/location-preference.d.ts +14 -21
- package/dist/cpsat/rules/location-preference.d.ts.map +1 -1
- package/dist/cpsat/rules/location-preference.js +45 -45
- package/dist/cpsat/rules/location-preference.js.map +1 -1
- package/dist/cpsat/rules/max-concurrent-assignments.d.ts +46 -0
- package/dist/cpsat/rules/max-concurrent-assignments.d.ts.map +1 -0
- package/dist/cpsat/rules/max-concurrent-assignments.js +121 -0
- package/dist/cpsat/rules/max-concurrent-assignments.js.map +1 -0
- package/dist/cpsat/rules/max-consecutive-days.d.ts +18 -17
- package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.js +67 -66
- package/dist/cpsat/rules/max-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/max-days-of-week-per-period.d.ts +45 -0
- package/dist/cpsat/rules/max-days-of-week-per-period.d.ts.map +1 -0
- package/dist/cpsat/rules/max-days-of-week-per-period.js +95 -0
- package/dist/cpsat/rules/max-days-of-week-per-period.js.map +1 -0
- package/dist/cpsat/rules/max-days-week.d.ts +17 -31
- package/dist/cpsat/rules/max-days-week.d.ts.map +1 -1
- package/dist/cpsat/rules/max-days-week.js +69 -81
- package/dist/cpsat/rules/max-days-week.js.map +1 -1
- package/dist/cpsat/rules/max-hours-day.d.ts +14 -31
- package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-day.js +56 -72
- package/dist/cpsat/rules/max-hours-day.js.map +1 -1
- package/dist/cpsat/rules/max-hours-week.d.ts +15 -31
- package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-week.js +60 -75
- package/dist/cpsat/rules/max-hours-week.js.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.d.ts +17 -33
- package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.js +57 -73
- package/dist/cpsat/rules/max-shifts-day.js.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.d.ts +18 -18
- package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.js +123 -94
- package/dist/cpsat/rules/min-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/min-days-of-week-per-period.d.ts +35 -0
- package/dist/cpsat/rules/min-days-of-week-per-period.d.ts.map +1 -0
- package/dist/cpsat/rules/min-days-of-week-per-period.js +108 -0
- package/dist/cpsat/rules/min-days-of-week-per-period.js.map +1 -0
- package/dist/cpsat/rules/min-days-week.d.ts +13 -26
- package/dist/cpsat/rules/min-days-week.d.ts.map +1 -1
- package/dist/cpsat/rules/min-days-week.js +85 -74
- package/dist/cpsat/rules/min-days-week.js.map +1 -1
- package/dist/cpsat/rules/min-hours-day.d.ts +14 -17
- package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-day.js +72 -54
- package/dist/cpsat/rules/min-hours-day.js.map +1 -1
- package/dist/cpsat/rules/min-hours-week.d.ts +15 -18
- package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-week.js +75 -57
- package/dist/cpsat/rules/min-hours-week.js.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts +14 -17
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.js +148 -138
- package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -1
- package/dist/cpsat/rules/minimize-cost.d.ts +2 -18
- package/dist/cpsat/rules/minimize-cost.d.ts.map +1 -1
- package/dist/cpsat/rules/minimize-cost.js +151 -163
- package/dist/cpsat/rules/minimize-cost.js.map +1 -1
- package/dist/cpsat/rules/must-assign.d.ts +5 -42
- package/dist/cpsat/rules/must-assign.d.ts.map +1 -1
- package/dist/cpsat/rules/must-assign.js +43 -75
- package/dist/cpsat/rules/must-assign.js.map +1 -1
- package/dist/cpsat/rules/overtime-daily-multiplier.d.ts +6 -10
- package/dist/cpsat/rules/overtime-daily-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-daily-multiplier.js +118 -112
- package/dist/cpsat/rules/overtime-daily-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-daily-surcharge.d.ts +6 -11
- package/dist/cpsat/rules/overtime-daily-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-daily-surcharge.js +104 -99
- package/dist/cpsat/rules/overtime-daily-surcharge.js.map +1 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts +9 -21
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.js +181 -199
- package/dist/cpsat/rules/overtime-tiered-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts +13 -12
- package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-multiplier.js +143 -143
- package/dist/cpsat/rules/overtime-weekly-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts +7 -11
- package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-surcharge.js +124 -119
- package/dist/cpsat/rules/overtime-weekly-surcharge.js.map +1 -1
- package/dist/cpsat/rules/pattern-eligibility.d.ts +6 -0
- package/dist/cpsat/rules/pattern-eligibility.d.ts.map +1 -0
- package/dist/cpsat/rules/pattern-eligibility.js +16 -0
- package/dist/cpsat/rules/pattern-eligibility.js.map +1 -0
- package/dist/cpsat/rules/pattern-time.d.ts +5 -0
- package/dist/cpsat/rules/pattern-time.d.ts.map +1 -0
- package/dist/cpsat/rules/pattern-time.js +20 -0
- package/dist/cpsat/rules/pattern-time.js.map +1 -0
- package/dist/cpsat/rules/registry.d.ts +217 -30
- package/dist/cpsat/rules/registry.d.ts.map +1 -1
- package/dist/cpsat/rules/registry.js +98 -34
- package/dist/cpsat/rules/registry.js.map +1 -1
- package/dist/cpsat/rules/resolver.d.ts +9 -7
- package/dist/cpsat/rules/resolver.d.ts.map +1 -1
- package/dist/cpsat/rules/resolver.js +19 -18
- package/dist/cpsat/rules/resolver.js.map +1 -1
- package/dist/cpsat/rules/role-preference.d.ts +24 -0
- package/dist/cpsat/rules/role-preference.d.ts.map +1 -0
- package/dist/cpsat/rules/role-preference.js +72 -0
- package/dist/cpsat/rules/role-preference.js.map +1 -0
- package/dist/cpsat/rules/rules.types.d.ts +90 -17
- package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.d.ts +24 -11
- package/dist/cpsat/rules/scope.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.js +14 -19
- package/dist/cpsat/rules/scope.types.js.map +1 -1
- package/dist/cpsat/rules/target-days-week.d.ts +31 -0
- package/dist/cpsat/rules/target-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/target-days-week.js +80 -0
- package/dist/cpsat/rules/target-days-week.js.map +1 -0
- package/dist/cpsat/rules/target-peak-concurrent-assignments.d.ts +33 -0
- package/dist/cpsat/rules/target-peak-concurrent-assignments.d.ts.map +1 -0
- package/dist/cpsat/rules/target-peak-concurrent-assignments.js +146 -0
- package/dist/cpsat/rules/target-peak-concurrent-assignments.js.map +1 -0
- package/dist/cpsat/rules/time-cost-surcharge.d.ts +15 -14
- package/dist/cpsat/rules/time-cost-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/time-cost-surcharge.js +82 -96
- package/dist/cpsat/rules/time-cost-surcharge.js.map +1 -1
- package/dist/cpsat/rules/time-off.d.ts +21 -57
- package/dist/cpsat/rules/time-off.d.ts.map +1 -1
- package/dist/cpsat/rules/time-off.js +114 -127
- package/dist/cpsat/rules/time-off.js.map +1 -1
- package/dist/cpsat/rules/variables.d.ts +4 -0
- package/dist/cpsat/rules/variables.d.ts.map +1 -0
- package/dist/cpsat/rules/variables.js +10 -0
- package/dist/cpsat/rules/variables.js.map +1 -0
- package/dist/cpsat/rules.d.ts +20 -3
- package/dist/cpsat/rules.d.ts.map +1 -1
- package/dist/cpsat/rules.js +19 -2
- package/dist/cpsat/rules.js.map +1 -1
- package/dist/cpsat/semantic-time.d.ts +7 -6
- package/dist/cpsat/semantic-time.d.ts.map +1 -1
- package/dist/cpsat/semantic-time.js +15 -28
- package/dist/cpsat/semantic-time.js.map +1 -1
- package/dist/cpsat/types.d.ts +47 -4
- package/dist/cpsat/types.d.ts.map +1 -1
- package/dist/cpsat/types.js +24 -1
- package/dist/cpsat/types.js.map +1 -1
- package/dist/cpsat/utils.d.ts +23 -6
- package/dist/cpsat/utils.d.ts.map +1 -1
- package/dist/cpsat/utils.js +76 -15
- package/dist/cpsat/utils.js.map +1 -1
- package/dist/cpsat/validation-reporter.d.ts +6 -2
- package/dist/cpsat/validation-reporter.d.ts.map +1 -1
- package/dist/cpsat/validation-reporter.js +122 -10
- package/dist/cpsat/validation-reporter.js.map +1 -1
- package/dist/cpsat/validation.types.d.ts +21 -10
- package/dist/cpsat/validation.types.d.ts.map +1 -1
- package/dist/datetime.utils.d.ts +7 -13
- package/dist/datetime.utils.d.ts.map +1 -1
- package/dist/datetime.utils.js +29 -36
- package/dist/datetime.utils.js.map +1 -1
- package/dist/index.d.ts +12 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/schedule/cost.d.ts +48 -60
- package/dist/schedule/cost.d.ts.map +1 -1
- package/dist/schedule/cost.js +15 -51
- package/dist/schedule/cost.js.map +1 -1
- package/dist/schedule/coverage.d.ts +57 -28
- package/dist/schedule/coverage.d.ts.map +1 -1
- package/dist/schedule/coverage.js +24 -1
- package/dist/schedule/coverage.js.map +1 -1
- package/dist/schedule/definition.d.ts +138 -19
- package/dist/schedule/definition.d.ts.map +1 -1
- package/dist/schedule/definition.js +99 -90
- package/dist/schedule/definition.js.map +1 -1
- package/dist/schedule/index.d.ts +4 -4
- package/dist/schedule/index.d.ts.map +1 -1
- package/dist/schedule/index.js +2 -2
- package/dist/schedule/index.js.map +1 -1
- package/dist/schedule/rules.d.ts +438 -113
- package/dist/schedule/rules.d.ts.map +1 -1
- package/dist/schedule/rules.js +310 -108
- package/dist/schedule/rules.js.map +1 -1
- package/dist/schedule/shift-patterns.d.ts +0 -17
- package/dist/schedule/shift-patterns.d.ts.map +1 -1
- package/dist/schedule/shift-patterns.js +0 -17
- package/dist/schedule/shift-patterns.js.map +1 -1
- package/dist/schedule/time-periods.d.ts +37 -27
- package/dist/schedule/time-periods.d.ts.map +1 -1
- package/dist/schedule/time-periods.js +37 -27
- package/dist/schedule/time-periods.js.map +1 -1
- package/dist/types.d.ts +67 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +64 -0
- package/dist/types.js.map +1 -1
- package/package.json +8 -9
- package/solver/src/solver/models.py +41 -4
- package/solver/src/solver/solver.py +546 -157
- package/solver/tests/test_solver.py +363 -7
- package/src/client.schemas.ts +127 -10
- package/src/client.ts +3 -0
- package/src/client.types.ts +73 -7
- package/src/cpsat/cost.ts +17 -7
- package/src/cpsat/model-builder.ts +614 -129
- package/src/cpsat/response.ts +57 -13
- package/src/cpsat/rule-descriptor.ts +311 -0
- package/src/cpsat/rules/artifacts.ts +56 -0
- package/src/cpsat/rules/assign-together.ts +104 -69
- package/src/cpsat/rules/assigned-day.ts +70 -0
- package/src/cpsat/rules/assignment-priority.ts +54 -58
- package/src/cpsat/rules/assignment-terms.ts +43 -0
- package/src/cpsat/rules/concurrent-intervals.ts +93 -0
- package/src/cpsat/rules/cost-utils.ts +1 -9
- package/src/cpsat/rules/day-cost-multiplier.ts +101 -81
- package/src/cpsat/rules/day-cost-surcharge.ts +91 -70
- package/src/cpsat/rules/index.ts +30 -24
- package/src/cpsat/rules/location-preference.ts +47 -52
- package/src/cpsat/rules/max-concurrent-assignments.ts +170 -0
- package/src/cpsat/rules/max-consecutive-days.ts +74 -91
- package/src/cpsat/rules/max-days-of-week-per-period.ts +127 -0
- package/src/cpsat/rules/max-days-week.ts +89 -115
- package/src/cpsat/rules/max-hours-day.ts +64 -84
- package/src/cpsat/rules/max-hours-week.ts +74 -90
- package/src/cpsat/rules/max-shifts-day.ts +65 -85
- package/src/cpsat/rules/min-consecutive-days.ts +161 -127
- package/src/cpsat/rules/min-days-of-week-per-period.ts +144 -0
- package/src/cpsat/rules/min-days-week.ts +93 -91
- package/src/cpsat/rules/min-hours-day.ts +79 -58
- package/src/cpsat/rules/min-hours-week.ts +87 -62
- package/src/cpsat/rules/min-rest-between-shifts.ts +191 -178
- package/src/cpsat/rules/minimize-cost.ts +175 -188
- package/src/cpsat/rules/must-assign.ts +44 -81
- package/src/cpsat/rules/overtime-daily-multiplier.ts +158 -140
- package/src/cpsat/rules/overtime-daily-surcharge.ts +141 -126
- package/src/cpsat/rules/overtime-tiered-multiplier.ts +234 -253
- package/src/cpsat/rules/overtime-weekly-multiplier.ts +183 -175
- package/src/cpsat/rules/overtime-weekly-surcharge.ts +161 -150
- package/src/cpsat/rules/pattern-eligibility.ts +26 -0
- package/src/cpsat/rules/pattern-time.ts +30 -0
- package/src/cpsat/rules/registry.ts +140 -62
- package/src/cpsat/rules/resolver.ts +58 -30
- package/src/cpsat/rules/role-preference.ts +92 -0
- package/src/cpsat/rules/rules.types.ts +89 -17
- package/src/cpsat/rules/scope.types.ts +31 -26
- package/src/cpsat/rules/target-days-week.ts +105 -0
- package/src/cpsat/rules/target-peak-concurrent-assignments.ts +212 -0
- package/src/cpsat/rules/time-cost-surcharge.ts +116 -122
- package/src/cpsat/rules/time-off.ts +154 -163
- package/src/cpsat/rules/variables.ts +11 -0
- package/src/cpsat/rules.ts +43 -17
- package/src/cpsat/semantic-time.ts +29 -43
- package/src/cpsat/types.ts +53 -4
- package/src/cpsat/utils.ts +92 -20
- package/src/cpsat/validation-reporter.ts +170 -19
- package/src/cpsat/validation.types.ts +22 -11
- package/src/datetime.utils.ts +45 -44
- package/src/index.ts +64 -12
- package/src/schedule/cost.ts +40 -61
- package/src/schedule/coverage.ts +57 -28
- package/src/schedule/definition.ts +565 -76
- package/src/schedule/index.ts +23 -3
- package/src/schedule/rules.ts +631 -132
- package/src/schedule/shift-patterns.ts +0 -17
- package/src/schedule/time-periods.ts +37 -27
- package/src/types.ts +114 -2
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
+
import { defineRuleDescriptor } from "../rule-descriptor.js";
|
|
2
3
|
import { normalizeEndMinutes, priorityToPenalty, timeOfDayToMinutes } from "../utils.js";
|
|
3
|
-
import { PrioritySchema, entityScope,
|
|
4
|
+
import { PrioritySchema, entityScope, parseEntityScope, parseTimeScope, requiredTimeScope, resolveActiveDaysFromScope, resolveMembersFromScope, ruleGroup, } from "./scope.types.js";
|
|
5
|
+
import { assignmentVar } from "./variables.js";
|
|
6
|
+
import { hardConstraint, reportValidation, softConstraint } from "./artifacts.js";
|
|
7
|
+
import { canAssignMemberToPattern, isPatternAvailableOnDay } from "./pattern-eligibility.js";
|
|
4
8
|
const timeOfDaySchema = z.object({
|
|
5
9
|
hours: z.number().int().min(0).max(23),
|
|
6
10
|
minutes: z.number().int().min(0).max(59),
|
|
7
11
|
});
|
|
8
|
-
const TimeOffSchema = z
|
|
12
|
+
export const TimeOffSchema = z
|
|
9
13
|
.object({
|
|
10
14
|
priority: PrioritySchema,
|
|
11
15
|
startTime: timeOfDaySchema.optional(),
|
|
@@ -21,136 +25,110 @@ const TimeOffSchema = z
|
|
|
21
25
|
message: "Both startTime and endTime must be provided together for partial day time-off",
|
|
22
26
|
});
|
|
23
27
|
/**
|
|
24
|
-
*
|
|
28
|
+
* Low-level descriptor for the `time-off` rule.
|
|
25
29
|
*
|
|
26
|
-
*
|
|
27
|
-
* (date ranges, specific dates, days of week, recurring periods).
|
|
28
|
-
* Optionally supports partial-day time-off with startTime/endTime.
|
|
29
|
-
*
|
|
30
|
-
* @param config - See {@link TimeOffConfig}
|
|
31
|
-
* @example Full day vacation
|
|
32
|
-
* ```ts
|
|
33
|
-
* createTimeOffRule({
|
|
34
|
-
* memberIds: ["alice"],
|
|
35
|
-
* dateRange: { start: "2024-02-01", end: "2024-02-05" },
|
|
36
|
-
* priority: "MANDATORY",
|
|
37
|
-
* });
|
|
38
|
-
* ```
|
|
39
|
-
*
|
|
40
|
-
* @example Every Wednesday afternoon off for students
|
|
41
|
-
* ```ts
|
|
42
|
-
* createTimeOffRule({
|
|
43
|
-
* roleIds: ["student"],
|
|
44
|
-
* dayOfWeek: ["wednesday"],
|
|
45
|
-
* startTime: { hours: 14, minutes: 0 },
|
|
46
|
-
* endTime: { hours: 23, minutes: 59 },
|
|
47
|
-
* priority: "MANDATORY",
|
|
48
|
-
* });
|
|
49
|
-
* ```
|
|
50
|
-
*
|
|
51
|
-
* @example Specific date, partial day
|
|
52
|
-
* ```ts
|
|
53
|
-
* createTimeOffRule({
|
|
54
|
-
* memberIds: ["bob"],
|
|
55
|
-
* specificDates: ["2024-03-15"],
|
|
56
|
-
* startTime: { hours: 16, minutes: 0 },
|
|
57
|
-
* endTime: { hours: 23, minutes: 59 },
|
|
58
|
-
* priority: "MANDATORY",
|
|
59
|
-
* });
|
|
60
|
-
* ```
|
|
30
|
+
* @category Rules
|
|
61
31
|
*/
|
|
62
|
-
export
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
32
|
+
export const timeOffRuleDescriptor = defineRuleDescriptor({
|
|
33
|
+
name: "time-off",
|
|
34
|
+
schema: TimeOffSchema,
|
|
35
|
+
compile(config, ctx) {
|
|
36
|
+
const { priority, startTime, endTime } = config;
|
|
37
|
+
const fullDayStart = { hours: 0, minutes: 0 };
|
|
38
|
+
const fullDayEnd = { hours: 23, minutes: 59 };
|
|
39
|
+
const timeWindowStart = startTime ?? fullDayStart;
|
|
40
|
+
const timeWindowEnd = endTime ?? fullDayEnd;
|
|
41
|
+
const entityScopeValue = parseEntityScope(config);
|
|
42
|
+
const timeScopeValue = parseTimeScope(config);
|
|
43
|
+
const group = ruleGroup("time-off", "Time off", entityScopeValue, timeScopeValue);
|
|
44
|
+
const targetMembers = resolveMembersFromScope(entityScopeValue, [...ctx.members]);
|
|
45
|
+
const activeDays = resolveActiveDaysFromScope(timeScopeValue, [...ctx.days]);
|
|
46
|
+
const timeWindowKey = formatTimeWindowKey(timeWindowStart, timeWindowEnd);
|
|
47
|
+
const constraintArtifacts = [];
|
|
48
|
+
for (const member of targetMembers) {
|
|
49
|
+
for (const day of activeDays) {
|
|
50
|
+
const overlappingVars = ctx.shiftPatterns
|
|
51
|
+
.filter((pattern) => canAssignMemberToPattern(member, pattern) &&
|
|
52
|
+
isPatternAvailableOnDay(pattern, day) &&
|
|
53
|
+
shiftOverlapsTimeWindow(pattern, timeWindowStart, timeWindowEnd))
|
|
54
|
+
.map((pattern) => assignmentVar(member.id, pattern.id, day.iso));
|
|
55
|
+
if (overlappingVars.length === 0)
|
|
56
|
+
continue;
|
|
57
|
+
const description = buildTimeOffDescription(member.id, day.iso, timeWindowStart, timeWindowEnd);
|
|
58
|
+
const context = { memberIds: [member.id], days: [day.iso] };
|
|
59
|
+
const constraintId = `time-off:${group.key}:${member.id}:${day.iso}:${timeWindowKey}`;
|
|
60
|
+
const terms = overlappingVars.map((varName) => ({ var: varName, coeff: 1 }));
|
|
61
|
+
if (priority === "MANDATORY") {
|
|
62
|
+
constraintArtifacts.push({
|
|
63
|
+
kind: "coverage-exclusion",
|
|
64
|
+
group,
|
|
65
|
+
memberId: member.id,
|
|
66
|
+
day: day.iso,
|
|
67
|
+
startTime: timeWindowStart,
|
|
68
|
+
endTime: timeWindowEnd,
|
|
69
|
+
});
|
|
70
|
+
constraintArtifacts.push(hardConstraint({
|
|
71
|
+
group,
|
|
72
|
+
description,
|
|
73
|
+
context,
|
|
74
|
+
validation: reportValidation(constraintId),
|
|
75
|
+
terms,
|
|
76
|
+
comparator: "<=",
|
|
77
|
+
targetValue: 0,
|
|
78
|
+
}));
|
|
109
79
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
for (const emp of targetMembers) {
|
|
123
|
-
for (const day of activeDays) {
|
|
124
|
-
const violated = assignments.some((a) => a.memberId === emp.id &&
|
|
125
|
-
a.day === day &&
|
|
126
|
-
assignmentOverlapsTimeWindow(a, timeWindowStart, timeWindowEnd));
|
|
127
|
-
if (violated) {
|
|
128
|
-
reporter.reportRuleViolation({
|
|
129
|
-
rule: "time-off",
|
|
130
|
-
message: `Time-off request for ${emp.id} on ${day} could not be honored`,
|
|
131
|
-
context: {
|
|
132
|
-
memberIds: [emp.id],
|
|
133
|
-
days: [day],
|
|
134
|
-
},
|
|
135
|
-
group,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
reporter.reportRulePassed({
|
|
140
|
-
rule: "time-off",
|
|
141
|
-
message: `Time-off honored for ${emp.id} on ${day}`,
|
|
142
|
-
context: {
|
|
143
|
-
memberIds: [emp.id],
|
|
144
|
-
days: [day],
|
|
145
|
-
},
|
|
146
|
-
group,
|
|
147
|
-
});
|
|
148
|
-
}
|
|
80
|
+
else {
|
|
81
|
+
constraintArtifacts.push(softConstraint({
|
|
82
|
+
group,
|
|
83
|
+
description,
|
|
84
|
+
context,
|
|
85
|
+
validation: reportValidation(),
|
|
86
|
+
terms,
|
|
87
|
+
comparator: "<=",
|
|
88
|
+
targetValue: 0,
|
|
89
|
+
penalty: priorityToPenalty(priority),
|
|
90
|
+
constraintId,
|
|
91
|
+
}));
|
|
149
92
|
}
|
|
150
93
|
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
94
|
+
}
|
|
95
|
+
const postSolveValidator = priority === "MANDATORY"
|
|
96
|
+
? []
|
|
97
|
+
: [
|
|
98
|
+
{
|
|
99
|
+
kind: "post-solve-feedback",
|
|
100
|
+
run(assignments, reporter, validationContext) {
|
|
101
|
+
const validatorMembers = resolveMembersFromScope(entityScopeValue, [
|
|
102
|
+
...validationContext.members,
|
|
103
|
+
]);
|
|
104
|
+
const validatorDays = resolveActiveDaysFromScope(timeScopeValue, [
|
|
105
|
+
...validationContext.days,
|
|
106
|
+
]);
|
|
107
|
+
for (const member of validatorMembers) {
|
|
108
|
+
for (const day of validatorDays) {
|
|
109
|
+
const violated = assignments.some((assignment) => assignment.memberId === member.id &&
|
|
110
|
+
assignment.day === day.iso &&
|
|
111
|
+
assignmentOverlapsTimeWindow(assignment, timeWindowStart, timeWindowEnd));
|
|
112
|
+
if (violated) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
reporter.reportRulePassed({
|
|
116
|
+
rule: "time-off",
|
|
117
|
+
message: `Time-off honored for ${member.id} on ${day.iso}`,
|
|
118
|
+
context: { memberIds: [member.id], days: [day.iso] },
|
|
119
|
+
group,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
return {
|
|
127
|
+
rule: "time-off",
|
|
128
|
+
artifacts: [...constraintArtifacts, ...postSolveValidator],
|
|
129
|
+
};
|
|
130
|
+
},
|
|
131
|
+
});
|
|
154
132
|
function shiftOverlapsTimeWindow(pattern, windowStart, windowEnd) {
|
|
155
133
|
const shiftStart = timeOfDayToMinutes(pattern.startTime);
|
|
156
134
|
const shiftEnd = normalizeEndMinutes(shiftStart, timeOfDayToMinutes(pattern.endTime));
|
|
@@ -165,4 +143,13 @@ function assignmentOverlapsTimeWindow(assignment, windowStart, windowEnd) {
|
|
|
165
143
|
const winEnd = normalizeEndMinutes(winStart, timeOfDayToMinutes(windowEnd));
|
|
166
144
|
return Math.max(assignStart, winStart) < Math.min(assignEnd, winEnd);
|
|
167
145
|
}
|
|
146
|
+
function buildTimeOffDescription(memberId, dayIso, windowStart, windowEnd) {
|
|
147
|
+
return `Time off for ${memberId} on ${dayIso} (${formatTimeWindowKey(windowStart, windowEnd)})`;
|
|
148
|
+
}
|
|
149
|
+
function formatTimeWindowKey(windowStart, windowEnd) {
|
|
150
|
+
return `${formatTimeOfDay(windowStart)}-${formatTimeOfDay(windowEnd)}`;
|
|
151
|
+
}
|
|
152
|
+
function formatTimeOfDay(time) {
|
|
153
|
+
return `${time.hours.toString().padStart(2, "0")}:${time.minutes.toString().padStart(2, "0")}`;
|
|
154
|
+
}
|
|
168
155
|
//# sourceMappingURL=time-off.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-off.js","sourceRoot":"","sources":["../../../src/cpsat/rules/time-off.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"time-off.js","sourceRoot":"","sources":["../../../src/cpsat/rules/time-off.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function assignmentVar(memberId: string, patternId: string, dayIso: string): string;
|
|
2
|
+
export declare function assignedDayVariableName(memberId: string, dayIso: string): string;
|
|
3
|
+
export declare function assignedDayStartVariableName(memberId: string, dayIso: string): string;
|
|
4
|
+
//# sourceMappingURL=variables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["../../../src/cpsat/rules/variables.ts"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEhF;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAErF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function assignmentVar(memberId, patternId, dayIso) {
|
|
2
|
+
return `assign:${memberId}:${patternId}:${dayIso}`;
|
|
3
|
+
}
|
|
4
|
+
export function assignedDayVariableName(memberId, dayIso) {
|
|
5
|
+
return `assigned_day_${memberId}_${dayIso}`;
|
|
6
|
+
}
|
|
7
|
+
export function assignedDayStartVariableName(memberId, dayIso) {
|
|
8
|
+
return `assigned_day_start_${memberId}_${dayIso}`;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variables.js","sourceRoot":"","sources":["../../../src/cpsat/rules/variables.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,SAAiB,EAAE,MAAc;IAC/E,OAAO,UAAU,QAAQ,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAAgB,EAAE,MAAc;IACtE,OAAO,gBAAgB,QAAQ,IAAI,MAAM,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,QAAgB,EAAE,MAAc;IAC3E,OAAO,sBAAsB,QAAQ,IAAI,MAAM,EAAE,CAAC;AACpD,CAAC"}
|
package/dist/cpsat/rules.d.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Low-level CP-SAT rule descriptor and registry APIs.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* These exports are intended for advanced consumers building custom rule
|
|
6
|
+
* registries or integrating directly with the descriptor layer underneath the
|
|
7
|
+
* high-level {@link schedule} helpers.
|
|
8
|
+
*
|
|
9
|
+
* Rules are the feedback unit. Validation groups summarize rule outcomes for
|
|
10
|
+
* presentation, while individual solver constraints remain implementation
|
|
11
|
+
* details. Descriptor compilation therefore emits artifacts that make the
|
|
12
|
+
* validation story explicit: reported constraints, pre-solve feedback,
|
|
13
|
+
* post-solve validators, cost contributions, and explicit skip strategies for
|
|
14
|
+
* scaffolding or artifacts with no meaningful validation feedback.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
export { assignTogetherRuleDescriptor, assignmentPriorityRuleDescriptor, locationPreferenceRuleDescriptor, maxConcurrentAssignmentsRuleDescriptor, maxConsecutiveDaysRuleDescriptor, maxHoursDayRuleDescriptor, maxHoursWeekRuleDescriptor, minConsecutiveDaysRuleDescriptor, minHoursDayRuleDescriptor, minHoursWeekRuleDescriptor, minRestBetweenShiftsRuleDescriptor, targetDaysWeekRuleDescriptor, targetPeakConcurrentAssignmentsRuleDescriptor, timeOffRuleDescriptor, } from "./rules/index.js";
|
|
19
|
+
export { assertValidCpsatRuleRegistry, builtInCpsatRuleRegistry, createCpsatRuleRegistry, } from "./rules/registry.js";
|
|
20
|
+
export type { AnyCpsatRuleConfigEntry, BuiltInCpsatRuleConfigRegistry, BuiltInCpsatRuleRegistry, CpsatRuleConfigByName, CpsatRuleConfigEntry, CpsatRuleConfigEntryFor, CpsatRuleName, CpsatRuleRegistry, } from "./rules/rules.types.js";
|
|
4
21
|
export { buildCpsatRules, getMemberIdsForScope, resolveRuleScopes } from "./rules/resolver.js";
|
|
5
22
|
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/cpsat/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/cpsat/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,gCAAgC,EAChC,sCAAsC,EACtC,gCAAgC,EAChC,yBAAyB,EACzB,0BAA0B,EAC1B,gCAAgC,EAChC,yBAAyB,EACzB,0BAA0B,EAC1B,kCAAkC,EAClC,4BAA4B,EAC5B,6CAA6C,EAC7C,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,uBAAuB,EACvB,8BAA8B,EAC9B,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/cpsat/rules.js
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Low-level CP-SAT rule descriptor and registry APIs.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* These exports are intended for advanced consumers building custom rule
|
|
6
|
+
* registries or integrating directly with the descriptor layer underneath the
|
|
7
|
+
* high-level {@link schedule} helpers.
|
|
8
|
+
*
|
|
9
|
+
* Rules are the feedback unit. Validation groups summarize rule outcomes for
|
|
10
|
+
* presentation, while individual solver constraints remain implementation
|
|
11
|
+
* details. Descriptor compilation therefore emits artifacts that make the
|
|
12
|
+
* validation story explicit: reported constraints, pre-solve feedback,
|
|
13
|
+
* post-solve validators, cost contributions, and explicit skip strategies for
|
|
14
|
+
* scaffolding or artifacts with no meaningful validation feedback.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
export { assignTogetherRuleDescriptor, assignmentPriorityRuleDescriptor, locationPreferenceRuleDescriptor, maxConcurrentAssignmentsRuleDescriptor, maxConsecutiveDaysRuleDescriptor, maxHoursDayRuleDescriptor, maxHoursWeekRuleDescriptor, minConsecutiveDaysRuleDescriptor, minHoursDayRuleDescriptor, minHoursWeekRuleDescriptor, minRestBetweenShiftsRuleDescriptor, targetDaysWeekRuleDescriptor, targetPeakConcurrentAssignmentsRuleDescriptor, timeOffRuleDescriptor, } from "./rules/index.js";
|
|
19
|
+
export { assertValidCpsatRuleRegistry, builtInCpsatRuleRegistry, createCpsatRuleRegistry, } from "./rules/registry.js";
|
|
3
20
|
export { buildCpsatRules, getMemberIdsForScope, resolveRuleScopes } from "./rules/resolver.js";
|
|
4
21
|
//# sourceMappingURL=rules.js.map
|
package/dist/cpsat/rules.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/cpsat/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/cpsat/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,gCAAgC,EAChC,sCAAsC,EACtC,gCAAgC,EAChC,yBAAyB,EACzB,0BAA0B,EAC1B,gCAAgC,EAChC,yBAAyB,EACzB,0BAA0B,EAC1B,kCAAkC,EAClC,4BAA4B,EAC5B,6CAA6C,EAC7C,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,4BAA4B,EAC5B,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DayOfWeek, TimeOfDay } from "../types.js";
|
|
1
|
+
import type { DateString, DayOfWeek, SchedulingDay, TimeOfDay } from "../types.js";
|
|
2
2
|
import type { CoverageRequirement, Priority } from "./types.js";
|
|
3
3
|
import { type ValidationGroup } from "./validation.types.js";
|
|
4
4
|
/**
|
|
@@ -23,7 +23,7 @@ export interface SemanticTimeVariant extends SemanticTimeDef {
|
|
|
23
23
|
/** Restrict this entry to specific days of the week. */
|
|
24
24
|
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
25
25
|
/** Restrict this entry to specific dates (YYYY-MM-DD). */
|
|
26
|
-
dates?:
|
|
26
|
+
dates?: DateString[];
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* A semantic time can be a simple definition (applies every day)
|
|
@@ -40,7 +40,7 @@ interface SemanticCoverageRequirementBase<S extends string> {
|
|
|
40
40
|
/** Scope this requirement to specific days of the week */
|
|
41
41
|
dayOfWeek?: [DayOfWeek, ...DayOfWeek[]];
|
|
42
42
|
/** Scope this requirement to specific dates (YYYY-MM-DD) */
|
|
43
|
-
dates?:
|
|
43
|
+
dates?: DateString[];
|
|
44
44
|
/**
|
|
45
45
|
* Override the auto-generated group for validation reporting.
|
|
46
46
|
* If not provided, a group is auto-generated from the semantic time name,
|
|
@@ -112,7 +112,7 @@ export type SemanticCoverageRequirement<S extends string> = RoleBasedSemanticCov
|
|
|
112
112
|
* Base fields shared by concrete coverage requirement variants.
|
|
113
113
|
*/
|
|
114
114
|
interface ConcreteCoverageRequirementBase {
|
|
115
|
-
day:
|
|
115
|
+
day: DateString;
|
|
116
116
|
startTime: TimeOfDay;
|
|
117
117
|
endTime: TimeOfDay;
|
|
118
118
|
targetCount: number;
|
|
@@ -160,6 +160,7 @@ export type ConcreteCoverageRequirement = RoleBasedConcreteCoverageRequirement |
|
|
|
160
160
|
/**
|
|
161
161
|
* A day-specific count within a variant {@link cover} call.
|
|
162
162
|
*
|
|
163
|
+
* @remarks
|
|
163
164
|
* Each variant specifies a count and optional day/date scope. During
|
|
164
165
|
* resolution, the most specific matching variant wins for each day
|
|
165
166
|
* (`dates` > `dayOfWeek` > default), mirroring {@link SemanticTimeVariant}.
|
|
@@ -182,7 +183,7 @@ export interface CoverageVariant {
|
|
|
182
183
|
/** Restrict this variant to specific days of the week. */
|
|
183
184
|
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
184
185
|
/** Restrict this variant to specific dates (YYYY-MM-DD). */
|
|
185
|
-
dates?:
|
|
186
|
+
dates?: DateString[];
|
|
186
187
|
/** Defaults to `"MANDATORY"`. */
|
|
187
188
|
priority?: Priority;
|
|
188
189
|
}
|
|
@@ -262,7 +263,7 @@ export interface SemanticTimeContext<S extends string> {
|
|
|
262
263
|
* Resolve all coverage requirements to concrete CoverageRequirement[]
|
|
263
264
|
* for the given days in the scheduling horizon.
|
|
264
265
|
*/
|
|
265
|
-
resolve(reqs: MixedCoverageRequirement<S>[], days:
|
|
266
|
+
resolve(reqs: MixedCoverageRequirement<S>[], days: SchedulingDay[]): CoverageRequirement[];
|
|
266
267
|
}
|
|
267
268
|
/**
|
|
268
269
|
* Define semantic times with type-safe names.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-time.d.ts","sourceRoot":"","sources":["../../src/cpsat/semantic-time.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"semantic-time.d.ts","sourceRoot":"","sources":["../../src/cpsat/semantic-time.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAenF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oCAAoC;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,kCAAkC;IAClC,OAAO,EAAE,SAAS,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,wDAAwD;IACxD,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IACjD,0DAA0D;IAC1D,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,eAAe,GAAG,mBAAmB,EAAE,CAAC;AAExE;;GAEG;AACH,UAAU,+BAA+B,CAAC,CAAC,SAAS,MAAM;IACxD,YAAY,EAAE,CAAC,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IACxC,4DAA4D;IAC5D,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;GAEG;AACH,UAAU,oCAAoC,CAC5C,CAAC,SAAS,MAAM,CAChB,SAAQ,+BAA+B,CAAC,CAAC,CAAC;IAC1C;;;OAGG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,qCAAqC,CAC7C,CAAC,SAAS,MAAM,CAChB,SAAQ,+BAA+B,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,MAAM,IACpD,oCAAoC,CAAC,CAAC,CAAC,GACvC,qCAAqC,CAAC,CAAC,CAAC,CAAC;AAE7C;;GAEG;AACH,UAAU,+BAA+B;IACvC,GAAG,EAAE,UAAU,CAAC;IAChB,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,SAAS,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;GAEG;AACH,UAAU,oCAAqC,SAAQ,+BAA+B;IACpF;;;OAGG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAC/B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,qCAAsC,SAAQ,+BAA+B;IACrF,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,2BAA2B,GACnC,oCAAoC,GACpC,qCAAqC,CAAC;AAM1C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC;IACjD,4DAA4D;IAC5D,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;GAEG;AACH,UAAU,8BAA8B,CAAC,CAAC,SAAS,MAAM;IACvD,YAAY,EAAE,CAAC,CAAC;IAChB,mFAAmF;IACnF,QAAQ,EAAE,CAAC,eAAe,EAAE,GAAG,eAAe,EAAE,CAAC,CAAC;IAClD,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;GAEG;AACH,UAAU,mCAAmC,CAC3C,CAAC,SAAS,MAAM,CAChB,SAAQ,8BAA8B,CAAC,CAAC,CAAC;IACzC,OAAO,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,oCAAoC,CAC5C,CAAC,SAAS,MAAM,CAChB,SAAQ,8BAA8B,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,MAAM,IACnD,mCAAmC,CAAC,CAAC,CAAC,GACtC,oCAAoC,CAAC,CAAC,CAAC,CAAC;AAM5C;;GAEG;AACH,MAAM,MAAM,wBAAwB,CAAC,CAAC,SAAS,MAAM,IACjD,2BAA2B,CAAC,CAAC,CAAC,GAC9B,2BAA2B,GAC3B,0BAA0B,CAAC,CAAC,CAAC,CAAC;AAElC;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,GAAG,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAC/B,GAAG,IAAI,2BAA2B,CAEpC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,EAChD,GAAG,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAC/B,GAAG,IAAI,0BAA0B,CAAC,CAAC,CAAC,CAEtC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,MAAM,EACjD,GAAG,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAC/B,GAAG,IAAI,2BAA2B,CAAC,CAAC,CAAC,CAEvC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC,SAAS,MAAM;IACnD,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAE5C;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,EAAE,GAAG,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;IAE7E;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,mBAAmB,EAAE,CAAC;CAC5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACnF,IAAI,EAAE,CAAC,GACN,mBAAmB,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAcvC"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { toDayOfWeekUTC } from "../datetime.utils.js";
|
|
2
|
-
import { parseDayString } from "./utils.js";
|
|
3
1
|
import { assertSafeKeySegment } from "./validation.types.js";
|
|
4
2
|
/** Validates and joins role/skill IDs into a key-safe segment. */
|
|
5
3
|
function safeRoleOrSkills(roleIds, skillIds) {
|
|
@@ -93,14 +91,11 @@ export function defineSemanticTimes(defs) {
|
|
|
93
91
|
function buildCoverageRequirement(day, startTime, endTime, roleIds, skillIds, targetCount, priority, group) {
|
|
94
92
|
const base = { day, startTime, endTime, targetCount, priority, group };
|
|
95
93
|
if (roleIds && roleIds.length > 0) {
|
|
96
|
-
// Role-based (with optional skills)
|
|
97
94
|
return skillIds && skillIds.length > 0 ? { ...base, roleIds, skillIds } : { ...base, roleIds };
|
|
98
95
|
}
|
|
99
96
|
else if (skillIds && skillIds.length > 0) {
|
|
100
|
-
// Skill-only
|
|
101
97
|
return { ...base, skillIds };
|
|
102
98
|
}
|
|
103
|
-
// This shouldn't happen if input types are correct, but handle gracefully
|
|
104
99
|
throw new Error(`Coverage requirement for day "${day}" must have at least one of roleIds or skillIds`);
|
|
105
100
|
}
|
|
106
101
|
/**
|
|
@@ -109,11 +104,11 @@ function buildCoverageRequirement(day, startTime, endTime, roleIds, skillIds, ta
|
|
|
109
104
|
*/
|
|
110
105
|
function resolveSemanticCoverage(defs, reqs, days) {
|
|
111
106
|
const result = [];
|
|
112
|
-
const
|
|
107
|
+
const dayIsoSet = new Set(days.map((d) => d.iso));
|
|
113
108
|
for (const req of reqs) {
|
|
114
109
|
if (isConcreteCoverage(req)) {
|
|
115
110
|
// Concrete requirement - pass through if day is in horizon
|
|
116
|
-
if (
|
|
111
|
+
if (dayIsoSet.has(req.day)) {
|
|
117
112
|
const defaultGroup = concreteCoverageGroup(req);
|
|
118
113
|
result.push(buildCoverageRequirement(req.day, req.startTime, req.endTime, req.roleIds, req.skillIds, req.targetCount, req.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
119
114
|
}
|
|
@@ -132,7 +127,7 @@ function resolveSemanticCoverage(defs, reqs, days) {
|
|
|
132
127
|
const variant = resolveVariantForDay(req.variants, day);
|
|
133
128
|
if (!variant)
|
|
134
129
|
continue;
|
|
135
|
-
result.push(buildCoverageRequirement(day, resolved.startTime, resolved.endTime, req.roleIds, req.skillIds, variant.count, variant.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
130
|
+
result.push(buildCoverageRequirement(day.iso, resolved.startTime, resolved.endTime, req.roleIds, req.skillIds, variant.count, variant.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
136
131
|
}
|
|
137
132
|
}
|
|
138
133
|
else {
|
|
@@ -146,7 +141,7 @@ function resolveSemanticCoverage(defs, reqs, days) {
|
|
|
146
141
|
for (const day of applicableDays) {
|
|
147
142
|
const resolved = resolveTimeForDay(entry, day);
|
|
148
143
|
if (resolved) {
|
|
149
|
-
result.push(buildCoverageRequirement(day, resolved.startTime, resolved.endTime, req.roleIds, req.skillIds, req.targetCount, req.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
144
|
+
result.push(buildCoverageRequirement(day.iso, resolved.startTime, resolved.endTime, req.roleIds, req.skillIds, req.targetCount, req.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
150
145
|
}
|
|
151
146
|
}
|
|
152
147
|
}
|
|
@@ -189,17 +184,15 @@ function variantCoverageGroup(req) {
|
|
|
189
184
|
* Returns null if no variant matches the day.
|
|
190
185
|
*/
|
|
191
186
|
function resolveVariantForDay(variants, day) {
|
|
192
|
-
const date = parseDayString(day);
|
|
193
|
-
const dayOfWeek = toDayOfWeekUTC(date);
|
|
194
187
|
let dateMatch = null;
|
|
195
188
|
let dowMatch = null;
|
|
196
189
|
let defaultMatch = null;
|
|
197
190
|
for (const variant of variants) {
|
|
198
|
-
if (variant.dates && variant.dates.includes(day)) {
|
|
191
|
+
if (variant.dates && variant.dates.includes(day.iso)) {
|
|
199
192
|
dateMatch = variant;
|
|
200
193
|
break;
|
|
201
194
|
}
|
|
202
|
-
if (variant.dayOfWeek && variant.dayOfWeek.includes(dayOfWeek)) {
|
|
195
|
+
if (variant.dayOfWeek && variant.dayOfWeek.includes(day.dayOfWeek)) {
|
|
203
196
|
dowMatch = variant;
|
|
204
197
|
}
|
|
205
198
|
if (!variant.dates && !variant.dayOfWeek) {
|
|
@@ -221,10 +214,11 @@ function concreteCoverageGroup(req) {
|
|
|
221
214
|
* Formats days of week for display in group keys.
|
|
222
215
|
*/
|
|
223
216
|
function formatDaysScope(days) {
|
|
224
|
-
|
|
217
|
+
const first = days[0];
|
|
218
|
+
if (!first)
|
|
225
219
|
return "";
|
|
226
220
|
if (days.length === 1)
|
|
227
|
-
return
|
|
221
|
+
return first;
|
|
228
222
|
// Check for common patterns
|
|
229
223
|
const weekdays = ["monday", "tuesday", "wednesday", "thursday", "friday"];
|
|
230
224
|
const weekend = ["saturday", "sunday"];
|
|
@@ -252,14 +246,12 @@ function formatTime(time) {
|
|
|
252
246
|
function filterDays(allDays, dayOfWeek, specificDates) {
|
|
253
247
|
let result = allDays;
|
|
254
248
|
if (specificDates && specificDates.length > 0) {
|
|
255
|
-
// If specific dates are provided, use only those (intersection with allDays)
|
|
256
249
|
const dateSet = new Set(specificDates);
|
|
257
|
-
result = result.filter((d) => dateSet.has(d));
|
|
250
|
+
result = result.filter((d) => dateSet.has(d.iso));
|
|
258
251
|
}
|
|
259
252
|
else if (dayOfWeek && dayOfWeek.length > 0) {
|
|
260
|
-
// Filter by day of week
|
|
261
253
|
const daySet = new Set(dayOfWeek);
|
|
262
|
-
result = result.filter((d) => daySet.has(
|
|
254
|
+
result = result.filter((d) => daySet.has(d.dayOfWeek));
|
|
263
255
|
}
|
|
264
256
|
return result;
|
|
265
257
|
}
|
|
@@ -268,29 +260,24 @@ function filterDays(allDays, dayOfWeek, specificDates) {
|
|
|
268
260
|
* Returns the most specific match: date-specific > day-of-week > default.
|
|
269
261
|
*/
|
|
270
262
|
function resolveTimeForDay(entry, day) {
|
|
271
|
-
// Simple definition - applies to all days
|
|
272
263
|
if (!Array.isArray(entry)) {
|
|
273
264
|
return entry;
|
|
274
265
|
}
|
|
275
|
-
const date = parseDayString(day);
|
|
276
|
-
const dayOfWeek = toDayOfWeekUTC(date);
|
|
277
|
-
// Find best match: date-specific first, then day-of-week, then default
|
|
278
266
|
let dateMatch = null;
|
|
279
267
|
let dowMatch = null;
|
|
280
268
|
let defaultMatch = null;
|
|
281
269
|
for (const variant of entry) {
|
|
282
|
-
if (variant.dates && variant.dates.includes(day)) {
|
|
270
|
+
if (variant.dates && variant.dates.includes(day.iso)) {
|
|
283
271
|
dateMatch = variant;
|
|
284
|
-
break;
|
|
272
|
+
break;
|
|
285
273
|
}
|
|
286
|
-
if (variant.dayOfWeek && variant.dayOfWeek.includes(dayOfWeek)) {
|
|
274
|
+
if (variant.dayOfWeek && variant.dayOfWeek.includes(day.dayOfWeek)) {
|
|
287
275
|
dowMatch = variant;
|
|
288
276
|
}
|
|
289
277
|
if (!variant.dates && !variant.dayOfWeek) {
|
|
290
278
|
defaultMatch = variant;
|
|
291
279
|
}
|
|
292
280
|
}
|
|
293
|
-
|
|
294
|
-
return match ?? null;
|
|
281
|
+
return dateMatch ?? dowMatch ?? defaultMatch ?? null;
|
|
295
282
|
}
|
|
296
283
|
//# sourceMappingURL=semantic-time.js.map
|