feat(tasks): implement custom task statuses#285
Conversation
- Reorganize documentation into logical directories (build, ci, deployment, entity-development) - Archive implemented RFCs by deleting legacy files - Add comprehensive entity development guide and phase-based documentation - Update README and project structure references to reflect new file locations
Introduces a new task status system allowing users to create, rename, recolor, reorder, and delete custom statuses. Key changes: - Added `TaskStatus` domain model and `ITaskStatusRepository`. - Implemented CRUD commands for task statuses (`SaveTaskStatusCommand`, `DeleteTaskStatusCommand`). - Integrated status management into task lifecycle: - `SaveTaskCommand` now synchronizes `statusId` with `completedAt`. - `TaskTable` schema updated to include `status_id`. - Added UI components for status management: - `TaskStatusesSetting` in task settings. - `StatusSelectionDialog` for task editing. - `StatusAwareCompleteButton` for status-colored checkboxes. - Enhanced Kanban board view to support grouping and columns by status. - Added database migration (v33 to v34) to seed built-in 'To Do' and 'Done' statuses and backfill existing tasks. - Added comprehensive localization support for status-related strings.
Update the database migration to use the quoted "order" column name to avoid conflicts with SQL reserved keywords. Update task-related unit and performance tests to handle the new GetListTaskStatusesQuery within their respective mock mediators.
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive task status management system, allowing users to customize, reorder, and color-code task statuses. The feedback highlights several critical issues: a missing 'modifiedDate' update in 'SaveTaskStatusCommand' that could break peer-to-peer sync, a concurrency bug in the settings UI where a shared debouncer can cause lost edits, potential UI crashes due to unsafe hex color parsing without try-catch blocks across multiple widgets, a missing fallback for deleted status IDs in task queries, and unhandled async errors in the task list refresh logic.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
- Set modifiedDate on status update for P2P sync conflict resolution - Fix shared debounce timer concurrency bug with per-status debouncers - Make hex color parsing robust with try-catch across all status UI components - Add fallback for deleted/invalid status IDs in Kanban grouping - Add error handling for refresh in tasks_list post-frame callbacks
…uses - Extract StatusLoaderMixin to eliminate duplicated _loadStatuses() pattern - Refactor StatusChip and StatusAwareCompleteButton to use StatusLoaderMixin - Decouple StatusChip from task details rebuild cycle via mixin-based status resolution - Fix GetTaskStatusQueryResponse to use standalone DTO instead of extending TaskStatus entity - Add input validation (name length, hex color format) to SaveTaskStatusCommand - Add get_tasks error translations to all 22 locales - Remove unused imports across affected files - Add DB index on task_table.status_id for query performance
Add comprehensive unit tests for new task status CQRS handlers: - SaveTaskStatusCommand (name validation, color format, max count) - DeleteTaskStatusCommand (built-in status protection, reassignment) - GetListTaskStatusesQuery (pagination, includeDeleted) - GetTaskStatusQuery (DTO mapping) Also fix: - Error handling in TaskStatusesSetting widget - Status resolution logging in TaskGroupCreationHandler - Decouple status fetch from task list query - Update existing tests for API changes (removed isDoneStatus param) Addresses architecture review findings M3, M6, M7, M8, H5, H6, M13.
- Move built-in status backfill from presentation to query handler layer - Add TaskStatusDisplay.resolveKey() for single source of truth on empty-name convention - Apply StatusLoaderMixin to StatusSelectionDialog to reduce code duplication - Update TaskGroupCreationHandler to use centralized status resolution logic - Remove duplicate status construction logic from tasks_list presentation layer - Add logging when status resolution fails in TaskGroupCreationHandler Fixes M10, M11, M12, M13, H3, H5, H6 from architecture review.
When switching to board view mode without a grouping selection, the Kanban board displays empty because columns require grouping to be enabled. This fix automatically applies board defaults (grouping by status) when entering board mode if grouping is not already enabled. **Files Changed:** - lib/presentation/ui/features/tasks/pages/tasks_page.dart **Fix Details:** - Updated `_onViewModeChange` to check if grouping is disabled - Applies board sorting defaults (status grouping) when entering board mode - Respects existing grouping configuration if already enabled - Prevents empty Kanban board when switching from list view **Testing:** - ✅ All 299+ tests passing - ✅ No code analysis issues - ✅ Properly formatted **Issue Resolved:** Switching to Kanban board without grouping selection now automatically selects status grouping, ensuring proper column display.
Refactor the task status management system to treat built-in statuses (To Do, Done) as first-class citizens within the domain and persistence layers. Key changes: - Update `DriftTaskStatusRepository` to provide virtual built-in statuses if they are missing from the database, ensuring system stability during migrations. - Implement `existsInDb` in the repository to distinguish between persisted custom statuses and virtual built-in ones. - Modify `SaveTaskStatusCommand` to allow empty names for built-in statuses and ensure they are correctly persisted/updated. - Update `GetListTaskStatusesQuery` to merge database results with guaranteed built-in status items. - Restrict reordering and deletion of built-in statuses in the `TaskStatusesSetting` UI. - Add localized tooltips and UI indicators to clarify the non-deletable nature of built-in statuses.
Reorder and adjust the available sort options in the task list options menu to improve usability. Key changes: - Reorder sort fields to prioritize status, priority, and title. - Add planned date and deadline date sorting options back to the list. - Adjust the sequence of existing sortable fields.
- Add `ReorderTaskStatusesCommand` to allow batch updating of status order. - Implement `updateMultiple` in `IRepository` and `DriftBaseRepository` for efficient batch operations. - Enhance `SaveTaskStatusCommandHandler` to persist built-in statuses when modified. - Update `TaskGroupCreationHandler` to resolve status IDs from translation keys or names. - Add validation for status names (empty/length) and color formats. - Update localization files with new task status error messages. - Improve `TaskStatus` JSON parsing with robust error handling.
🚀 Motivation and Context
Introduce a fully customizable task status system, replacing the hardcoded completed/pending model. Users can now create, rename, recolor, reorder, and delete custom statuses to match their workflow (e.g., 'In Progress', 'Blocked', 'Review', 'Backlog').
⚙️ Implementation Details
TaskStatusentity,TaskStatusConstants(built-in 'To Do'/'Done'), andITaskStatusRepositoryinterfaceSaveTaskStatusCommand,DeleteTaskStatusCommand), queries (GetListTaskStatusesQuery,GetTaskStatusQuery), andtasks_registration.dartwiringDriftTaskStatusRepository, schema update (TaskTable.status_id), database migration (v33→v34) with backfill for existing tasksTaskStatusesSetting(manage in settings),StatusSelectionDialog(pick in task editor),StatusAwareCompleteButton(color-coded checkbox), Kanban board status grouping📋 Checklist for Reviewer
🔗 Related
Implements support for customizable workflow states across the task management module.