The UTC date trap is a great catch: at 9am in Sydney new Date().toISOString() still returns yesterday, so every daysFromDue comes out one short. Picking the highest stage at or below daysFromDue so downtime does not trigger a burst of emails is also a thoughtful touch. The Sheets serial number gotcha (46312 for 17 Oct 2026) silently dropping a reformatted column is the kind of failure that would be hard to spot without this write up.
StackShortlist
Proof Over Promises.
The UTC date trap is a great catch: at 9am in Sydney new Date().toISOString() still returns yesterday, so every daysFromDue comes out one short. Picking the highest stage at or below daysFromDue so downtime does not trigger a burst of emails is also a thoughtful touch. The Sheets serial number gotcha (46312 for 17 Oct 2026) silently dropping a reformatted column is the kind of failure that would be hard to spot without this write up.