fix(backend): correct "next weekday" and harden resolvers against model output
Four defects found by review of the preceding commits.
"next <weekday>" was occurrence-anchored ("this" plus seven) rather than week-
anchored. Said on a Thursday, "Thursday next week" resolved to +14 instead of
+7: next week runs Sat 10-18 to Fri 10-24, so its Thursday is 10-23, not 10-30.
A lab case a week late. "next" now counts from the start of the following
Saturday-start week, which also lets "this" and "next" correctly coincide —
said on a Thursday, "the coming Saturday" and "Saturday next week" are the same
day. "this" stays occurrence-anchored so it can never resolve into the past.
The other three all come from the same root cause: exported functions that are
reachable from untrusted model output must degrade, not throw or drop.
- a non-object `due` (the model emitting a bare string) was treated as "no
deadline spoken" and silently discarded; only null/undefined mean absent now,
anything else is flagged so the clinician sees something was heard and lost
- isJalaliLeapYear / jalaliDaysInMonth threw for years outside the conversion
table, contradicting the module's own "degrade to null" contract; they now
return false / 0, which also makes isValidJalaliDate's day check naturally
false
- civilDateInZone passed a client-supplied zone straight to Intl, which raises
RangeError before any fallback; it now validates and backstops to UTC, so a
bad zone costs at most a day rather than a 500
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -61,8 +61,12 @@ export function civilDateJsWeekday(isoDate: string): number {
|
||||
* client-supplied date, which matters for relative deadlines like "by Thursday".
|
||||
*/
|
||||
export function civilDateInZone(date: Date, timeZone: string): string {
|
||||
// Intl throws RangeError on an unknown zone, before any fallback below could help, and
|
||||
// this receives a client-supplied string. Callers validate first; this is the backstop
|
||||
// so a bad zone degrades to a date that is at most a day out rather than a 500.
|
||||
const zone = isValidIanaTimeZone(timeZone) ? timeZone : 'UTC';
|
||||
const parts = new Intl.DateTimeFormat('en-CA', {
|
||||
timeZone,
|
||||
timeZone: zone,
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
|
||||
Reference in New Issue
Block a user