dabke 0.79.0 → 0.81.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 +67 -0
- package/README.md +6 -4
- package/dist/client.types.d.ts +58 -0
- package/dist/client.types.d.ts.map +1 -1
- package/dist/client.types.js.map +1 -1
- package/dist/cpsat/cost.d.ts +65 -0
- package/dist/cpsat/cost.d.ts.map +1 -0
- package/dist/cpsat/cost.js +77 -0
- package/dist/cpsat/cost.js.map +1 -0
- package/dist/cpsat/model-builder.d.ts +61 -16
- package/dist/cpsat/model-builder.d.ts.map +1 -1
- package/dist/cpsat/model-builder.js +76 -76
- package/dist/cpsat/model-builder.js.map +1 -1
- package/dist/cpsat/response.d.ts +19 -10
- package/dist/cpsat/response.d.ts.map +1 -1
- package/dist/cpsat/response.js +10 -10
- package/dist/cpsat/response.js.map +1 -1
- package/dist/cpsat/rules/assign-together.d.ts +10 -3
- package/dist/cpsat/rules/assign-together.d.ts.map +1 -1
- package/dist/cpsat/rules/assign-together.js +18 -21
- package/dist/cpsat/rules/assign-together.js.map +1 -1
- package/dist/cpsat/rules/assignment-priority.d.ts +38 -0
- package/dist/cpsat/rules/assignment-priority.d.ts.map +1 -0
- package/dist/cpsat/rules/assignment-priority.js +59 -0
- package/dist/cpsat/rules/assignment-priority.js.map +1 -0
- package/dist/cpsat/rules/day-cost-multiplier.d.ts +19 -0
- package/dist/cpsat/rules/day-cost-multiplier.d.ts.map +1 -0
- package/dist/cpsat/rules/day-cost-multiplier.js +104 -0
- package/dist/cpsat/rules/day-cost-multiplier.js.map +1 -0
- package/dist/cpsat/rules/day-cost-surcharge.d.ts +19 -0
- package/dist/cpsat/rules/day-cost-surcharge.d.ts.map +1 -0
- package/dist/cpsat/rules/day-cost-surcharge.js +84 -0
- package/dist/cpsat/rules/day-cost-surcharge.js.map +1 -0
- package/dist/cpsat/rules/index.d.ts +10 -1
- package/dist/cpsat/rules/index.d.ts.map +1 -1
- package/dist/cpsat/rules/index.js +10 -1
- package/dist/cpsat/rules/index.js.map +1 -1
- package/dist/cpsat/rules/location-preference.d.ts +14 -12
- package/dist/cpsat/rules/location-preference.d.ts.map +1 -1
- package/dist/cpsat/rules/location-preference.js +19 -22
- package/dist/cpsat/rules/location-preference.js.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.d.ts +13 -14
- package/dist/cpsat/rules/max-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/max-consecutive-days.js +13 -19
- package/dist/cpsat/rules/max-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/max-hours-day.d.ts +13 -29
- package/dist/cpsat/rules/max-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-day.js +15 -103
- package/dist/cpsat/rules/max-hours-day.js.map +1 -1
- package/dist/cpsat/rules/max-hours-week.d.ts +15 -35
- package/dist/cpsat/rules/max-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/max-hours-week.js +15 -111
- package/dist/cpsat/rules/max-hours-week.js.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.d.ts +15 -40
- package/dist/cpsat/rules/max-shifts-day.d.ts.map +1 -1
- package/dist/cpsat/rules/max-shifts-day.js +17 -114
- package/dist/cpsat/rules/max-shifts-day.js.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.d.ts +13 -14
- package/dist/cpsat/rules/min-consecutive-days.d.ts.map +1 -1
- package/dist/cpsat/rules/min-consecutive-days.js +13 -19
- package/dist/cpsat/rules/min-consecutive-days.js.map +1 -1
- package/dist/cpsat/rules/min-hours-day.d.ts +13 -14
- package/dist/cpsat/rules/min-hours-day.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-day.js +13 -19
- package/dist/cpsat/rules/min-hours-day.js.map +1 -1
- package/dist/cpsat/rules/min-hours-week.d.ts +14 -14
- package/dist/cpsat/rules/min-hours-week.d.ts.map +1 -1
- package/dist/cpsat/rules/min-hours-week.js +12 -21
- package/dist/cpsat/rules/min-hours-week.js.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts +14 -15
- package/dist/cpsat/rules/min-rest-between-shifts.d.ts.map +1 -1
- package/dist/cpsat/rules/min-rest-between-shifts.js +13 -19
- package/dist/cpsat/rules/min-rest-between-shifts.js.map +1 -1
- package/dist/cpsat/rules/minimize-cost.d.ts +23 -0
- package/dist/cpsat/rules/minimize-cost.d.ts.map +1 -0
- package/dist/cpsat/rules/minimize-cost.js +206 -0
- package/dist/cpsat/rules/minimize-cost.js.map +1 -0
- package/dist/cpsat/rules/overtime-daily-multiplier.d.ts +16 -0
- package/dist/cpsat/rules/overtime-daily-multiplier.d.ts.map +1 -0
- package/dist/cpsat/rules/overtime-daily-multiplier.js +142 -0
- package/dist/cpsat/rules/overtime-daily-multiplier.js.map +1 -0
- package/dist/cpsat/rules/overtime-daily-surcharge.d.ts +17 -0
- package/dist/cpsat/rules/overtime-daily-surcharge.d.ts.map +1 -0
- package/dist/cpsat/rules/overtime-daily-surcharge.js +120 -0
- package/dist/cpsat/rules/overtime-daily-surcharge.js.map +1 -0
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts +37 -0
- package/dist/cpsat/rules/overtime-tiered-multiplier.d.ts.map +1 -0
- package/dist/cpsat/rules/overtime-tiered-multiplier.js +243 -0
- package/dist/cpsat/rules/overtime-tiered-multiplier.js.map +1 -0
- package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts +23 -0
- package/dist/cpsat/rules/overtime-weekly-multiplier.d.ts.map +1 -0
- package/dist/cpsat/rules/overtime-weekly-multiplier.js +178 -0
- package/dist/cpsat/rules/overtime-weekly-multiplier.js.map +1 -0
- package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts +18 -0
- package/dist/cpsat/rules/overtime-weekly-surcharge.d.ts.map +1 -0
- package/dist/cpsat/rules/overtime-weekly-surcharge.js +140 -0
- package/dist/cpsat/rules/overtime-weekly-surcharge.js.map +1 -0
- package/dist/cpsat/rules/registry.d.ts.map +1 -1
- package/dist/cpsat/rules/registry.js +11 -2
- package/dist/cpsat/rules/registry.js.map +1 -1
- package/dist/cpsat/rules/resolver.d.ts +6 -11
- package/dist/cpsat/rules/resolver.d.ts.map +1 -1
- package/dist/cpsat/rules/resolver.js +82 -51
- package/dist/cpsat/rules/resolver.js.map +1 -1
- package/dist/cpsat/rules/rules.types.d.ts +31 -5
- package/dist/cpsat/rules/rules.types.d.ts.map +1 -1
- package/dist/cpsat/rules/scope.types.d.ts +274 -0
- package/dist/cpsat/rules/scope.types.d.ts.map +1 -0
- package/dist/cpsat/rules/scope.types.js +337 -0
- package/dist/cpsat/rules/scope.types.js.map +1 -0
- package/dist/cpsat/rules/time-cost-surcharge.d.ts +29 -0
- package/dist/cpsat/rules/time-cost-surcharge.d.ts.map +1 -0
- package/dist/cpsat/rules/time-cost-surcharge.js +124 -0
- package/dist/cpsat/rules/time-cost-surcharge.js.map +1 -0
- package/dist/cpsat/rules/time-off.d.ts +24 -28
- package/dist/cpsat/rules/time-off.d.ts.map +1 -1
- package/dist/cpsat/rules/time-off.js +24 -120
- package/dist/cpsat/rules/time-off.js.map +1 -1
- package/dist/cpsat/rules.d.ts +2 -2
- package/dist/cpsat/rules.d.ts.map +1 -1
- package/dist/cpsat/rules.js +2 -2
- package/dist/cpsat/rules.js.map +1 -1
- package/dist/cpsat/semantic-time.d.ts +141 -30
- package/dist/cpsat/semantic-time.d.ts.map +1 -1
- package/dist/cpsat/semantic-time.js +92 -34
- package/dist/cpsat/semantic-time.js.map +1 -1
- package/dist/cpsat/types.d.ts +73 -36
- package/dist/cpsat/types.d.ts.map +1 -1
- package/dist/cpsat/utils.d.ts +16 -2
- package/dist/cpsat/utils.d.ts.map +1 -1
- package/dist/cpsat/utils.js +27 -2
- package/dist/cpsat/utils.js.map +1 -1
- package/dist/cpsat/validation-reporter.js +14 -14
- package/dist/cpsat/validation-reporter.js.map +1 -1
- package/dist/cpsat/validation.types.d.ts +10 -10
- package/dist/cpsat/validation.types.d.ts.map +1 -1
- package/dist/datetime.utils.d.ts +4 -4
- package/dist/datetime.utils.js +6 -6
- package/dist/datetime.utils.js.map +1 -1
- package/dist/index.d.ts +81 -69
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +75 -57
- package/dist/index.js.map +1 -1
- package/dist/llms.d.ts +1 -4
- package/dist/llms.d.ts.map +1 -1
- package/dist/llms.js +2 -7
- package/dist/llms.js.map +1 -1
- package/dist/schedule.d.ts +724 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/schedule.js +899 -0
- package/dist/schedule.js.map +1 -0
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/testing/solver-container.d.ts.map +1 -1
- package/dist/testing/solver-container.js +8 -1
- package/dist/testing/solver-container.js.map +1 -1
- package/dist/types.d.ts +11 -21
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/validation.d.ts +21 -21
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +30 -30
- package/dist/validation.js.map +1 -1
- package/llms.txt +662 -1930
- package/package.json +1 -1
- package/src/client.types.ts +58 -0
- package/src/cpsat/cost.ts +128 -0
- package/src/cpsat/model-builder.ts +134 -83
- package/src/cpsat/response.ts +24 -15
- package/src/cpsat/rules/assign-together.ts +24 -21
- package/src/cpsat/rules/assignment-priority.ts +80 -0
- package/src/cpsat/rules/day-cost-multiplier.ts +124 -0
- package/src/cpsat/rules/day-cost-surcharge.ts +106 -0
- package/src/cpsat/rules/index.ts +10 -1
- package/src/cpsat/rules/location-preference.ts +32 -25
- package/src/cpsat/rules/max-consecutive-days.ts +26 -22
- package/src/cpsat/rules/max-hours-day.ts +33 -127
- package/src/cpsat/rules/max-hours-week.ts +40 -137
- package/src/cpsat/rules/max-shifts-day.ts +35 -138
- package/src/cpsat/rules/min-consecutive-days.ts +26 -22
- package/src/cpsat/rules/min-hours-day.ts +26 -22
- package/src/cpsat/rules/min-hours-week.ts +29 -27
- package/src/cpsat/rules/min-rest-between-shifts.ts +28 -24
- package/src/cpsat/rules/minimize-cost.ts +250 -0
- package/src/cpsat/rules/overtime-daily-multiplier.ts +181 -0
- package/src/cpsat/rules/overtime-daily-surcharge.ts +161 -0
- package/src/cpsat/rules/overtime-tiered-multiplier.ts +323 -0
- package/src/cpsat/rules/overtime-weekly-multiplier.ts +226 -0
- package/src/cpsat/rules/overtime-weekly-surcharge.ts +190 -0
- package/src/cpsat/rules/registry.ts +20 -2
- package/src/cpsat/rules/resolver.ts +99 -75
- package/src/cpsat/rules/rules.types.ts +29 -5
- package/src/cpsat/rules/scope.types.ts +548 -0
- package/src/cpsat/rules/time-cost-surcharge.ts +169 -0
- package/src/cpsat/rules/time-off.ts +52 -155
- package/src/cpsat/rules.ts +2 -2
- package/src/cpsat/semantic-time.ts +262 -54
- package/src/cpsat/types.ts +74 -36
- package/src/cpsat/utils.ts +27 -2
- package/src/cpsat/validation-reporter.ts +17 -17
- package/src/cpsat/validation.types.ts +10 -10
- package/src/datetime.utils.ts +6 -6
- package/src/index.ts +128 -138
- package/src/llms.ts +2 -8
- package/src/schedule.ts +1419 -0
- package/src/testing/index.ts +1 -1
- package/src/testing/solver-container.ts +10 -3
- package/src/types.ts +11 -21
- package/src/validation.ts +31 -31
- package/dist/cpsat/rules/employee-assignment-priority.d.ts +0 -64
- package/dist/cpsat/rules/employee-assignment-priority.d.ts.map +0 -1
- package/dist/cpsat/rules/employee-assignment-priority.js +0 -151
- package/dist/cpsat/rules/employee-assignment-priority.js.map +0 -1
- package/dist/cpsat/rules/scoping.d.ts +0 -129
- package/dist/cpsat/rules/scoping.d.ts.map +0 -1
- package/dist/cpsat/rules/scoping.js +0 -190
- package/dist/cpsat/rules/scoping.js.map +0 -1
- package/src/cpsat/rules/employee-assignment-priority.ts +0 -182
- package/src/cpsat/rules/scoping.ts +0 -340
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,73 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
This changelog was generated from the git history of the project when it was
|
|
6
6
|
named `scheduling-core`, prior to the rename to `dabke` in v0.78.0.
|
|
7
7
|
|
|
8
|
+
## 0.81.0 (2026-02-19)
|
|
9
|
+
|
|
10
|
+
### Breaking Changes
|
|
11
|
+
|
|
12
|
+
- **Rename employee to member**: `SchedulingEmployee` is now `SchedulingMember`,
|
|
13
|
+
`employeeIds` scope fields are now `memberIds`, and `Employee` type alias is removed.
|
|
14
|
+
The `employee-assignment-priority` rule is renamed to `assignment-priority`.
|
|
15
|
+
- **Rename roleIds/skillIds to roles/skills**: on `SchedulingMember`, `ShiftPattern`,
|
|
16
|
+
and all coverage requirement types. Scope fields on rules remain `roleIds`/`skillIds`.
|
|
17
|
+
- **Merge ShiftPatternDef into ShiftPattern**: the separate `ShiftPatternDef` type is
|
|
18
|
+
removed. `ShiftPattern` now directly includes `startTime`, `endTime`, and optional
|
|
19
|
+
`roles`/`skills` fields.
|
|
20
|
+
- **Flatten CpsatRuleConfigEntry**: rule config entries change from
|
|
21
|
+
`{ name, config: { ... } }` to `{ name, ...config }`. Config fields sit at the same
|
|
22
|
+
level as `name`. The type is now a distributive union preventing mismatched name/config
|
|
23
|
+
pairings at compile time.
|
|
24
|
+
- **Rename daysOfWeek to dayOfWeek**: on `SchedulingPeriod`, `SemanticTimeVariant`,
|
|
25
|
+
and coverage requirement types.
|
|
26
|
+
- **Remove v1-only exports**: `Employee`, `ShiftPatternDef`, `defineSemanticTimes`,
|
|
27
|
+
and related types removed from the public API. Use `defineSchedule` instead.
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
- **defineSchedule API**: new primary API with composable factory functions (`time`,
|
|
32
|
+
`cover`, `shift`, rule helpers like `maxHoursPerWeek`, `timeOff`, etc.) for building
|
|
33
|
+
a complete scheduling configuration declaratively.
|
|
34
|
+
- **Cost optimization**: base pay tracking (`HourlyPay`, `SalariedPay` on members),
|
|
35
|
+
cost minimization rule (`minimize-cost`), day/time cost surcharges and multipliers,
|
|
36
|
+
and post-solve cost calculation.
|
|
37
|
+
- **Overtime rules**: daily and weekly overtime multipliers and surcharges,
|
|
38
|
+
tiered overtime multiplier for graduated rates.
|
|
39
|
+
- **Variant coverage**: day-specific count overrides on coverage requirements
|
|
40
|
+
via `countByDay` on the `cover()` helper.
|
|
41
|
+
|
|
42
|
+
### Fixes
|
|
43
|
+
|
|
44
|
+
- Clean up stale solver containers on startup in the test harness.
|
|
45
|
+
- Strip all entity-scope fields consistently during scope resolution.
|
|
46
|
+
|
|
47
|
+
### Improvements
|
|
48
|
+
|
|
49
|
+
- Simplify rule translation layer; rule-specific knowledge (schemas, defaults,
|
|
50
|
+
validation, cost) is co-located in each rule file.
|
|
51
|
+
- Rewrite llms.txt generator as whitelist-based, aligned with the v2 API.
|
|
52
|
+
- Enrich TSDoc throughout: schedule.ts, semantic-time.ts, coverage types,
|
|
53
|
+
and package-level documentation updated for the defineSchedule API.
|
|
54
|
+
|
|
55
|
+
## 0.80.0 (2026-02-14)
|
|
56
|
+
|
|
57
|
+
### Breaking Changes
|
|
58
|
+
|
|
59
|
+
- Overhaul rule scoping types: replace `withScopes()` / `normalizeScope()` with
|
|
60
|
+
`entityScope()`, `timeScope()`, and `requiredTimeScope()` builder functions
|
|
61
|
+
- Remove exported types `EntityScope`, `TimeScope`, `RuleScope`, `ScopeConfig`
|
|
62
|
+
and functions `withScopes`, `normalizeScope`, `specificity`, `effectiveEmployeeIds`,
|
|
63
|
+
`subtractIds`, `timeScopeKey`, `entityScopeTypeKey`
|
|
64
|
+
- Scope fields (`employeeIds`, `roleIds`, `skillIds`, `specificDates`, `dayOfWeek`,
|
|
65
|
+
`recurringPeriods`) now require non-empty arrays; empty arrays are rejected at parse time
|
|
66
|
+
- Enforce mutual exclusivity of scope fields at compile time via `?: never` pattern
|
|
67
|
+
|
|
68
|
+
### Improvements
|
|
69
|
+
|
|
70
|
+
- Export `SolverStatusSchema` from main entry point
|
|
71
|
+
- Export new scoping types: `EntityScopeType`, `OptionalTimeScopeType`,
|
|
72
|
+
`RequiredTimeScopeType`, `ParsedEntityScope`, `ParsedTimeScope`, `RecurringPeriod`
|
|
73
|
+
- Add TSDoc to all solver wire types, rule config types, and model builder interfaces
|
|
74
|
+
|
|
8
75
|
## 0.79.0 (2026-02-10)
|
|
9
76
|
|
|
10
77
|
### Breaking Changes
|
package/README.md
CHANGED
|
@@ -38,7 +38,9 @@ const builder = new ModelBuilder({
|
|
|
38
38
|
priority: "MANDATORY",
|
|
39
39
|
},
|
|
40
40
|
],
|
|
41
|
-
schedulingPeriod: {
|
|
41
|
+
schedulingPeriod: {
|
|
42
|
+
dateRange: { start: "2026-02-09", end: "2026-02-09" },
|
|
43
|
+
},
|
|
42
44
|
ruleConfigs: [
|
|
43
45
|
{ name: "max-hours-day", config: { hours: 8, priority: "MANDATORY" } },
|
|
44
46
|
{ name: "min-rest-between-shifts", config: { hours: 10, priority: "MANDATORY" } },
|
|
@@ -135,7 +137,7 @@ const builder = new ModelBuilder({
|
|
|
135
137
|
shiftPatterns,
|
|
136
138
|
coverage,
|
|
137
139
|
schedulingPeriod: {
|
|
138
|
-
|
|
140
|
+
dateRange: { start: "2026-02-09", end: "2026-02-09" },
|
|
139
141
|
},
|
|
140
142
|
ruleConfigs: [
|
|
141
143
|
{ name: "max-hours-day", config: { hours: 8, priority: "MANDATORY" } },
|
|
@@ -177,12 +179,12 @@ const times = defineSemanticTimes({
|
|
|
177
179
|
{
|
|
178
180
|
startTime: { hours: 11, minutes: 30 },
|
|
179
181
|
endTime: { hours: 14 },
|
|
180
|
-
|
|
182
|
+
dayOfWeek: ["monday", "tuesday", "wednesday", "thursday", "friday"],
|
|
181
183
|
},
|
|
182
184
|
{
|
|
183
185
|
startTime: { hours: 12 },
|
|
184
186
|
endTime: { hours: 15 },
|
|
185
|
-
|
|
187
|
+
dayOfWeek: ["saturday", "sunday"],
|
|
186
188
|
},
|
|
187
189
|
],
|
|
188
190
|
closing: { startTime: { hours: 21 }, endTime: { hours: 23 } },
|
package/dist/client.types.d.ts
CHANGED
|
@@ -7,13 +7,71 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { z } from "zod";
|
|
9
9
|
import type { SolverTermSchema, SolverVariableSchema, SolverConstraintSchema, SolverObjectiveSchema, SolverRequestSchema, SolverResponseSchema, SolverStatusSchema, SoftConstraintViolationSchema } from "./client.schemas.js";
|
|
10
|
+
/**
|
|
11
|
+
* A single linear term in a constraint or objective.
|
|
12
|
+
*
|
|
13
|
+
* - `var` (required): variable name
|
|
14
|
+
* - `coeff` (required): integer coefficient
|
|
15
|
+
*/
|
|
10
16
|
export type SolverTerm = z.infer<typeof SolverTermSchema>;
|
|
17
|
+
/**
|
|
18
|
+
* A decision variable in the CP-SAT model.
|
|
19
|
+
*
|
|
20
|
+
* - `name` (required): unique variable identifier
|
|
21
|
+
* - `lb` (required): lower bound
|
|
22
|
+
* - `ub` (required): upper bound
|
|
23
|
+
* - `isBoolean` (optional): whether this is a boolean variable
|
|
24
|
+
* - `isInterval` (optional): whether this is an interval variable
|
|
25
|
+
* - `start`, `end`, `size`, `presenceVar` (optional): interval variable fields
|
|
26
|
+
*/
|
|
11
27
|
export type SolverVariable = z.infer<typeof SolverVariableSchema>;
|
|
28
|
+
/**
|
|
29
|
+
* A constraint in the CP-SAT model.
|
|
30
|
+
*
|
|
31
|
+
* - `name` (required): constraint identifier
|
|
32
|
+
* - `type` (required): constraint kind (e.g. "linear", "bool_and", "no_overlap")
|
|
33
|
+
* - Additional fields vary by constraint type
|
|
34
|
+
*/
|
|
12
35
|
export type SolverConstraint = z.infer<typeof SolverConstraintSchema>;
|
|
36
|
+
/**
|
|
37
|
+
* An optimization objective for the solver.
|
|
38
|
+
*
|
|
39
|
+
* - `terms` (required): linear terms to minimize/maximize
|
|
40
|
+
* - `minimize` (required): whether to minimize (true) or maximize (false)
|
|
41
|
+
*/
|
|
13
42
|
export type SolverObjective = z.infer<typeof SolverObjectiveSchema>;
|
|
43
|
+
/**
|
|
44
|
+
* The full request payload sent to the CP-SAT solver service.
|
|
45
|
+
*
|
|
46
|
+
* - `variables` (required): all decision variables
|
|
47
|
+
* - `constraints` (required): all constraints
|
|
48
|
+
* - `objective` (optional): optimization objective
|
|
49
|
+
* - `timeoutSeconds` (optional): solver time limit
|
|
50
|
+
*/
|
|
14
51
|
export type SolverRequest = z.infer<typeof SolverRequestSchema>;
|
|
52
|
+
/**
|
|
53
|
+
* The response payload returned by the CP-SAT solver service.
|
|
54
|
+
*
|
|
55
|
+
* - `status` (required): solve outcome (see {@link SolverStatus})
|
|
56
|
+
* - `values` (optional): variable assignments when a solution is found
|
|
57
|
+
* - `statistics` (optional): solve time, conflicts, branches
|
|
58
|
+
* - `softViolations` (optional): which soft constraints were violated
|
|
59
|
+
* - `error` (optional): error message on failure
|
|
60
|
+
* - `solutionInfo` (optional): solver diagnostic info
|
|
61
|
+
*/
|
|
15
62
|
export type SolverResponse = z.infer<typeof SolverResponseSchema>;
|
|
63
|
+
/**
|
|
64
|
+
* Solver outcome status.
|
|
65
|
+
*
|
|
66
|
+
* One of `"OPTIMAL"`, `"FEASIBLE"`, `"INFEASIBLE"`, `"TIMEOUT"`, or `"ERROR"`.
|
|
67
|
+
*/
|
|
16
68
|
export type SolverStatus = z.infer<typeof SolverStatusSchema>;
|
|
69
|
+
/**
|
|
70
|
+
* A soft constraint violation reported by the solver.
|
|
71
|
+
*
|
|
72
|
+
* - `constraintId` (required): which soft constraint was violated
|
|
73
|
+
* - `violationAmount` (required): magnitude of the violation
|
|
74
|
+
*/
|
|
17
75
|
export type SoftConstraintViolation = z.infer<typeof SoftConstraintViolationSchema>;
|
|
18
76
|
export declare const SOLVER_STATUS: {
|
|
19
77
|
readonly OPTIMAL: "OPTIMAL";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.types.d.ts","sourceRoot":"","sources":["../src/client.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,6BAA6B,EAC9B,MAAM,qBAAqB,CAAC;AAM7B,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAMpF,eAAO,MAAM,aAAa;;;;;;CAMhB,CAAC;AAMX,MAAM,MAAM,WAAW,GACnB,OAAO,KAAK,GACZ;IACE,KAAK,EAAE,OAAO,KAAK,CAAC;CACrB,CAAC;AAEN,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3F,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
|
|
1
|
+
{"version":3,"file":"client.types.d.ts","sourceRoot":"","sources":["../src/client.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,6BAA6B,EAC9B,MAAM,qBAAqB,CAAC;AAM7B;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAMpF,eAAO,MAAM,aAAa;;;;;;CAMhB,CAAC;AAMX,MAAM,MAAM,WAAW,GACnB,OAAO,KAAK,GACZ;IACE,KAAK,EAAE,OAAO,KAAK,CAAC;CACrB,CAAC;AAEN,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3F,MAAM,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
|
package/dist/client.types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.types.js","sourceRoot":"","sources":["../src/client.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"client.types.js","sourceRoot":"","sources":["../src/client.types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4FH,6EAA6E;AAC7E,qCAAqC;AACrC,6EAA6E;AAE7E,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,UAAU,EAAE,YAAY;IACxB,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;CACN,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ShiftAssignment } from "./response.js";
|
|
2
|
+
import type { SchedulingMember, ShiftPattern } from "./types.js";
|
|
3
|
+
import type { CompilationRule } from "./model-builder.js";
|
|
4
|
+
/**
|
|
5
|
+
* Well-known cost categories used by built-in rules.
|
|
6
|
+
*
|
|
7
|
+
* Custom rules can use any string as a category. These constants
|
|
8
|
+
* are provided for convenience and consistency.
|
|
9
|
+
*/
|
|
10
|
+
export declare const COST_CATEGORY: {
|
|
11
|
+
/** Base pay cost (from {@link minimizeCost}). */
|
|
12
|
+
readonly BASE: "base";
|
|
13
|
+
/** Overtime cost (from overtime rules). */
|
|
14
|
+
readonly OVERTIME: "overtime";
|
|
15
|
+
/** Premium cost (from day/time multipliers and surcharges). */
|
|
16
|
+
readonly PREMIUM: "premium";
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Per-member cost breakdown.
|
|
20
|
+
*
|
|
21
|
+
* Categories are open-ended strings. Built-in rules use categories
|
|
22
|
+
* from {@link COST_CATEGORY}. Custom rules can introduce their own.
|
|
23
|
+
*/
|
|
24
|
+
export interface MemberCostDetail {
|
|
25
|
+
/** Sum of all category costs. */
|
|
26
|
+
totalCost: number;
|
|
27
|
+
/** Total hours worked (computed from assignments, not from rules). */
|
|
28
|
+
totalHours: number;
|
|
29
|
+
/** Cost per category. Only categories with nonzero cost appear. */
|
|
30
|
+
categories: ReadonlyMap<string, number>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Full cost breakdown for a solved schedule.
|
|
34
|
+
*/
|
|
35
|
+
export interface CostBreakdown {
|
|
36
|
+
/** Total cost in the caller's currency unit. */
|
|
37
|
+
total: number;
|
|
38
|
+
/** Cost per member. */
|
|
39
|
+
byMember: ReadonlyMap<string, MemberCostDetail>;
|
|
40
|
+
/** Cost per day. */
|
|
41
|
+
byDay: ReadonlyMap<string, number>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Configuration accepted by {@link calculateScheduleCost}.
|
|
45
|
+
*
|
|
46
|
+
* In practice, callers pass the `ModelBuilderConfig` (which satisfies this)
|
|
47
|
+
* or the relevant subset.
|
|
48
|
+
*/
|
|
49
|
+
export interface CostCalculationConfig {
|
|
50
|
+
members: ReadonlyArray<SchedulingMember>;
|
|
51
|
+
shiftPatterns: ReadonlyArray<ShiftPattern>;
|
|
52
|
+
rules: ReadonlyArray<CompilationRule>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Computes the actual cost of a solved schedule using the same cost model
|
|
56
|
+
* as the solver rules.
|
|
57
|
+
*
|
|
58
|
+
* Collects `CostEntry` values from all rules' `cost()` methods and
|
|
59
|
+
* aggregates them into a {@link CostBreakdown}.
|
|
60
|
+
*
|
|
61
|
+
* @param assignments - Shift assignments from {@link parseSolverResponse}
|
|
62
|
+
* @param config - Members, shift patterns, and compiled rules
|
|
63
|
+
*/
|
|
64
|
+
export declare function calculateScheduleCost(assignments: ShiftAssignment[], config: CostCalculationConfig): CostBreakdown;
|
|
65
|
+
//# sourceMappingURL=cost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/cpsat/cost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAa,MAAM,oBAAoB,CAAC;AAGrE;;;;;GAKG;AACH,eAAO,MAAM,aAAa;IACxB,iDAAiD;;IAEjD,2CAA2C;;IAE3C,+DAA+D;;CAEvD,CAAC;AAEX;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAChD,oBAAoB;IACpB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IAC3C,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CACvC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,eAAe,EAAE,EAC9B,MAAM,EAAE,qBAAqB,GAC5B,aAAa,CAuDf"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { timeOfDayToMinutes, normalizeEndMinutes } from "./utils.js";
|
|
2
|
+
/**
|
|
3
|
+
* Well-known cost categories used by built-in rules.
|
|
4
|
+
*
|
|
5
|
+
* Custom rules can use any string as a category. These constants
|
|
6
|
+
* are provided for convenience and consistency.
|
|
7
|
+
*/
|
|
8
|
+
export const COST_CATEGORY = {
|
|
9
|
+
/** Base pay cost (from {@link minimizeCost}). */
|
|
10
|
+
BASE: "base",
|
|
11
|
+
/** Overtime cost (from overtime rules). */
|
|
12
|
+
OVERTIME: "overtime",
|
|
13
|
+
/** Premium cost (from day/time multipliers and surcharges). */
|
|
14
|
+
PREMIUM: "premium",
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Computes the actual cost of a solved schedule using the same cost model
|
|
18
|
+
* as the solver rules.
|
|
19
|
+
*
|
|
20
|
+
* Collects `CostEntry` values from all rules' `cost()` methods and
|
|
21
|
+
* aggregates them into a {@link CostBreakdown}.
|
|
22
|
+
*
|
|
23
|
+
* @param assignments - Shift assignments from {@link parseSolverResponse}
|
|
24
|
+
* @param config - Members, shift patterns, and compiled rules
|
|
25
|
+
*/
|
|
26
|
+
export function calculateScheduleCost(assignments, config) {
|
|
27
|
+
const { members, shiftPatterns, rules } = config;
|
|
28
|
+
// Collect all cost entries from rules
|
|
29
|
+
const allEntries = [];
|
|
30
|
+
for (const rule of rules) {
|
|
31
|
+
if (!rule.cost)
|
|
32
|
+
continue;
|
|
33
|
+
const contribution = rule.cost(assignments, members, shiftPatterns);
|
|
34
|
+
allEntries.push(...contribution.entries);
|
|
35
|
+
}
|
|
36
|
+
// Compute total hours per member from assignments
|
|
37
|
+
const patternMap = new Map(shiftPatterns.map((p) => [p.id, p]));
|
|
38
|
+
const memberHours = new Map();
|
|
39
|
+
for (const a of assignments) {
|
|
40
|
+
const pattern = patternMap.get(a.shiftPatternId);
|
|
41
|
+
if (!pattern)
|
|
42
|
+
continue;
|
|
43
|
+
const start = timeOfDayToMinutes(pattern.startTime);
|
|
44
|
+
const end = normalizeEndMinutes(start, timeOfDayToMinutes(pattern.endTime));
|
|
45
|
+
const hours = (end - start) / 60;
|
|
46
|
+
memberHours.set(a.memberId, (memberHours.get(a.memberId) ?? 0) + hours);
|
|
47
|
+
}
|
|
48
|
+
// Build per-member category maps
|
|
49
|
+
const memberCategories = new Map();
|
|
50
|
+
const dayTotals = new Map();
|
|
51
|
+
for (const entry of allEntries) {
|
|
52
|
+
// Per-member category accumulation
|
|
53
|
+
let categories = memberCategories.get(entry.memberId);
|
|
54
|
+
if (!categories) {
|
|
55
|
+
categories = new Map();
|
|
56
|
+
memberCategories.set(entry.memberId, categories);
|
|
57
|
+
}
|
|
58
|
+
categories.set(entry.category, (categories.get(entry.category) ?? 0) + entry.amount);
|
|
59
|
+
dayTotals.set(entry.day, (dayTotals.get(entry.day) ?? 0) + entry.amount);
|
|
60
|
+
}
|
|
61
|
+
let total = 0;
|
|
62
|
+
const byMember = new Map();
|
|
63
|
+
for (const [memberId, categories] of memberCategories) {
|
|
64
|
+
let totalCost = 0;
|
|
65
|
+
for (const amount of categories.values()) {
|
|
66
|
+
totalCost += amount;
|
|
67
|
+
}
|
|
68
|
+
total += totalCost;
|
|
69
|
+
byMember.set(memberId, {
|
|
70
|
+
totalCost,
|
|
71
|
+
totalHours: memberHours.get(memberId) ?? 0,
|
|
72
|
+
categories,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return { total, byMember, byDay: dayTotals };
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/cpsat/cost.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { SolverRequest } from "../client.types.js";
|
|
2
2
|
import type { DayOfWeek, SchedulingPeriod } from "../types.js";
|
|
3
|
-
import type { CoverageRequirement, ModelBuilderOptions, ShiftPattern,
|
|
3
|
+
import type { CoverageRequirement, ModelBuilderOptions, ShiftPattern, SchedulingMember, Term } from "./types.js";
|
|
4
4
|
import type { CpsatRuleConfigEntry, CpsatRuleFactories } from "./rules/rules.types.js";
|
|
5
5
|
import type { ValidationReporter } from "./validation-reporter.js";
|
|
6
6
|
import type { ScheduleValidation } from "./validation.types.js";
|
|
7
|
-
import type { ResolvedShiftAssignment } from "./response.js";
|
|
7
|
+
import type { ShiftAssignment, ResolvedShiftAssignment } from "./response.js";
|
|
8
8
|
/**
|
|
9
9
|
* Builds a CP-SAT solver request from high-level scheduling constructs
|
|
10
10
|
* (team, shift patterns, coverage, and rule compilers).
|
|
@@ -13,13 +13,54 @@ import type { ResolvedShiftAssignment } from "./response.js";
|
|
|
13
13
|
* Context provided to rules during post-solve validation.
|
|
14
14
|
*/
|
|
15
15
|
export interface RuleValidationContext {
|
|
16
|
-
readonly
|
|
16
|
+
readonly members: SchedulingMember[];
|
|
17
17
|
readonly days: string[];
|
|
18
18
|
readonly shiftPatterns: ShiftPattern[];
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* A rule that adds constraints or objectives to the solver model.
|
|
22
|
+
*
|
|
23
|
+
* Rules implement `compile` to emit solver constraints during model building,
|
|
24
|
+
* and optionally `validate` to check the solution after solving.
|
|
25
|
+
* Use the `create*Rule` functions to create built-in rules.
|
|
26
|
+
*/
|
|
20
27
|
export interface CompilationRule {
|
|
28
|
+
/** Emit constraints and objectives into the model builder. */
|
|
21
29
|
compile(builder: ModelBuilder): void;
|
|
30
|
+
/** Validate the solved schedule and report violations. */
|
|
22
31
|
validate?(assignments: ResolvedShiftAssignment[], reporter: ValidationReporter, context: RuleValidationContext): void;
|
|
32
|
+
/** Compute cost contribution for a solved schedule. */
|
|
33
|
+
cost?(assignments: ShiftAssignment[], members: ReadonlyArray<SchedulingMember>, shiftPatterns: ReadonlyArray<ShiftPattern>): CostContribution;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Shared context for cost rules.
|
|
37
|
+
*
|
|
38
|
+
* Set by `minimizeCost()` during compilation, read by modifier rules.
|
|
39
|
+
* When undefined, modifier rules skip emitting solver terms.
|
|
40
|
+
*/
|
|
41
|
+
export interface CostContext {
|
|
42
|
+
/** Normalization divisor: max raw cost of any single assignment. */
|
|
43
|
+
normalizationFactor: number;
|
|
44
|
+
/** Whether minimizeCost() is active (modifier rules check this). */
|
|
45
|
+
active: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A cost entry produced by a rule's `cost()` method.
|
|
49
|
+
*
|
|
50
|
+
* The `category` is an open-ended string. Built-in rules use well-known
|
|
51
|
+
* categories from {@link COST_CATEGORY}. Custom rules can use any string.
|
|
52
|
+
*/
|
|
53
|
+
export interface CostEntry {
|
|
54
|
+
memberId: string;
|
|
55
|
+
day: string;
|
|
56
|
+
category: string;
|
|
57
|
+
amount: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Cost contribution from a single rule.
|
|
61
|
+
*/
|
|
62
|
+
export interface CostContribution {
|
|
63
|
+
entries: CostEntry[];
|
|
23
64
|
}
|
|
24
65
|
export interface CompilationResult {
|
|
25
66
|
request: SolverRequest;
|
|
@@ -32,22 +73,24 @@ export interface CompilationResult {
|
|
|
32
73
|
* @example Date range with day-of-week filtering (restaurant closed Mon/Tue)
|
|
33
74
|
* ```typescript
|
|
34
75
|
* const config: ModelBuilderConfig = {
|
|
35
|
-
*
|
|
76
|
+
* members: [...],
|
|
36
77
|
* shiftPatterns: [...],
|
|
37
78
|
* coverage: [...],
|
|
38
79
|
* schedulingPeriod: {
|
|
39
80
|
* dateRange: { start: '2025-02-03', end: '2025-02-09' },
|
|
40
|
-
*
|
|
81
|
+
* dayOfWeek: ['wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
|
|
41
82
|
* },
|
|
42
83
|
* };
|
|
43
84
|
* ```
|
|
44
85
|
*/
|
|
45
86
|
export interface ModelBuilderConfig extends ModelBuilderOptions {
|
|
46
|
-
|
|
87
|
+
/** Team members available for scheduling. */
|
|
88
|
+
members: SchedulingMember[];
|
|
89
|
+
/** Available shift patterns (time slots) that members can be assigned to. */
|
|
47
90
|
shiftPatterns: ShiftPattern[];
|
|
48
91
|
/**
|
|
49
92
|
* Defines when scheduling should occur as a date range with optional
|
|
50
|
-
* `
|
|
93
|
+
* `dayOfWeek` and `dates` filters that compose to narrow which days are included.
|
|
51
94
|
*/
|
|
52
95
|
schedulingPeriod: SchedulingPeriod;
|
|
53
96
|
coverage: CoverageRequirement[];
|
|
@@ -74,7 +117,7 @@ export interface ModelBuilderConfig extends ModelBuilderOptions {
|
|
|
74
117
|
*/
|
|
75
118
|
export declare class ModelBuilder {
|
|
76
119
|
#private;
|
|
77
|
-
readonly
|
|
120
|
+
readonly members: SchedulingMember[];
|
|
78
121
|
readonly shiftPatterns: ShiftPattern[];
|
|
79
122
|
readonly days: string[];
|
|
80
123
|
readonly coverage: CoverageRequirement[];
|
|
@@ -84,11 +127,13 @@ export declare class ModelBuilder {
|
|
|
84
127
|
readonly coverageBucketMinutes: number;
|
|
85
128
|
readonly reporter: ValidationReporter;
|
|
86
129
|
readonly fairDistribution: boolean;
|
|
130
|
+
/** Shared context for cost rules. Set by minimizeCost(), read by modifiers. */
|
|
131
|
+
costContext: CostContext | undefined;
|
|
87
132
|
constructor(config: ModelBuilderConfig);
|
|
88
133
|
boolVar(name: string): string;
|
|
89
134
|
intVar(name: string, min: number, max: number): string;
|
|
90
135
|
shiftActive(patternId: string, day: string): string;
|
|
91
|
-
assignment(
|
|
136
|
+
assignment(memberId: string, patternId: string, day: string): string;
|
|
92
137
|
addLinear(terms: Term[], op: "<=" | ">=" | "==", rhs: number): void;
|
|
93
138
|
addSoftLinear(terms: Term[], op: "<=" | ">=", rhs: number, penalty: number, id?: string): void;
|
|
94
139
|
addExactlyOne(vars: string[]): void;
|
|
@@ -99,20 +144,20 @@ export declare class ModelBuilder {
|
|
|
99
144
|
intervalVar(name: string, start: number, end: number, size: number, presenceVar?: string): string;
|
|
100
145
|
addNoOverlap(intervals: string[]): void;
|
|
101
146
|
addPenalty(varName: string, weight: number): void;
|
|
102
|
-
|
|
147
|
+
membersWithRole(roleId: string): SchedulingMember[];
|
|
103
148
|
/**
|
|
104
149
|
* Returns team members who can satisfy a coverage requirement.
|
|
105
150
|
*
|
|
106
151
|
* Matching logic:
|
|
107
|
-
* - If only
|
|
108
|
-
* - If only
|
|
109
|
-
* - If both: must have
|
|
152
|
+
* - If only roles: must have ANY of those roles (OR)
|
|
153
|
+
* - If only skills: must have ALL specified skills (AND)
|
|
154
|
+
* - If both: must have a matching role AND ALL specified skills
|
|
110
155
|
*/
|
|
111
|
-
|
|
112
|
-
canAssign(
|
|
156
|
+
membersForCoverage(cov: CoverageRequirement): SchedulingMember[];
|
|
157
|
+
canAssign(member: SchedulingMember, pattern: ShiftPattern): boolean;
|
|
113
158
|
/**
|
|
114
159
|
* Checks if a shift pattern can be used on a specific day.
|
|
115
|
-
* Returns false if the pattern has
|
|
160
|
+
* Returns false if the pattern has dayOfWeek restrictions that exclude this day.
|
|
116
161
|
*/
|
|
117
162
|
patternAvailableOnDay(pattern: ShiftPattern, day: string): boolean;
|
|
118
163
|
patternDuration(patternId: string): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-builder.d.ts","sourceRoot":"","sources":["../../src/cpsat/model-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,aAAa,EAAkB,MAAM,oBAAoB,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAU/D,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"model-builder.d.ts","sourceRoot":"","sources":["../../src/cpsat/model-builder.ts"],"names":[],"mappings":"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"}
|