Jobs: derive lateness on the device — end-of-day rule and a shared minute ticker #186

Closed
opened 2026-08-23 21:57:29 +00:00 by nalum · 0 comments
Owner

Part of the jobs flow redesign (#184). The design handoff added a late-state
pass; this issue is the behaviour half of it, separate from the wording (#179)
and the card (#174).

A date-only deadline is late only after the end of that day

Both clients ask deadline < now and stop there (web/src/deadline.ts:23-27,
android/.../Today.kt:82-85). A date-only deadline is stored as local
midnight, so a job due today is drawn late from 00:00 — red for the whole day
it is actually due.

conformance/deadline.json pins that as a case, named untimed today counts as
overdue past midnight
, overdue: true. The rule reverses it to false until
the end of that day, so isOverdue, its Android twin and the fixture change
together, in one commit.

The server already behaves the new way. internal/services/item/reminder.go
compares dates, so it rings JobDue on the due date and JobOverdue only from
the next day. This closes a live client/server disagreement rather than
adjusting a preference.

A timed deadline legitimately keeps a different granularity: the card goes late
at 09:45 while the reminder would not ring overdue until the next day. Two
mechanisms, two granularities, both correct. Do not "fix" one to match.

A shared minute ticker

Late is derived on the device, so a card visible at 09:44 must flip at 09:45
with no refresh. Nothing does that today: const now = new Date() is computed
per render (Jobs.tsx:233, and the same on Today), and web/src/clock.ts holds
only fmtTime.

Needed on both surfaces, plus a wake handler. Small, but new. The screenshot
suites pin the browser clock, so a ticker must not reintroduce nondeterminism
there.

Two rules that ride along: comparisons are always against the timestamp, never
a rendered string, and "yesterday" is computed against the reader's local
midnight.

Blocks the late state in #174 and its wording in #179.

Part of the jobs flow redesign (#184). The design handoff added a late-state pass; this issue is the behaviour half of it, separate from the wording (#179) and the card (#174). ## A date-only deadline is late only after the end of that day Both clients ask `deadline < now` and stop there (`web/src/deadline.ts:23-27`, `android/.../Today.kt:82-85`). A date-only deadline is stored as local midnight, so a job due today is drawn late from 00:00 — red for the whole day it is actually due. `conformance/deadline.json` pins that as a case, named *untimed today counts as overdue past midnight*, `overdue: true`. The rule reverses it to false until the end of that day, so `isOverdue`, its Android twin and the fixture change together, in one commit. **The server already behaves the new way.** `internal/services/item/reminder.go` compares dates, so it rings `JobDue` on the due date and `JobOverdue` only from the next day. This closes a live client/server disagreement rather than adjusting a preference. A timed deadline legitimately keeps a different granularity: the card goes late at 09:45 while the reminder would not ring overdue until the next day. Two mechanisms, two granularities, both correct. Do not "fix" one to match. ## A shared minute ticker Late is derived on the device, so a card visible at 09:44 must flip at 09:45 with no refresh. Nothing does that today: `const now = new Date()` is computed per render (`Jobs.tsx:233`, and the same on Today), and `web/src/clock.ts` holds only `fmtTime`. Needed on both surfaces, plus a wake handler. Small, but new. The screenshot suites pin the browser clock, so a ticker must not reintroduce nondeterminism there. Two rules that ride along: comparisons are always against the timestamp, never a rendered string, and "yesterday" is computed against the reader's local midnight. Blocks the late state in #174 and its wording in #179.
nalum closed this issue 2026-08-26 18:33:42 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
eagraiclainne/app#186
No description provided.