dabke 0.81.1 → 0.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +45 -27
- package/dist/client.d.ts +20 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -1
- package/dist/client.js.map +1 -1
- package/dist/client.types.d.ts +9 -0
- package/dist/client.types.d.ts.map +1 -1
- package/dist/client.types.js +1 -0
- package/dist/client.types.js.map +1 -1
- package/dist/cpsat/model-builder.d.ts +9 -0
- package/dist/cpsat/model-builder.d.ts.map +1 -1
- package/dist/cpsat/model-builder.js +36 -34
- package/dist/cpsat/model-builder.js.map +1 -1
- package/dist/cpsat/response.d.ts +13 -1
- package/dist/cpsat/response.d.ts.map +1 -1
- package/dist/cpsat/response.js +4 -0
- package/dist/cpsat/response.js.map +1 -1
- package/dist/cpsat/rules/cost-utils.d.ts +11 -0
- package/dist/cpsat/rules/cost-utils.d.ts.map +1 -0
- package/dist/cpsat/rules/cost-utils.js +24 -0
- package/dist/cpsat/rules/cost-utils.js.map +1 -0
- package/dist/cpsat/rules/day-cost-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/day-cost-multiplier.js +3 -14
- package/dist/cpsat/rules/day-cost-multiplier.js.map +1 -1
- package/dist/cpsat/rules/day-cost-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/day-cost-surcharge.js +3 -7
- package/dist/cpsat/rules/day-cost-surcharge.js.map +1 -1
- package/dist/cpsat/rules/index.d.ts +3 -0
- package/dist/cpsat/rules/index.d.ts.map +1 -1
- package/dist/cpsat/rules/index.js +3 -0
- package/dist/cpsat/rules/index.js.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.js +16 -2
- package/dist/cpsat/rules/max-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/max-days-week.d.ts +44 -0
- package/dist/cpsat/rules/max-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/max-days-week.js +95 -0
- package/dist/cpsat/rules/max-days-week.js.map +1 -0
- package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-day.js +15 -2
- package/dist/cpsat/rules/max-hours-day.js.map +1 -1
- package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-week.js +16 -2
- package/dist/cpsat/rules/max-hours-week.js.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.js +15 -2
- package/dist/cpsat/rules/max-shifts-day.js.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.js +15 -2
- package/dist/cpsat/rules/min-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/min-days-week.d.ts +34 -0
- package/dist/cpsat/rules/min-days-week.d.ts.map +1 -0
- package/dist/cpsat/rules/min-days-week.js +84 -0
- package/dist/cpsat/rules/min-days-week.js.map +1 -0
- package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-day.js +15 -2
- package/dist/cpsat/rules/min-hours-day.js.map +1 -1
- package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-week.js +16 -2
- package/dist/cpsat/rules/min-hours-week.js.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.js +72 -2
- package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -1
- package/dist/cpsat/rules/minimize-cost.d.ts.map +1 -1
- package/dist/cpsat/rules/minimize-cost.js +2 -23
- package/dist/cpsat/rules/minimize-cost.js.map +1 -1
- package/dist/cpsat/rules/must-assign.d.ts +49 -0
- package/dist/cpsat/rules/must-assign.d.ts.map +1 -0
- package/dist/cpsat/rules/must-assign.js +86 -0
- package/dist/cpsat/rules/must-assign.js.map +1 -0
- package/dist/cpsat/rules/overtime-daily-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-daily-multiplier.js +1 -12
- package/dist/cpsat/rules/overtime-daily-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-daily-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-daily-surcharge.js +1 -5
- package/dist/cpsat/rules/overtime-daily-surcharge.js.map +1 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts +5 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-tiered-multiplier.js +1 -12
- package/dist/cpsat/rules/overtime-tiered-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-multiplier.js +1 -12
- package/dist/cpsat/rules/overtime-weekly-multiplier.js.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/overtime-weekly-surcharge.js +1 -5
- package/dist/cpsat/rules/overtime-weekly-surcharge.js.map +1 -1
- package/dist/cpsat/rules/registry.d.ts +28 -2
- package/dist/cpsat/rules/registry.d.ts.map +1 -1
- package/dist/cpsat/rules/registry.js +4 -1
- package/dist/cpsat/rules/registry.js.map +1 -1
- package/dist/cpsat/rules/resolver.js +2 -2
- package/dist/cpsat/rules/resolver.js.map +1 -1
- package/dist/cpsat/rules/rules.types.d.ts +3 -0
- package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.d.ts +18 -1
- package/dist/cpsat/rules/scope.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.js +59 -16
- package/dist/cpsat/rules/scope.types.js.map +1 -1
- package/dist/cpsat/rules/time-cost-surcharge.d.ts.map +1 -1
- package/dist/cpsat/rules/time-cost-surcharge.js +2 -1
- package/dist/cpsat/rules/time-cost-surcharge.js.map +1 -1
- package/dist/cpsat/rules/time-off.d.ts.map +1 -1
- package/dist/cpsat/rules/time-off.js +6 -3
- package/dist/cpsat/rules/time-off.js.map +1 -1
- package/dist/cpsat/semantic-time.d.ts +44 -42
- package/dist/cpsat/semantic-time.d.ts.map +1 -1
- package/dist/cpsat/semantic-time.js +64 -46
- package/dist/cpsat/semantic-time.js.map +1 -1
- package/dist/cpsat/types.d.ts +37 -27
- package/dist/cpsat/types.d.ts.map +1 -1
- package/dist/cpsat/utils.d.ts.map +1 -1
- package/dist/cpsat/utils.js +7 -12
- package/dist/cpsat/utils.js.map +1 -1
- package/dist/cpsat/validation-reporter.d.ts +10 -7
- package/dist/cpsat/validation-reporter.d.ts.map +1 -1
- package/dist/cpsat/validation-reporter.js +44 -72
- package/dist/cpsat/validation-reporter.js.map +1 -1
- package/dist/cpsat/validation.types.d.ts +54 -44
- package/dist/cpsat/validation.types.d.ts.map +1 -1
- package/dist/cpsat/validation.types.js +15 -10
- package/dist/cpsat/validation.types.js.map +1 -1
- package/dist/datetime.utils.d.ts +3 -203
- package/dist/datetime.utils.d.ts.map +1 -1
- package/dist/datetime.utils.js +1 -288
- package/dist/datetime.utils.js.map +1 -1
- package/dist/index.d.ts +14 -83
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -83
- package/dist/index.js.map +1 -1
- package/dist/schedule/cost.d.ts +204 -0
- package/dist/schedule/cost.d.ts.map +1 -0
- package/dist/schedule/cost.js +187 -0
- package/dist/schedule/cost.js.map +1 -0
- package/dist/schedule/coverage.d.ts +85 -0
- package/dist/schedule/coverage.d.ts.map +1 -0
- package/dist/schedule/coverage.js +33 -0
- package/dist/schedule/coverage.js.map +1 -0
- package/dist/schedule/definition.d.ts +227 -0
- package/dist/schedule/definition.d.ts.map +1 -0
- package/dist/schedule/definition.js +659 -0
- package/dist/schedule/definition.js.map +1 -0
- package/dist/schedule/index.d.ts +67 -0
- package/dist/schedule/index.d.ts.map +1 -0
- package/dist/schedule/index.js +69 -0
- package/dist/schedule/index.js.map +1 -0
- package/dist/schedule/rules.d.ts +353 -0
- package/dist/schedule/rules.d.ts.map +1 -0
- package/dist/schedule/rules.js +352 -0
- package/dist/schedule/rules.js.map +1 -0
- package/dist/schedule/shift-patterns.d.ts +34 -0
- package/dist/schedule/shift-patterns.d.ts.map +1 -0
- package/dist/schedule/shift-patterns.js +41 -0
- package/dist/schedule/shift-patterns.js.map +1 -0
- package/dist/schedule/time-periods.d.ts +69 -0
- package/dist/schedule/time-periods.d.ts.map +1 -0
- package/dist/schedule/time-periods.js +91 -0
- package/dist/schedule/time-periods.js.map +1 -0
- package/dist/types.d.ts +14 -78
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +4 -9
- package/solver/src/solver/app.py +1 -1
- package/solver/src/solver/solver.py +7 -4
- package/src/client.ts +6 -8
- package/src/client.types.ts +9 -0
- package/src/cpsat/model-builder.ts +44 -35
- package/src/cpsat/response.ts +13 -1
- package/src/cpsat/rules/cost-utils.ts +25 -0
- package/src/cpsat/rules/day-cost-multiplier.ts +3 -14
- package/src/cpsat/rules/day-cost-surcharge.ts +3 -8
- package/src/cpsat/rules/index.ts +3 -0
- package/src/cpsat/rules/max-consecutive-days.ts +17 -0
- package/src/cpsat/rules/max-days-week.ts +143 -0
- package/src/cpsat/rules/max-hours-day.ts +21 -1
- package/src/cpsat/rules/max-hours-week.ts +22 -1
- package/src/cpsat/rules/max-shifts-day.ts +21 -1
- package/src/cpsat/rules/min-consecutive-days.ts +16 -1
- package/src/cpsat/rules/min-days-week.ts +120 -0
- package/src/cpsat/rules/min-hours-day.ts +16 -1
- package/src/cpsat/rules/min-hours-week.ts +17 -1
- package/src/cpsat/rules/min-rest-between-shifts.ts +92 -2
- package/src/cpsat/rules/minimize-cost.ts +2 -29
- package/src/cpsat/rules/must-assign.ts +108 -0
- package/src/cpsat/rules/overtime-daily-multiplier.ts +1 -12
- package/src/cpsat/rules/overtime-daily-surcharge.ts +1 -6
- package/src/cpsat/rules/overtime-tiered-multiplier.ts +6 -13
- package/src/cpsat/rules/overtime-weekly-multiplier.ts +1 -12
- package/src/cpsat/rules/overtime-weekly-surcharge.ts +1 -6
- package/src/cpsat/rules/registry.ts +8 -2
- package/src/cpsat/rules/resolver.ts +2 -2
- package/src/cpsat/rules/rules.types.ts +3 -0
- package/src/cpsat/rules/scope.types.ts +73 -20
- package/src/cpsat/rules/time-cost-surcharge.ts +2 -1
- package/src/cpsat/rules/time-off.ts +6 -2
- package/src/cpsat/semantic-time.ts +115 -91
- package/src/cpsat/types.ts +37 -27
- package/src/cpsat/utils.ts +8 -12
- package/src/cpsat/validation-reporter.ts +51 -82
- package/src/cpsat/validation.types.ts +72 -47
- package/src/datetime.utils.ts +3 -334
- package/src/index.ts +35 -107
- package/src/schedule/cost.ts +242 -0
- package/src/schedule/coverage.ts +135 -0
- package/src/schedule/definition.ts +958 -0
- package/src/schedule/index.ts +112 -0
- package/src/schedule/rules.ts +529 -0
- package/src/schedule/shift-patterns.ts +46 -0
- package/src/schedule/time-periods.ts +110 -0
- package/src/types.ts +14 -88
- package/dist/errors.d.ts +0 -12
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -17
- package/dist/errors.js.map +0 -1
- package/dist/llms.d.ts +0 -2
- package/dist/llms.d.ts.map +0 -1
- package/dist/llms.js +0 -3
- package/dist/llms.js.map +0 -1
- package/dist/schedule.d.ts +0 -724
- package/dist/schedule.d.ts.map +0 -1
- package/dist/schedule.js +0 -899
- package/dist/schedule.js.map +0 -1
- package/dist/validation.d.ts +0 -105
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -130
- package/dist/validation.js.map +0 -1
- package/llms.txt +0 -925
- package/src/errors.ts +0 -17
- package/src/llms.ts +0 -3
- package/src/schedule.ts +0 -1419
- package/src/validation.ts +0 -188
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DayOfWeek, TimeOfDay } from "../types.js";
|
|
2
2
|
import type { CoverageRequirement, Priority } from "./types.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type ValidationGroup } from "./validation.types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Base definition for a semantic time period.
|
|
6
6
|
*/
|
|
@@ -21,7 +21,7 @@ export interface SemanticTimeDef {
|
|
|
21
21
|
*/
|
|
22
22
|
export interface SemanticTimeVariant extends SemanticTimeDef {
|
|
23
23
|
/** Restrict this entry to specific days of the week. */
|
|
24
|
-
dayOfWeek?: readonly DayOfWeek[];
|
|
24
|
+
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
25
25
|
/** Restrict this entry to specific dates (YYYY-MM-DD). */
|
|
26
26
|
dates?: string[];
|
|
27
27
|
}
|
|
@@ -38,54 +38,54 @@ interface SemanticCoverageRequirementBase<S extends string> {
|
|
|
38
38
|
targetCount: number;
|
|
39
39
|
priority?: Priority;
|
|
40
40
|
/** Scope this requirement to specific days of the week */
|
|
41
|
-
dayOfWeek?: DayOfWeek[];
|
|
41
|
+
dayOfWeek?: [DayOfWeek, ...DayOfWeek[]];
|
|
42
42
|
/** Scope this requirement to specific dates (YYYY-MM-DD) */
|
|
43
43
|
dates?: string[];
|
|
44
44
|
/**
|
|
45
|
-
* Override the auto-generated group
|
|
46
|
-
* If not provided, a
|
|
45
|
+
* Override the auto-generated group for validation reporting.
|
|
46
|
+
* If not provided, a group is auto-generated from the semantic time name,
|
|
47
47
|
* role/skills, and target count.
|
|
48
48
|
*/
|
|
49
|
-
|
|
49
|
+
group?: ValidationGroup;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
52
|
* Semantic coverage requiring specific roles, optionally filtered by skills.
|
|
53
53
|
*/
|
|
54
54
|
interface RoleBasedSemanticCoverageRequirement<S extends string> extends SemanticCoverageRequirementBase<S> {
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
56
|
+
* Role IDs that satisfy this coverage (OR logic).
|
|
57
57
|
* Must have at least one role.
|
|
58
58
|
*/
|
|
59
|
-
|
|
59
|
+
roleIds: [string, ...string[]];
|
|
60
60
|
/**
|
|
61
|
-
* Additional skill filter (AND logic with roles).
|
|
61
|
+
* Additional skill ID filter (AND logic with roles).
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
skillIds?: [string, ...string[]];
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
66
|
* Semantic coverage requiring specific skills only (any role).
|
|
67
67
|
*/
|
|
68
68
|
interface SkillBasedSemanticCoverageRequirement<S extends string> extends SemanticCoverageRequirementBase<S> {
|
|
69
|
-
|
|
69
|
+
roleIds?: never;
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
71
|
+
* Skill IDs required (ALL required, AND logic).
|
|
72
72
|
* Must have at least one skill.
|
|
73
73
|
*/
|
|
74
|
-
|
|
74
|
+
skillIds: [string, ...string[]];
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
77
|
* Coverage requirement that references a semantic time by name.
|
|
78
78
|
* Type-safe: S is constrained to known semantic time names.
|
|
79
79
|
*
|
|
80
80
|
* This is a discriminated union enforcing at compile time that at least
|
|
81
|
-
* one of `
|
|
81
|
+
* one of `roleIds` or `skillIds` must be provided.
|
|
82
82
|
*
|
|
83
83
|
* @remarks
|
|
84
84
|
* **Fields:**
|
|
85
85
|
* - `semanticTime` (required) — name of a defined semantic time
|
|
86
86
|
* - `targetCount` (required) — how many people are needed
|
|
87
|
-
* - `
|
|
88
|
-
* - `
|
|
87
|
+
* - `roleIds` — role IDs that satisfy this (OR logic); at least one of `roleIds`/`skillIds` required
|
|
88
|
+
* - `skillIds` — skill IDs required (AND logic); at least one of `roleIds`/`skillIds` required
|
|
89
89
|
* - `dayOfWeek` — scope to specific days of the week (e.g. `["monday", "tuesday"]`)
|
|
90
90
|
* - `dates` — scope to specific dates (`"YYYY-MM-DD"` strings)
|
|
91
91
|
* - `priority` — `"MANDATORY"` | `"HIGH"` | `"MEDIUM"` | `"LOW"`
|
|
@@ -96,15 +96,15 @@ interface SkillBasedSemanticCoverageRequirement<S extends string> extends Semant
|
|
|
96
96
|
*
|
|
97
97
|
* @example Weekday vs weekend (mutually exclusive dayOfWeek)
|
|
98
98
|
* ```typescript
|
|
99
|
-
* { semanticTime: "day_shift",
|
|
99
|
+
* { semanticTime: "day_shift", roleIds: ["nurse"], targetCount: 3,
|
|
100
100
|
* dayOfWeek: ["monday", "tuesday", "wednesday", "thursday", "friday"] },
|
|
101
|
-
* { semanticTime: "day_shift",
|
|
101
|
+
* { semanticTime: "day_shift", roleIds: ["nurse"], targetCount: 2,
|
|
102
102
|
* dayOfWeek: ["saturday", "sunday"] },
|
|
103
103
|
* ```
|
|
104
104
|
*
|
|
105
105
|
* @example Skill-based coverage (any role with the skill)
|
|
106
106
|
* ```typescript
|
|
107
|
-
* { semanticTime: "night_shift",
|
|
107
|
+
* { semanticTime: "night_shift", skillIds: ["charge_nurse"], targetCount: 1 },
|
|
108
108
|
* ```
|
|
109
109
|
*/
|
|
110
110
|
export type SemanticCoverageRequirement<S extends string> = RoleBasedSemanticCoverageRequirement<S> | SkillBasedSemanticCoverageRequirement<S>;
|
|
@@ -118,43 +118,43 @@ interface ConcreteCoverageRequirementBase {
|
|
|
118
118
|
targetCount: number;
|
|
119
119
|
priority?: Priority;
|
|
120
120
|
/**
|
|
121
|
-
* Override the auto-generated group
|
|
122
|
-
* If not provided, a
|
|
121
|
+
* Override the auto-generated group for validation reporting.
|
|
122
|
+
* If not provided, a group is auto-generated from the day, time range,
|
|
123
123
|
* role/skills, and target count.
|
|
124
124
|
*/
|
|
125
|
-
|
|
125
|
+
group?: ValidationGroup;
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Concrete coverage requiring specific roles, optionally filtered by skills.
|
|
129
129
|
*/
|
|
130
130
|
interface RoleBasedConcreteCoverageRequirement extends ConcreteCoverageRequirementBase {
|
|
131
131
|
/**
|
|
132
|
-
*
|
|
132
|
+
* Role IDs that satisfy this coverage (OR logic).
|
|
133
133
|
* Must have at least one role.
|
|
134
134
|
*/
|
|
135
|
-
|
|
135
|
+
roleIds: [string, ...string[]];
|
|
136
136
|
/**
|
|
137
|
-
* Additional skill filter (AND logic with roles).
|
|
137
|
+
* Additional skill ID filter (AND logic with roles).
|
|
138
138
|
*/
|
|
139
|
-
|
|
139
|
+
skillIds?: [string, ...string[]];
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* Concrete coverage requiring specific skills only (any role).
|
|
143
143
|
*/
|
|
144
144
|
interface SkillBasedConcreteCoverageRequirement extends ConcreteCoverageRequirementBase {
|
|
145
|
-
|
|
145
|
+
roleIds?: never;
|
|
146
146
|
/**
|
|
147
|
-
*
|
|
147
|
+
* Skill IDs required (ALL required, AND logic).
|
|
148
148
|
* Must have at least one skill.
|
|
149
149
|
*/
|
|
150
|
-
|
|
150
|
+
skillIds: [string, ...string[]];
|
|
151
151
|
}
|
|
152
152
|
/**
|
|
153
153
|
* Concrete coverage requirement with explicit day and times.
|
|
154
154
|
* Used for one-off requirements that don't fit a semantic time.
|
|
155
155
|
*
|
|
156
156
|
* This is a discriminated union enforcing at compile time that at least
|
|
157
|
-
* one of `
|
|
157
|
+
* one of `roleIds` or `skillIds` must be provided.
|
|
158
158
|
*/
|
|
159
159
|
export type ConcreteCoverageRequirement = RoleBasedConcreteCoverageRequirement | SkillBasedConcreteCoverageRequirement;
|
|
160
160
|
/**
|
|
@@ -173,12 +173,14 @@ export type ConcreteCoverageRequirement = RoleBasedConcreteCoverageRequirement |
|
|
|
173
173
|
* { count: 2, dates: ["2025-12-24"] },
|
|
174
174
|
* )
|
|
175
175
|
* ```
|
|
176
|
+
*
|
|
177
|
+
* @category Coverage
|
|
176
178
|
*/
|
|
177
179
|
export interface CoverageVariant {
|
|
178
180
|
/** Number of people needed. */
|
|
179
181
|
count: number;
|
|
180
182
|
/** Restrict this variant to specific days of the week. */
|
|
181
|
-
dayOfWeek?: readonly DayOfWeek[];
|
|
183
|
+
dayOfWeek?: readonly [DayOfWeek, ...DayOfWeek[]];
|
|
182
184
|
/** Restrict this variant to specific dates (YYYY-MM-DD). */
|
|
183
185
|
dates?: string[];
|
|
184
186
|
/** Defaults to `"MANDATORY"`. */
|
|
@@ -191,21 +193,21 @@ interface VariantCoverageRequirementBase<S extends string> {
|
|
|
191
193
|
semanticTime: S;
|
|
192
194
|
/** At least one variant is required. At most one may be unscoped (the default). */
|
|
193
195
|
variants: [CoverageVariant, ...CoverageVariant[]];
|
|
194
|
-
|
|
196
|
+
group?: ValidationGroup;
|
|
195
197
|
}
|
|
196
198
|
/**
|
|
197
199
|
* Variant coverage requiring specific roles, optionally filtered by skills.
|
|
198
200
|
*/
|
|
199
201
|
interface RoleBasedVariantCoverageRequirement<S extends string> extends VariantCoverageRequirementBase<S> {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
roleIds: [string, ...string[]];
|
|
203
|
+
skillIds?: [string, ...string[]];
|
|
202
204
|
}
|
|
203
205
|
/**
|
|
204
206
|
* Variant coverage requiring specific skills only (any role).
|
|
205
207
|
*/
|
|
206
208
|
interface SkillBasedVariantCoverageRequirement<S extends string> extends VariantCoverageRequirementBase<S> {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
roleIds?: never;
|
|
210
|
+
skillIds: [string, ...string[]];
|
|
209
211
|
}
|
|
210
212
|
/**
|
|
211
213
|
* Coverage requirement with day-specific count overrides.
|
|
@@ -220,7 +222,7 @@ interface SkillBasedVariantCoverageRequirement<S extends string> extends Variant
|
|
|
220
222
|
* @example Decrease from default on a specific date
|
|
221
223
|
* ```typescript
|
|
222
224
|
* {
|
|
223
|
-
* semanticTime: "peak_hours",
|
|
225
|
+
* semanticTime: "peak_hours", roleIds: ["agent"],
|
|
224
226
|
* variants: [
|
|
225
227
|
* { count: 4 }, // default
|
|
226
228
|
* { count: 2, dates: ["2025-12-24"] }, // Christmas Eve
|
|
@@ -278,10 +280,10 @@ export interface SemanticTimeContext<S extends string> {
|
|
|
278
280
|
* });
|
|
279
281
|
*
|
|
280
282
|
* const coverage = times.coverage([
|
|
281
|
-
* { semanticTime: "day_shift",
|
|
282
|
-
* { semanticTime: "morning_round",
|
|
283
|
+
* { semanticTime: "day_shift", roleIds: ["nurse"], targetCount: 3 },
|
|
284
|
+
* { semanticTime: "morning_round", skillIds: ["charge_nurse"], targetCount: 1, priority: "MANDATORY" },
|
|
283
285
|
* // Type error: "evening" is not a defined semantic time
|
|
284
|
-
* // { semanticTime: "evening",
|
|
286
|
+
* // { semanticTime: "evening", roleIds: ["nurse"], targetCount: 2 },
|
|
285
287
|
* ]);
|
|
286
288
|
* ```
|
|
287
289
|
*
|
|
@@ -298,9 +300,9 @@ export interface SemanticTimeContext<S extends string> {
|
|
|
298
300
|
* @example Mixed semantic and concrete coverage
|
|
299
301
|
* ```typescript
|
|
300
302
|
* const coverage = times.coverage([
|
|
301
|
-
* { semanticTime: "day_shift",
|
|
303
|
+
* { semanticTime: "day_shift", roleIds: ["nurse"], targetCount: 3 },
|
|
302
304
|
* // One-off event requiring extra staff
|
|
303
|
-
* { day: "2026-01-14", startTime: { hours: 8 }, endTime: { hours: 12 },
|
|
305
|
+
* { day: "2026-01-14", startTime: { hours: 8 }, endTime: { hours: 12 }, roleIds: ["nurse"], targetCount: 5 },
|
|
304
306
|
* ]);
|
|
305
307
|
* ```
|
|
306
308
|
*/
|
|
@@ -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;AAGxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,
|
|
1
|
+
{"version":3,"file":"semantic-time.d.ts","sourceRoot":"","sources":["../../src/cpsat/semantic-time.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { toDayOfWeekUTC } from "../datetime.utils.js";
|
|
2
2
|
import { parseDayString } from "./utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import { assertSafeKeySegment } from "./validation.types.js";
|
|
4
|
+
/** Validates and joins role/skill IDs into a key-safe segment. */
|
|
5
|
+
function safeRoleOrSkills(roleIds, skillIds) {
|
|
6
|
+
if (roleIds && roleIds.length > 0) {
|
|
7
|
+
for (const r of roleIds)
|
|
8
|
+
assertSafeKeySegment(r, "role ID");
|
|
9
|
+
return roleIds.join("/");
|
|
10
|
+
}
|
|
11
|
+
if (skillIds && skillIds.length > 0) {
|
|
12
|
+
for (const s of skillIds)
|
|
13
|
+
assertSafeKeySegment(s, "skill ID");
|
|
14
|
+
return skillIds.join("+");
|
|
15
|
+
}
|
|
16
|
+
throw new Error("At least one role or skill is required");
|
|
17
|
+
}
|
|
4
18
|
/**
|
|
5
19
|
* Type guard to check if a requirement is concrete (has explicit day/times).
|
|
6
20
|
*/
|
|
@@ -35,10 +49,10 @@ export function isSemanticCoverage(req) {
|
|
|
35
49
|
* });
|
|
36
50
|
*
|
|
37
51
|
* const coverage = times.coverage([
|
|
38
|
-
* { semanticTime: "day_shift",
|
|
39
|
-
* { semanticTime: "morning_round",
|
|
52
|
+
* { semanticTime: "day_shift", roleIds: ["nurse"], targetCount: 3 },
|
|
53
|
+
* { semanticTime: "morning_round", skillIds: ["charge_nurse"], targetCount: 1, priority: "MANDATORY" },
|
|
40
54
|
* // Type error: "evening" is not a defined semantic time
|
|
41
|
-
* // { semanticTime: "evening",
|
|
55
|
+
* // { semanticTime: "evening", roleIds: ["nurse"], targetCount: 2 },
|
|
42
56
|
* ]);
|
|
43
57
|
* ```
|
|
44
58
|
*
|
|
@@ -55,9 +69,9 @@ export function isSemanticCoverage(req) {
|
|
|
55
69
|
* @example Mixed semantic and concrete coverage
|
|
56
70
|
* ```typescript
|
|
57
71
|
* const coverage = times.coverage([
|
|
58
|
-
* { semanticTime: "day_shift",
|
|
72
|
+
* { semanticTime: "day_shift", roleIds: ["nurse"], targetCount: 3 },
|
|
59
73
|
* // One-off event requiring extra staff
|
|
60
|
-
* { day: "2026-01-14", startTime: { hours: 8 }, endTime: { hours: 12 },
|
|
74
|
+
* { day: "2026-01-14", startTime: { hours: 8 }, endTime: { hours: 12 }, roleIds: ["nurse"], targetCount: 5 },
|
|
61
75
|
* ]);
|
|
62
76
|
* ```
|
|
63
77
|
*/
|
|
@@ -76,18 +90,18 @@ export function defineSemanticTimes(defs) {
|
|
|
76
90
|
* Build a CoverageRequirement from resolved fields.
|
|
77
91
|
* Handles the discriminated union by checking which variant to construct.
|
|
78
92
|
*/
|
|
79
|
-
function buildCoverageRequirement(day, startTime, endTime,
|
|
80
|
-
const base = { day, startTime, endTime, targetCount, priority,
|
|
81
|
-
if (
|
|
93
|
+
function buildCoverageRequirement(day, startTime, endTime, roleIds, skillIds, targetCount, priority, group) {
|
|
94
|
+
const base = { day, startTime, endTime, targetCount, priority, group };
|
|
95
|
+
if (roleIds && roleIds.length > 0) {
|
|
82
96
|
// Role-based (with optional skills)
|
|
83
|
-
return
|
|
97
|
+
return skillIds && skillIds.length > 0 ? { ...base, roleIds, skillIds } : { ...base, roleIds };
|
|
84
98
|
}
|
|
85
|
-
else if (
|
|
99
|
+
else if (skillIds && skillIds.length > 0) {
|
|
86
100
|
// Skill-only
|
|
87
|
-
return { ...base,
|
|
101
|
+
return { ...base, skillIds };
|
|
88
102
|
}
|
|
89
103
|
// This shouldn't happen if input types are correct, but handle gracefully
|
|
90
|
-
throw new Error(`Coverage requirement for day "${day}" must have at least one of
|
|
104
|
+
throw new Error(`Coverage requirement for day "${day}" must have at least one of roleIds or skillIds`);
|
|
91
105
|
}
|
|
92
106
|
/**
|
|
93
107
|
* Resolve semantic coverage requirements to concrete requirements.
|
|
@@ -100,8 +114,8 @@ function resolveSemanticCoverage(defs, reqs, days) {
|
|
|
100
114
|
if (isConcreteCoverage(req)) {
|
|
101
115
|
// Concrete requirement - pass through if day is in horizon
|
|
102
116
|
if (daySet.has(req.day)) {
|
|
103
|
-
const
|
|
104
|
-
result.push(buildCoverageRequirement(req.day, req.startTime, req.endTime, req.
|
|
117
|
+
const defaultGroup = concreteCoverageGroup(req);
|
|
118
|
+
result.push(buildCoverageRequirement(req.day, req.startTime, req.endTime, req.roleIds, req.skillIds, req.targetCount, req.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
105
119
|
}
|
|
106
120
|
}
|
|
107
121
|
else if (isVariantCoverage(req)) {
|
|
@@ -110,7 +124,7 @@ function resolveSemanticCoverage(defs, reqs, days) {
|
|
|
110
124
|
if (!entry) {
|
|
111
125
|
throw new Error(`Unknown semantic time: ${req.semanticTime}`);
|
|
112
126
|
}
|
|
113
|
-
const
|
|
127
|
+
const defaultGroup = variantCoverageGroup(req);
|
|
114
128
|
for (const day of days) {
|
|
115
129
|
const resolved = resolveTimeForDay(entry, day);
|
|
116
130
|
if (!resolved)
|
|
@@ -118,7 +132,7 @@ function resolveSemanticCoverage(defs, reqs, days) {
|
|
|
118
132
|
const variant = resolveVariantForDay(req.variants, day);
|
|
119
133
|
if (!variant)
|
|
120
134
|
continue;
|
|
121
|
-
result.push(buildCoverageRequirement(day, resolved.startTime, resolved.endTime, req.
|
|
135
|
+
result.push(buildCoverageRequirement(day, resolved.startTime, resolved.endTime, req.roleIds, req.skillIds, variant.count, variant.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
122
136
|
}
|
|
123
137
|
}
|
|
124
138
|
else {
|
|
@@ -127,42 +141,46 @@ function resolveSemanticCoverage(defs, reqs, days) {
|
|
|
127
141
|
if (!entry) {
|
|
128
142
|
throw new Error(`Unknown semantic time: ${req.semanticTime}`);
|
|
129
143
|
}
|
|
130
|
-
const
|
|
144
|
+
const defaultGroup = semanticCoverageGroup(req);
|
|
131
145
|
const applicableDays = filterDays(days, req.dayOfWeek, req.dates);
|
|
132
146
|
for (const day of applicableDays) {
|
|
133
147
|
const resolved = resolveTimeForDay(entry, day);
|
|
134
148
|
if (resolved) {
|
|
135
|
-
result.push(buildCoverageRequirement(day, resolved.startTime, resolved.endTime, req.
|
|
149
|
+
result.push(buildCoverageRequirement(day, resolved.startTime, resolved.endTime, req.roleIds, req.skillIds, req.targetCount, req.priority ?? "MANDATORY", req.group ?? defaultGroup));
|
|
136
150
|
}
|
|
137
151
|
}
|
|
138
152
|
}
|
|
139
153
|
}
|
|
140
154
|
return result;
|
|
141
155
|
}
|
|
142
|
-
/**
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const base = `${req.targetCount}x ${roleOrSkills} during ${req.semanticTime}`;
|
|
149
|
-
// Add scope qualifier if scoped to specific days
|
|
156
|
+
/** Generates deterministic group for a semantic coverage requirement. */
|
|
157
|
+
function semanticCoverageGroup(req) {
|
|
158
|
+
assertSafeKeySegment(req.semanticTime, "semantic time name");
|
|
159
|
+
const roleOrSkills = safeRoleOrSkills(req.roleIds, req.skillIds);
|
|
160
|
+
const title = `${req.targetCount}x ${roleOrSkills} during ${req.semanticTime}`;
|
|
161
|
+
let scopeSuffix = "";
|
|
150
162
|
if (req.dayOfWeek && req.dayOfWeek.length > 0 && req.dayOfWeek.length < 7) {
|
|
151
|
-
|
|
163
|
+
scopeSuffix = `:dow:${req.dayOfWeek.toSorted().join(",")}`;
|
|
152
164
|
}
|
|
153
|
-
if (req.dates && req.dates.length > 0) {
|
|
154
|
-
|
|
165
|
+
else if (req.dates && req.dates.length > 0) {
|
|
166
|
+
scopeSuffix = `:dates:${req.dates.toSorted().join(",")}`;
|
|
155
167
|
}
|
|
156
|
-
|
|
168
|
+
const key = `coverage:${req.semanticTime}:${roleOrSkills}:${req.targetCount}${scopeSuffix}`;
|
|
169
|
+
const titleSuffix = scopeSuffix && req.dayOfWeek
|
|
170
|
+
? ` (${formatDaysScope(req.dayOfWeek)})`
|
|
171
|
+
: scopeSuffix && req.dates
|
|
172
|
+
? " (specific dates)"
|
|
173
|
+
: "";
|
|
174
|
+
return { key, title: `${title}${titleSuffix}` };
|
|
157
175
|
}
|
|
158
|
-
/**
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
176
|
+
/** Generates deterministic group for a variant coverage requirement. */
|
|
177
|
+
function variantCoverageGroup(req) {
|
|
178
|
+
assertSafeKeySegment(req.semanticTime, "semantic time name");
|
|
179
|
+
const roleOrSkills = safeRoleOrSkills(req.roleIds, req.skillIds);
|
|
180
|
+
return {
|
|
181
|
+
key: `coverage-variant:${req.semanticTime}:${roleOrSkills}`,
|
|
182
|
+
title: `${roleOrSkills} during ${req.semanticTime}`,
|
|
183
|
+
};
|
|
166
184
|
}
|
|
167
185
|
/**
|
|
168
186
|
* Resolve the most specific variant for a given day.
|
|
@@ -190,14 +208,14 @@ function resolveVariantForDay(variants, day) {
|
|
|
190
208
|
}
|
|
191
209
|
return dateMatch ?? dowMatch ?? defaultMatch;
|
|
192
210
|
}
|
|
193
|
-
/**
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
*/
|
|
197
|
-
function generateConcreteGroupKey(req) {
|
|
198
|
-
const roleOrSkills = req.roles?.join("/") ?? req.skills?.join("+") ?? "staff";
|
|
211
|
+
/** Generates deterministic group for a concrete coverage requirement. */
|
|
212
|
+
function concreteCoverageGroup(req) {
|
|
213
|
+
const roleOrSkills = safeRoleOrSkills(req.roleIds, req.skillIds);
|
|
199
214
|
const timeRange = `${formatTime(req.startTime)}-${formatTime(req.endTime)}`;
|
|
200
|
-
return
|
|
215
|
+
return {
|
|
216
|
+
key: `coverage-concrete:${req.day}:${roleOrSkills}:${req.targetCount}:${timeRange}`,
|
|
217
|
+
title: `${req.targetCount}x ${roleOrSkills} on ${req.day} ${timeRange}`,
|
|
218
|
+
};
|
|
201
219
|
}
|
|
202
220
|
/**
|
|
203
221
|
* Formats days of week for display in group keys.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-time.js","sourceRoot":"","sources":["../../src/cpsat/semantic-time.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"semantic-time.js","sourceRoot":"","sources":["../../src/cpsat/semantic-time.ts"],"names":[],"mappings":"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"}
|