Co-authored-by: nova28 <17953305+nova28@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
8.0 KiB
status, system, requirements, created, owners
| status | system | requirements | created | owners | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| current | tasks |
|
2026-09-03 |
|
Task priority visibility System Design
Purpose and boundaries
The task system owns the priority value and its update contract. The web board owns only the presentation and the user actions that call this contract. The Office task surface remains a separate consumer with its own vocabulary.
Requirement mapping
| Requirement | Design section |
|---|---|
| REQ-TASKS-PRIORITY-VISIBILITY-001 | Components and responsibilities, Control flow |
| REQ-TASKS-PRIORITY-VISIBILITY-002 | Data and contracts, Control flow |
| REQ-TASKS-PRIORITY-VISIBILITY-003 | Data and contracts, Control flow, Failure and recovery |
| REQ-TASKS-PRIORITY-VISIBILITY-004 | Data and contracts, Persistence |
| REQ-TASKS-PRIORITY-VISIBILITY-005 | Components and responsibilities, Data and contracts, Control flow, Failure and recovery |
Components and responsibilities
- The task service authorizes task writes, validates task fields, and publishes
task.updatedafter a successful mutation. - The task repository stores the task row. Its
TaskPriorityRepository.UpdateTaskPrioritycapability updates onlypriorityandupdated_atfor a priority-only write. Full task updates keep their existing snapshot behavior for requests that change several fields. - The task HTTP and WebSocket handlers keep using the existing task update request and response contracts. No priority-specific endpoint is added.
- The boot-state mapper includes priority in the task snapshot used by the initial kanban render.
- The web task API client uses the shared
TaskPrioritytype. The kanban card renders a non-medium indicator, and the shared card menu sends priority changes through the existing update hook. The Priority submenu uses a leading icon consistent with the other card actions. - The desktop sidebar and the phone or tablet task-navigation surface render the
shared
TaskSwitcher. Its task projection carries priority, its row uses the same task-owned indicator presentation as the kanban card, and its single-task context menu uses the existing priority update hook. The row renders priority in its existing inline badge area after the title, outside the fixed leading state-icon column, so priority presence does not change title alignment. The shared task priority metadata owns token order, localized label keys, indicator shapes and colors; no sidebar-specific priority vocabulary is added. - The task creation dialog sends the selected priority token and uses the same four-token picker inside the Advanced settings section, which is collapsed by default, at every supported breakpoint. On wide layouts, the dependency picker is first and the priority picker starts at the leading edge of the second column. The priority label exposes a localized help description through a fine-pointer tooltip or a coarse-pointer touch disclosure.
- The mobile E2E scenario checks the touch target sizes and the complete create and update flow.
Data and contracts
The canonical task priority type is the four-token set
critical, high, medium, and low. Tokens are stored and sent unchanged.
Labels are resolved from the active locale when the UI renders them.
Task creation and task update requests carry an optional priority token. A
successful update publishes the complete task in task.updated, so every
connected board can replace its task projection. A board refresh that does not
carry priority preserves the existing value in the client projection.
TaskSwitcherItem carries the priority from both task-switcher projection
adapters: the desktop buildSidebarItem path and the phone or tablet
toSheetItem path. Both paths read the same kanbanMulti.snapshots task data.
The task switcher does not store another priority value.
Control flow
Creation follows this path:
Create dialog -> Advanced settings -> priority picker -> task create request -> task service -> task row -> task.created -> board store -> card indicator
The backend applies medium when a create request omits priority. The selected
token is present in the created task and in the event consumed by the board.
Priority changes follow this path:
Card menu -> updateTask hook -> PATCH task -> task service -> field-scoped repository write -> reload -> task.updated -> WebSocket clients -> board store
The service first authorizes and reads the task. For a request that contains
only priority, it uses TaskPriorityRepository.UpdateTaskPriority. The service
then reloads the row and publishes the resulting complete task. Requests that
also change another field continue through the normal full task update path.
Task-switcher changes follow the same mutation path:
Visible task-actions control or desktop right-click -> shared task-switcher menu -> Priority submenu -> updateTask hook -> PATCH task -> task service -> field-scoped repository write -> task.updated -> workflow snapshots -> task-switcher row
The desktop sidebar and mobile task-navigation surfaces share the row and menu implementation. On phones, the visible ellipsis trigger opens the existing responsive context-menu surface inside the task-switcher drawer. No hover, right-click or long press is required. The drawer remains the single scroll owner, and the existing responsive menu styling owns viewport containment, safe-area clearance and 44-pixel action rows.
Failure and recovery
If the priority write fails, the service returns the error and does not publish
task.updated. The web hook reports the error with the existing localized toast,
and the card and task-switcher row keep their last known value. Repeating the
current token is safe and uses the same write and event path. Archived rows and
multi-task selections do not offer this single-task mutation.
The database constraint remains the final guard for values outside the four tokens. User-facing board controls can emit only the canonical tokens.
Persistence
The tasks.priority column, default, and constraint already exist. This design
adds no migration. The field-scoped update changes only priority and
updated_at, so a concurrent priority action cannot replace a stale title,
description, metadata, workflow placement, parent, or position from a task
snapshot.
Security and accessibility
The task service applies the existing task authorization before either update path. Priority tokens are not translated at the API boundary. The card menu, task-switcher menu and creation picker expose localized accessible names. On coarse pointer layouts, the card menu trigger, task-switcher action trigger, menu rows, picker trigger, picker items, and priority help trigger use at least a 44 CSS-pixel hit target while the desktop layout keeps its compact controls. The priority help description is available on hover and focus for fine pointers, and from a touch disclosure for coarse pointers.
Verification
- Backend tests verify the field-scoped repository write preserves other task fields and that the service uses it for a priority-only request.
- The mobile kanban test verifies the 44-pixel hit targets, localized controls,
persistence, and the live
task.updatedresult. - Existing desktop priority tests continue to cover the card indicator, create dialog, both menu triggers, idempotent writes, and remote convergence.
- Task-switcher projection tests verify that desktop and mobile adapters retain priority. Shared row tests verify the non-medium display contract and invalid value fallback. Task-switcher menu tests verify the icon, option order, current marker, selection and archived or multi-selection exclusions.
- Desktop sidebar and mobile task-action Playwright scenarios verify first render, menu reachability, persistence, live convergence, touch target size, viewport containment and the absence of document horizontal overflow.