feat: add PlanningDurationService for estimating planning duration
- Implemented PlanningDurationService to provide an indicative wait time before calculation based on user input and calendar settings. - Introduced duration estimation logic that considers horizon dates, balances, and rules without triggering a calculation. - Enhanced user input component to display estimated duration using the new service. - Updated translation files to include new duration estimate strings in multiple languages. - Added tests for PlanningDurationService to ensure accurate duration estimation and calibration. - Refactored leave planner service to remove hardcoded deadlines and improve worker responsiveness.
This commit is contained in:
1 parent
2edf2004f5
commit
bc8570d8ca
29 files changed
+1064
-123
No files matched your search
@@ -8,9 +8,22 @@ import {
|
||||
|
||||
describe('leave planner benchmark protocol', () => {
|
||||
// Warm-up and two repetitions include complete trace delivery after planning.
|
||||
it('keeps five deterministic scenarios and exercises a later earned consumer', async () => {
|
||||
it('keeps seven deterministic scenarios including two and three years and a later earned consumer', async () => {
|
||||
const scenarios = benchmarkScenarios();
|
||||
expect(scenarios).toHaveLength(5);
|
||||
expect(scenarios).toHaveLength(7);
|
||||
for (const [name, end] of [
|
||||
['two years', '2026-01-01'],
|
||||
['three years', '2027-01-01'],
|
||||
]) {
|
||||
const scenario = scenarios.find((item) => item.name === name)!;
|
||||
expect(scenario.request.horizon).toEqual({ start: '2024-01-01', end });
|
||||
expect(
|
||||
scenario.request.balances.some(
|
||||
(item) => String(item.availableFrom) >= '2025-01-01',
|
||||
),
|
||||
).toBe(true);
|
||||
expect(scenario.request.deadlineMs).toBeUndefined();
|
||||
}
|
||||
const typedObligations = scenarios.find(
|
||||
(scenario) => scenario.name === 'typed obligations',
|
||||
);
|
||||
@@ -49,6 +62,19 @@ describe('leave planner benchmark protocol', () => {
|
||||
).toHaveLength(2);
|
||||
}
|
||||
const measurements = await runLeavePlannerBenchmark(2);
|
||||
for (const [name, placements] of [
|
||||
['two years', 60],
|
||||
['three years', 90],
|
||||
] as const) {
|
||||
const longer = measurements.filter((measurement) => measurement.scenario === name);
|
||||
expect(longer).toHaveLength(2);
|
||||
expect(longer.map((item) => item.outcome)).toEqual(['Plan', 'Plan']);
|
||||
expect(longer.map((item) => item.lastCompletedStage)).toEqual(['dates', 'dates']);
|
||||
expect(longer.map((item) => item.placements)).toEqual([placements, placements]);
|
||||
expect(longer.map((item) => item.deterministic)).toEqual(['baseline', 'yes']);
|
||||
expect(longer.map((item) => item.traceStatus)).toEqual(['ready', 'ready']);
|
||||
expect(longer[0].traceCandidates).toBeGreaterThan(0);
|
||||
}
|
||||
const chained = measurements.find(
|
||||
(measurement) => measurement.scenario === 'chained earned entitlements',
|
||||
);
|
||||
@@ -74,7 +100,7 @@ describe('leave planner benchmark protocol', () => {
|
||||
expect(loaded[0].traceStatus).toBe('ready');
|
||||
expect(loaded[0].traceCandidates).toBeGreaterThan(0);
|
||||
const report = benchmarkReport(measurements);
|
||||
expect(report.split('\n')).toHaveLength(11);
|
||||
expect(report.split('\n')).toHaveLength(15);
|
||||
expect(report).toContain('planning_ms\ttrace_delivery_ms');
|
||||
expect(report).toContain('planning_work_ms\ttrace_capture_ms');
|
||||
expect(report).toContain('\tbaseline\t');
|
||||
|
||||
Reference in new issue
Block a user