Tasks Feature Guide
Guide to the Tasks module — one-off and dated to-dos with due dates, scheduled dates, smart date filtering, subtasks, tags, reminders, and Eisenhower prioritization.
Overview
The Tasks module lets users create to-dos that are organized by three independent date fields — dueDateTime (a deadline), scheduledDateTime (do it on a specific day), and showInListFrom (when the task should start appearing in the list). The server performs smart filtering over these fields so a task surfaces in the right date range, including overdue scheduled tasks that are not yet done. Tasks support subtasks, tags, reminders, priority, and project association. Completion is a single boolean toggle (done) recorded with a doneDateTime, not a per-occurrence flag like Habits. The client uses a stale-while-revalidate cache and reacts to domain events so completing, rescheduling, or editing a task refreshes related screens automatically.
Architecture
TasksRepositoryImpl reads from the local Room cache first and revalidates from the server in the background, so the UI renders immediately and updates when fresh data arrives.
Data Models
The Task model also carries clearFields (a list of field names to explicitly null on PATCH) and subtasks (omitted/null = leave unchanged, empty list = clear all).
ReminderType Enum
| Value | Meaning |
|---|---|
NOTIFICATION | Local/push notification (default) |
EMAIL | Email reminder |
SMS | SMS reminder |
A task with no explicit
Reminderrow still gets a “task starting soon” push when its anchor (scheduledDateTime ?? dueDateTime) falls withinUserSettings.defaultTaskReminderOffsetMinutes(default 15,0to disable). See Default reminder offsets.
SortOption (client TaskState)
| Value | Sorts by |
|---|---|
EISENHOWER | Eisenhower matrix (urgency × importance) — default |
DUE_DATE | Due date |
PRIORITY | Priority value |
NAME | Name (alphabetical) |
CREATED | Created date |
TaskFilters (date-range presets)
TODAY, THIS_WEEK, NEXT_WEEK, THIS_MONTH — each maps to a Pair<startDate, endDate> via getDateRangeByFilter().
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /tasks | List tasks (filter, limit/offset, date, withOverdue, tagSlug, projectId, sortOption, ignoreShowInListFrom, includeMeta) |
GET | /tasks/byDateRange | List tasks between startDate and endDate (no smart filtering) |
GET | /tasks/byDateRangeWithSmartFiltering | Smart-filtered range list (withOverdue, currentDateTime, includeCompleted, includeUndated, returns virtual rows when includeMeta) |
GET | /tasks/noDueDate | Tasks with no dueDateTime; completions older than 7 days excluded |
GET | /tasks/{id} | Get task detail |
POST | /tasks | Create task (CreateTaskDTO) — 201 Created |
PATCH | /tasks/{id} | Update task (UpdateTaskDTO) |
DELETE | /tasks/{id} | Delete task |
PATCH | /tasks/{id}/complete | Mark complete — datetime query param required and validated |
PATCH | /tasks/{id}/uncomplete | Undo completion |
PUT | /tasks/{id}/tags | Replace all tags on a task (UpdateTaskTagsDTO) |
POST | /tasks/{id}/tags/{tagId} | Attach a single tag |
DELETE | /tasks/{id}/tags/{tagId} | Detach a single tag |
POST | /tasks/import/preview | AI import preview (parse free text / tabular into tasks) |
POST | /tasks/import | Commit AI-parsed task import |
POST | /tasks/tags/ai/preview | AI tag-suggestion preview |
POST | /tasks/tags/ai/apply | Apply AI tag suggestions |
All date/time parameters (date, startDate, endDate, datetime, currentDateTime) use the dd/MM/yyyy HH:mm format and are validated server-side (Validator.isValidDateTimeFormat). The X-Platform header (DESKTOP/MOBILE) gates feature flags used when building virtual task rows.
State Machine
Completion is a single done boolean (with a recorded doneDateTime) — unlike Habits, there is no per-occurrence completion. RescheduleTask moves whichever of showInListFrom, dueDateTime, and scheduledDateTime are set forward to tomorrow at the original time, leaving null fields null.
Client Behavior
TaskViewModel subscribes to the DomainEventBus and re-fetches on TaskCreated, TaskUpdated, TaskCompleted, TaskUncompleted, TaskDeleted, and TaskRescheduled. A fetch generation counter discards stale results when overlapping refreshes race.
Key Files
| File | Purpose |
|---|---|
shared/.../models/Task.kt | Task, TaskSubtask, Reminder, ReminderType models |
shared/.../models/Tag.kt | Tag / tag request models |
shared/.../models/TaskFilters.kt | Date-range filter presets (TODAY, THIS_WEEK, …) |
shared/.../services/tasks/TaskService.kt | Ktor HTTP client for task endpoints |
tasks/tasks_domain/.../repository/TasksRepository.kt | Repository interface |
tasks/tasks_domain/.../use_cases/TaskUseCases.kt | Aggregated use cases (get/add/complete/reschedule/…) |
tasks/tasks_domain/.../use_cases/RescheduleTask.kt | Reschedule-to-tomorrow logic |
tasks/tasks_data/.../repository/TasksRepositoryImpl.kt | SWR repository (local Room + remote) |
tasks/tasks_presentation/.../viewmodel/TaskViewModel.kt | MVI ViewModel + event-bus refresh |
tasks/tasks_presentation/.../viewmodel/state/TaskState.kt | TaskState + SortOption |
server/.../routing/TasksRouting.kt | REST endpoints + date validation |
server/.../service/TaskService.kt | Server-side task logic / smart filtering |
Testing
- Unit:
RescheduleTask— verify only non-null date fields shift to tomorrow at the original time;SortOptionordering (Eisenhower vs due date). - Server smart filtering:
TaskSmartFilteringTest,TaskPendingVisibilityTest—dueDate >= startDateinclusion, overdue scheduled tasks withwithOverdue, andshowInListFromvscurrentDateTimevisibility window. - Import:
TaskTextImportParserTest,TaskTabularImportParserTest,TaskImportDefaultDueTest,TaskReminderImportParseTest— AI/import parsing edge cases. - Integration: complete/uncomplete toggling;
/tasks/noDueDateexcluding completions older than 7 days.
Troubleshooting
Task not appearing for today
- A
dueDateTimetask shows only ifdueDateTime >= startDate; check the requested range. - If
showInListFromis set, the task stays hidden untilshowInListFrom <= min(currentDateTime, endDate 23:59)— sendcurrentDateTimeso same-day windows behave correctly. - A
scheduledDateTimetask only shows on that date unless it is overdue, not done, andwithOverdue=true.
Overdue scheduled task missing
- Overdue scheduled tasks require
withOverdue=true(the default). If “hide overdue” is on, they are suppressed.
Complete request returns 400
- The
datetimequery param is required onPATCH /tasks/{id}/completeand must matchdd/MM/yyyy HH:mm; an invalid or missing value returns400.
Edited task field not clearing
- On PATCH, a null/omitted field is left unchanged. To explicitly null a field, include its name in
clearFields. For subtasks, send an empty list to clear all.
Stale list after completing/editing
- Refresh is driven by
DomainEventBusevents; if a screen does not update, confirm it subscribes to the relevantDomainEvent.Task*event. The SWR cache may briefly show local data before the server revalidation completes.
API Endpoints
All endpoints require JWT authentication and are prefixed with /api/v1. See server/README.md for full reference.
| Method | Path | Description |
|---|---|---|
GET | /tasks | List tasks (filterable by date, tagSlug, projectId, sortOption) |
GET | /tasks/byDateRange | List tasks in a date range |
GET | /tasks/noDueDate | List tasks with no due date |
POST | /tasks | Create a task |
POST | /tasks/import/preview | Preview AI-powered task import from text |
POST | /tasks/import | Import tasks via AI from natural language |
POST | /tasks/tags/ai/preview | Preview AI-suggested tags |
POST | /tasks/tags/ai/apply | Apply AI-suggested tags |
GET | /tasks/{id} | Get task by ID |
PATCH | /tasks/{id} | Update task |
DELETE | /tasks/{id} | Delete task |
PATCH | /tasks/{id}/complete | Mark task as complete |
PATCH | /tasks/{id}/uncomplete | Mark task as incomplete |
PUT | /tasks/{id}/tags | Replace all tags on a task |
Related Docs
- Task logic — server-side smart filtering algorithm (dueDate, scheduledDate, showInListFrom, withOverdue)
- Habits — recurrence and per-occurrence completion (contrast with Tasks)
- Calendar — how task dates map onto calendar days
- Domain & models — shared domain model reference
- UI & UX — task screen layouts and interactions
- Testing & QA — testing strategy