fix: return extension_date regardless of server UTC date
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 4m14s

list_child_tasks used date_type.today() (server UTC) to look up the
TaskExtension record. When the client's local date differed from the
server's UTC date (e.g. user is UTC-5 and it's past midnight UTC),
the lookup returned None and extension_date was incorrectly null.

Fix:
- Add get_extension_for_child_task() to db/task_extensions.py that
  queries by child_id + task_id only, without a date filter, and
  returns the entry with the latest date when multiple exist.
- Update list_child_tasks to use the new function. The comment already
  states 'client does all time math', so returning the stored
  extension_date is correct — the frontend compares it to local date.
- In extend_chore_time, delete any existing extension for the
  child+task before inserting the new one to prevent stale records
  from accumulating across days.
- Add regression test that inserts an extension for yesterday's date
  and asserts extension_date is non-null in the list-tasks response.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-12 01:59:51 +00:00
parent 861b3dc9d4
commit bb7c4c469c
4 changed files with 47 additions and 5 deletions

View File

@@ -30,3 +30,20 @@ def delete_extensions_for_task(task_id: str) -> None:
def delete_extension_for_child_task(child_id: str, task_id: str) -> None:
q = Query()
task_extensions_db.remove((q.child_id == child_id) & (q.task_id == task_id))
def get_extension_for_child_task(child_id: str, task_id: str) -> TaskExtension | None:
"""Return the extension for a child+task without filtering by date.
Avoids timezone mismatches between the server (UTC) and the client's local
date. The caller (or the frontend) is responsible for deciding whether the
returned extension_date is still applicable.
"""
q = Query()
results = task_extensions_db.search(
(q.child_id == child_id) & (q.task_id == task_id)
)
if not results:
return None
latest = max(results, key=lambda r: r.get('date', ''))
return TaskExtension.from_dict(latest)