feat(planning): make optimization rules composable
Evaluate explicit, ordered optimization configurations through one shared planner model. Add six editable presets, durable one-time legacy migration, and consistent completed and cancelled plan provenance. Include functional regressions and the agreed trace-removal and benchmark follow-up specs. Performance acceptance remains in #78 under unchanged gates. Refs: #70, #71, #72, #73, #74, #75, #76, #77, #78
This commit is contained in:
1 parent
209bf05f36
commit
6811142299
45 files changed
+8795
-3075
No files matched your search
@@ -5,11 +5,12 @@ import { RuleService, RuleType } from './rule-service';
|
||||
import { UserInputService } from './user-input-service';
|
||||
import { createPlanningCalculation } from './leave-planner.service';
|
||||
import { PlanningDurationService } from './planning-duration.service';
|
||||
import { OPTIMIZATION_PRESETS } from './planning-objectives';
|
||||
|
||||
describe('Planning duration estimate', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
localStorage.setItem('vacationRules', '[]');
|
||||
localStorage.setItem('vacationRules', '{"version":1,"rules":[]}');
|
||||
TestBed.inject(CalendarSettingsService).setPlanningDates('2024-01-01', '2024-12-31');
|
||||
TestBed.inject(UserInputService).updateBalances(() => [
|
||||
{
|
||||
@@ -34,6 +35,22 @@ describe('Planning duration estimate', () => {
|
||||
expect(TestBed.inject(RuleService).rules).toEqual([]);
|
||||
});
|
||||
|
||||
it('estimates and calibrates optimization rules without a requested leave quantity', () => {
|
||||
const rules = TestBed.inject(RuleService);
|
||||
rules.addRule({
|
||||
id: 'loss',
|
||||
name: 'Loss',
|
||||
type: RuleType.OPTIMIZATION,
|
||||
enabled: true,
|
||||
force: 'preference',
|
||||
configuration: structuredClone(OPTIMIZATION_PRESETS.unplacedAtRisk),
|
||||
});
|
||||
const duration = TestBed.inject(PlanningDurationService);
|
||||
expect(Number.isFinite(duration.estimate()!.maximum)).toBe(true);
|
||||
duration.recordCompletion(duration.request()!, 20_000);
|
||||
expect(duration.estimate()).toEqual({ minimum: 10, maximum: 60, unit: 'seconds' });
|
||||
});
|
||||
|
||||
it('updates for dates, balances and active rules without requesting a calculation', () => {
|
||||
const duration = TestBed.inject(PlanningDurationService);
|
||||
const settings = TestBed.inject(CalendarSettingsService);
|
||||
|
||||
Reference in new issue
Block a user