New js/utils.js exports toISO, monthPrefix, getWeekday, formatDateDE and
buildNameMap. algorithm.js, calendar.js, excel.js and history.js now import
these instead of re-implementing ISO construction, weekday math, DD.MM.YYYY
formatting and the id→name map inline. Adds tests/utils.test.mjs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- generatePlan computes a histCount Map once; scoreCandidate now does an O(1)
lookup instead of filtering the whole history per candidate per day.
- minGap eligibility finds the latest prior date in a single pass instead of
spreading history+monthAssignments into a new array and sorting it.
Behaviour is unchanged (all algorithm tests pass).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
generatePlan gains a preAssigned parameter: manual entries occupy slots,
count toward eligibility (maxPerMonth/minGap) and are never double-booked;
only the remaining slots per day are auto-filled. The generate handler now
keeps manual:true entries for the month instead of wiping them.
Adds tests for slot occupation, fully-manual days, and maxPerMonth counting.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>