Schedule chores and replace Pin with "Add to Today"

Changed

Context

The new dashboard (#338) is driven by scheduling: a chore shows on Today only on the day it is due or scheduled, and otherwise in Upcoming or Backlog. Today the only date is field_next_due_date, which is derived (last log date + frequency) by the process_chorenextdue ECA, so there is no way to pick a day for a chore.

Pinning (sticky, toggled by the node_sticky_toggle views field and StickyToggleController in inventory_custom) currently means "needs doing" and is cleared when a log arrives. It overlaps with scheduling.

Decisions

  • Add a chore date field field_scheduled_date that stores only a chosen day. Logging does not clear it: whether a schedule was met is derived (last log date >= scheduled date), so deleting a log (undo) reverts cleanly and no cron job is needed. This follows the "one authoritative value, derive the rest" rule in docs/sites/inventory.md.
  • A missed scheduled day goes back to the backlog. It does not roll over to Today.
  • Pin becomes Add to Today: the same button sets field_scheduled_date to today (and clears it again when it is today). The 2 chores pinned now get converted to today's schedule.
  • No snooze.

Buckets, all derived:

  • Today: scheduled = today, or next due = today, or last logged today (shown as done).
  • Backlog: (next due < today or no next due) and not scheduled >= today. A Once chore that has been logged is excluded. Chores with no due date (never logged, As needed, Once not done yet) live here until they are scheduled or logged.
  • Upcoming: next due > today or scheduled > today.
  • Overdue: next due < today. This overlaps Backlog on purpose; it is a count and a tab.

TODO

  • [ ] Add field_scheduled_date (date only) to chore. Add it to the content Search API index too, if /chores/search should filter on it.
  • [ ] Rework NodeStickyToggle / StickyToggleController into an Add to Today / Remove from Today toggle on field_scheduled_date. Keep the CSRF token, the AJAX view refresh and the redirect when JS is off.
  • [ ] Update hook: set field_scheduled_date = today on chores with sticky = 1, then clear sticky.
  • [ ] Remove the unpin step from process_chorenextdue once nothing reads sticky.
  • [ ] Document the buckets and the new field in docs/sites/inventory.md.

Done when

  • Add to Today on a backlog chore puts it on Today, and pressing it again takes it off.
  • A chore scheduled for yesterday and not logged shows in Backlog, not on Today, with no cron run in between.
  • Logging a chore scheduled for today, then deleting that log, leaves it scheduled and not done for today.
  • sticky is 0 on every chore, and the 2 previously pinned chores are scheduled.
Task type
Project
Parent task