The web edit/create/quick-add views and the sync endpoint assigned
due_date/due_time/reminder_at straight from request data as raw strings.
Django tolerates this at save() (types get coerced deep in the SQL
layer), but the in-memory instance keeps the raw strings afterward.
Task.reschedule_reminders(), added for per-task reminders and run from
save() on that same instance, was the first code to actually operate on
those fields before a page reload and crashed with a TypeError - which
the service worker's 5xx-treated-as-offline fallback then masked as a
misleading "you're offline" screen instead of a real error.
Fixed by parsing with Django's parse_date/parse_time/parse_datetime at
the point these values are read from the request/payload in
tasks/views.py and sync/views.py, rather than trusting raw strings.
5 new regression tests exercise the actual views/endpoint with raw
date/time strings and assert proper types land on the model.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Fixes subtasks appearing flattened into the main task list (missing
parent filter), and adds everything else needed for full offline
functionality: tag chips/assignment/creation, full field editing
(description, due time, recurrence presets), time tracking with a
live-updating timer, and properly nested subtasks -- all queued
locally and synced via the existing /api/sync/ protocol.
The offline page now reuses the real dashboard's app-layout/header/
sidebar/detail-pane structure instead of a bespoke layout, with an
amber-tinted header and banner so it's unmistakable which mode you're
in. The detail panel mirrors _task_detail.html's fields and actions.
Also fixes a real backend gap this feature depends on: apply_conflict_data()
in sync/views.py silently no-op'd on time_entry conflicts. And computes
duration_seconds client-side on merge, since TimeEntrySyncSerializer
doesn't include it in the wire format at all.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Lets users create, edit, and complete tasks with no network connection,
queued locally in IndexedDB and replayed via the existing /api/sync/
protocol once back online -- the same protocol the native Android app
already uses, with zero backend changes. The service worker now routes
the dashboard's offline fallback to a small client-rendered task app
instead of the generic "you're offline" page; every other route keeps
the generic fallback.
Conflicts (server row touched elsewhere since last sync) auto-resolve
as "local wins" rather than surfacing a resolution UI. Scope is title/
status/priority/due-date only -- tags, subtasks, time tracking, and
recurrence editing offline are out of scope for this phase.
Also adds the first real test coverage for sync/views.py (previously
untested): new-item creation, soft-delete-bypasses-conflict-check,
conflict detection/discarding, and both resolve_conflict paths.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Features:
- Django-based REST API with web interface
- Task management with tags, priorities, and due dates
- Time tracking with start/stop timers
- Subtasks support
- Task filtering (all, today, upcoming, overdue, completed)
- Tag-based organization with color coding
- Sorting by due date and priority
- Auto-assign tags when filtering
- Responsive 3-pane layout (sidebar, task list, detail panel)
- Task sharing between users
- Mobile-responsive design with dark mode support
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>