Skip to content

feat(tasks): adopt Office-style /tasks list UX#1593

Merged
carlosflorencio merged 12 commits into
mainfrom
feature/new-list-ux-tasks-als
Jul 3, 2026
Merged

feat(tasks): adopt Office-style /tasks list UX#1593
carlosflorencio merged 12 commits into
mainfrom
feature/new-list-ux-tasks-als

Conversation

@carlosflorencio

@carlosflorencio carlosflorencio commented Jul 3, 2026

Copy link
Copy Markdown
Member

Summary\n- Replace the kanban-style /tasks table layout with an Office-like list page (toolbar + bordered rows + pagination).\n- Move search into the list toolbar so it is always visible/usable in mobile flows.\n- Preserve existing task behavior (create, archive, delete, navigation, pagination) while reusing current task data/actions.\n- Split page orchestration and rendering into tasks-page-client.tsx and tasks-list-view.tsx to keep client file size in bounds.\n- Update mobile and desktop Playwright specs to target the new list-row/list container DOM model (no table semantics).\n- Cleanup mobile search state on mount/unmount to avoid stale open state after removing topbar search UI.\n\n## Validation\n- Web lint (changed files only): passed\n- New and existing Playwright specs for task list flows were updated and aligned to new interactions.

Review in cubic

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds persisted task-list sort/group preferences from backend settings through task listing, boot data, SSR, client state, list UI, and e2e coverage. Also adds hideTitle support to kanban headers and lowers the narrow-header breakpoint.

Changes

Tasks list sort/group preferences

Layer / File(s) Summary
Backend settings types
apps/backend/internal/user/models/models.go, apps/backend/internal/user/dto/dto.go, apps/backend/pkg/api/v1/user.go
Adds TasksListSort and TasksListGroup fields to backend settings types and maps them through DTO conversion.
Validation and persistence
apps/backend/internal/user/models/tasks_list_preferences.go, apps/backend/internal/user/service/service.go, apps/backend/internal/user/controller/controller.go, apps/backend/internal/user/service/service_test.go
Adds sort/group allow-lists, normalization helpers, PATCH handling, event payload fields, controller pass-through, and validation tests.
SQLite settings storage
apps/backend/internal/user/store/sqlite.go
Stores and loads tasks_list_sort and tasks_list_group in user settings JSON with normalization and defaults.
Task listing sort contract
apps/backend/internal/task/repository/interface.go, apps/backend/internal/office/service/service.go, apps/backend/internal/task/handlers/task_http_handlers.go, apps/backend/internal/task/repository/sqlite/task.go, apps/backend/internal/task/service/service_tasks.go, apps/backend/internal/task/repository/task_repository_test.go, apps/backend/internal/task/repository/sqlite/task_order_test.go
Extends ListTasksByWorkspace with a sort parameter and applies SQL ordering based on it, with tests covering ordering before pagination and dialect-specific title sorting.
ListTasksByWorkspace callers and stubs
apps/backend/internal/office/service/workspace_deletion.go, apps/backend/internal/office/service/workspace_deletion_test.go, apps/backend/internal/task/service/service_resources.go, apps/backend/internal/task/service/service_pr_search_test.go, apps/backend/internal/task/service/handoff_workspace_test.go, apps/backend/internal/orchestrator/executor/executor_mocks_test.go, apps/backend/internal/task/handlers/process_handlers_test.go, apps/backend/internal/backendapp/e2e_reset.go, apps/backend/internal/office/service/event_subscribers_fallback_test.go, apps/backend/internal/task/repository/archive_repository_test.go
Updates remaining callers, mocks, and tests to the extended ListTasksByWorkspace signature.
Boot state task preferences
apps/backend/internal/backendapp/boot_state_routes.go
Derives effective sort/group values from query params and settings, exposes them in boot data and user-settings state, and passes sort into task loading.
Web settings and SSR fields
apps/web/lib/types/http-user-settings.ts, apps/web/src/boot-payload.ts, apps/web/hooks/use-ensure-user-settings.test.ts, apps/web/e2e/helpers/api-client.ts, apps/web/lib/state/slices/settings/types.ts, apps/web/lib/state/slices/settings/settings-slice.ts, apps/web/components/settings/editors-settings-state.tsx, apps/web/hooks/use-user-display-settings.ts, apps/web/lib/ssr/user-settings.ts
Adds task-list preference fields and defaults to web settings types, slices, SSR parsing, and editor settings mapping.
Task list options utilities
apps/web/lib/tasks/tasks-list-options.ts
Adds sort/group option constants, parsers, ordering helpers, and state ordering.
Tasks list UI and pagination
apps/web/app/tasks/tasks-list-view.tsx, apps/web/app/tasks/tasks-pagination.tsx
Adds the hierarchical grouped tasks list view, controls, row actions, and pagination UI.
Tasks page client wiring
apps/web/app/tasks/tasks-page-client.tsx
Reworks client state, task fetching, URL sync, preference persistence, and rendering around the new list view.
Tasks page SSR and API sort wiring
apps/web/app/tasks/page.tsx, apps/web/app/actions/workspaces.ts, apps/web/lib/api/domains/kanban-api.ts, apps/web/src/spa-routes.tsx
Resolves preferences server-side, forwards sort through the task-listing API path, and seeds the client with sorted initial tasks and preference props.
Tasks list e2e coverage
apps/web/e2e/tests/task/*.spec.ts
Updates task-list locators to use tasks-list and adds coverage for sort, grouping, pagination, and persistence flows.

Kanban header hideTitle and breakpoint

Layer / File(s) Summary
Header hideTitle and breakpoint
apps/web/components/kanban/kanban-header.tsx, apps/web/components/kanban/kanban-header-mobile.tsx, apps/web/e2e/tests/kanban/kanban-board.spec.ts
Adds hideTitle support across kanban header variants, suppresses title/back chrome when hidden, lowers the narrow-header threshold from 1100 to 800, and updates matching e2e assertions.

Estimated code review effort: 4 (Complex) | ~70 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TasksPage
  participant TasksPageClient
  participant listTasksByWorkspaceAction
  participant Service
  participant Repository
  participant TasksListOptions

  TasksPage->>TasksPageClient: initialSort and initialGroup
  TasksPageClient->>TasksListOptions: parseTasksListSort / parseTasksListGroup
  TasksPageClient->>listTasksByWorkspaceAction: fetch tasks with sort
  listTasksByWorkspaceAction->>Service: ListTasksByWorkspace(..., sort, ...)
  Service->>Repository: ListTasksByWorkspace(..., sort, ...)
  Repository->>TasksListOptions: NormalizeTasksListSort
  Repository-->>Service: ordered tasks
  Service-->>TasksPageClient: tasks and total
Loading

Possibly related PRs

  • kdlbs/kandev#612: Both PRs touch the task-listing request path from HTTP handler through repository SQL ordering.
  • kdlbs/kandev#1268: Both PRs modify Service.ListTasksByWorkspace and its task-query handling.
  • kdlbs/kandev#1547: Both PRs update the workspace-deletion code path that calls ListTasksByWorkspace.

Poem

A rabbit hopped through rows that sort,
By title, state, or grouped report.
The list now keeps its chosen way,
And remembers what I like each day. 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers summary and validation, but it omits the required Checklist section and doesn't match the template format. Add the Checklist section with the required items and format the summary as prose per the template; include any missing required sections.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly describes the main change: replacing the /tasks UI with an Office-style list experience.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/new-list-ux-tasks-als

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 2m 57s —— View job


Code Review

  • Gather context and read changed files
  • Review tasks-list-view.tsx (new component)
  • Review tasks-page-client.tsx (modified)
  • Review E2E test changes
  • Post inline comments and summary

Clean split — the new TasksListView handles all rendering and the orchestration hook chain in tasks-page-client.tsx stays unchanged in behaviour. Two issues and one nit worth addressing:

Issues (inline)

  • Tooltip on disabled Delete button (tasks-list-view.tsx ~line 331) — when isDeleting is true the <Button disabled> drops pointer events, so the "Delete" tooltip silently never fires. AGENTS.md specifies wrapping the disabled button in a focusable span on TooltipTrigger. Low-priority since the spinner is sufficient feedback, but it's a divergence from the established codebase convention.
  • Pagination shown for single-page results (tasks-list-view.tsx line 384) — the total === 0 guard hides pagination when there are no tasks, but when all tasks fit on one page (pageCount === 1) both nav buttons render as disabled with no actionable purpose. if (total === 0 || pageCount <= 1) return null cleans this up.

Nit (not inline-commentable — unchanged context line)

useTasksPageSetup (line 342 of tasks-page-client.tsx) still returns debouncedQuery in its spread, but TasksPageClient no longer uses it (it was previously forwarded to KanbanHeader as isSearchLoading). Dropping it from the return keeps the hook's public surface tight.

What looks good

  • Correct memoization of workflowMap/stepMap/repoMap inside TaskRows avoids repeated Map construction.
  • stopPropagation on the actions container correctly prevents archive/delete clicks from triggering row navigation.
  • role="button" + tabIndex={0} + the event.target !== event.currentTarget guard in onKeyDown is the right keyboard-navigation pattern for a clickable row with inner focusable controls.
  • Both mount and unmount cleanup of setMobileSearchOpen(false) correctly prevents stale mobile-search state when navigating to/from /tasks.
  • Using linkToTask instead of an inline /tasks/${task.id} string is the right call.
  • E2E spec replacement is minimal and correct — old tests relied on getByRole("table") and the mobile search-toggle flow, which no longer exist; new tests target the new tasks-list testid and the always-visible toolbar search.

Comment thread apps/web/app/tasks/tasks-list-view.tsx
Comment thread apps/web/app/tasks/tasks-list-view.tsx Outdated
@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces the kanban-style /tasks table with an Office-like list view (toolbar + bordered rows + pagination), splits the page into tasks-page-client.tsx (orchestration) and tasks-list-view.tsx (rendering), and adds server-side sort/group preferences persisted on the user-settings model. The backend ListTasksByWorkspace now accepts a sort parameter, resolves it to a validated SQL ORDER BY clause, and the search subquery is refactored to a derived-table pattern so the sort can be applied after DISTINCT.

  • Server-side sort is wired end-to-end: boot route, HTTP handler, service, and SQLite repository all forward the sort param, resolving the previous per-page client sort inconsistency.
  • Sort/group preferences round-trip via URL params and updateUserSettings, with the useTasksListPreferenceSync hook keeping local state, URL, and backend in sync.
  • New TasksPagination component adds first/last/prev/next navigation with an ellipsis-style page number algorithm and a rows-per-page selector.

Confidence Score: 5/5

Safe to merge — the core sort/group preference flow is correctly wired end-to-end (URL params → boot route → HTTP handler → repository ORDER BY → client state), and the previous per-page sort inconsistency is resolved.

The server-side sort is validated before interpolation into SQL, pagination arithmetic is correct, and the preference-sync hook handles URL/state/backend consistency without introducing loops or dropped fetches. The only notable scope question is the intentional kanban search bar repositioning introduced alongside the tasks page change.

apps/web/components/kanban/kanban-header.tsx — the centerSearch condition change affects the kanban board search placement, not just the new tasks page. Confirm this was intentional for the kanban UX.

Important Files Changed

Filename Overview
apps/web/app/tasks/tasks-list-view.tsx New file — renders the list view with sections, task rows, actions, and grouping/sort controls. The buildTaskTree function's second pass over all tasks silently handles cyclic parent-child references but this intent is undocumented.
apps/web/app/tasks/tasks-page-client.tsx Orchestration layer for the tasks page — manages fetch, sort/group sync with URL and user settings, workspace/workflow/repo filters. Sort is correctly forwarded to the API, resolving the previous per-page sort inconsistency.
apps/web/app/tasks/tasks-pagination.tsx New pagination component with first/last/prev/next buttons, ellipsis page numbers, and rows-per-page select. Logic is correct.
apps/backend/internal/task/repository/sqlite/task.go Adds server-side sort with a refactored taskScanColumns table, taskListOrderBy helper, and a derived-table wrapper for searchTasks so ORDER BY can be applied after DISTINCT. Validated sort strings are correctly used in the ORDER BY expression.
apps/backend/internal/user/models/tasks_list_preferences.go New file — defines sort/group enum constants, validation helpers, and normalize functions. Clean and well-structured.
apps/web/components/kanban/kanban-header.tsx Adds hideTitle prop and changes DesktopHeader search placement from actions area on non-home pages to centered on all pages when not narrow — a behavioral change to the kanban board, not just the tasks page.
apps/web/lib/tasks/tasks-list-options.ts New shared module defining sort/group option constants, parse helpers, and client-side sortTasksForList used for optimistic updates before fetch resolves.
apps/backend/internal/backendapp/boot_state_routes.go Boot data now resolves tasksListSort and tasksListGroup from URL params (with fallback to user settings), passes sort to tasksForWorkspace, and includes both in the route data payload.
apps/web/src/spa-routes.tsx TasksDataRoute now resolves initialSort/initialGroup from URL → boot payload → user settings, and applies sortTasksForList to the SSR-provided tasks for consistent initial render.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant TasksPageClient
    participant useTasksListPreferenceSync
    participant BackendAPI
    participant UserSettings

    User->>TasksPageClient: Change sort / group
    TasksPageClient->>useTasksListPreferenceSync: handleSortChange(sort)
    useTasksListPreferenceSync->>TasksPageClient: setTasksListSort(sort)
    useTasksListPreferenceSync->>TasksPageClient: setTasks(sortTasksForList) [optimistic]
    useTasksListPreferenceSync->>TasksPageClient: "setPagination(pageIndex=0)"
    useTasksListPreferenceSync->>TasksPageClient: writeUrl(sort, group)
    useTasksListPreferenceSync->>UserSettings: "updateUserSettings({tasks_list_sort, tasks_list_group})"
    TasksPageClient->>BackendAPI: "listTasksByWorkspace({sort, page: 1})"
    BackendAPI-->>TasksPageClient: "{tasks (server-sorted), total}"
    TasksPageClient->>TasksPageClient: setTasks(result.tasks) [replaces optimistic]

    Note over User,UserSettings: On next page load (SSR boot)
    User->>BackendAPI: "GET /tasks?sort=title_asc"
    BackendAPI->>BackendAPI: tasksListSortForRoute(query, settings)
    BackendAPI-->>User: "{tasks (sorted), tasksListSort, tasksListGroup}"
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant TasksPageClient
    participant useTasksListPreferenceSync
    participant BackendAPI
    participant UserSettings

    User->>TasksPageClient: Change sort / group
    TasksPageClient->>useTasksListPreferenceSync: handleSortChange(sort)
    useTasksListPreferenceSync->>TasksPageClient: setTasksListSort(sort)
    useTasksListPreferenceSync->>TasksPageClient: setTasks(sortTasksForList) [optimistic]
    useTasksListPreferenceSync->>TasksPageClient: "setPagination(pageIndex=0)"
    useTasksListPreferenceSync->>TasksPageClient: writeUrl(sort, group)
    useTasksListPreferenceSync->>UserSettings: "updateUserSettings({tasks_list_sort, tasks_list_group})"
    TasksPageClient->>BackendAPI: "listTasksByWorkspace({sort, page: 1})"
    BackendAPI-->>TasksPageClient: "{tasks (server-sorted), total}"
    TasksPageClient->>TasksPageClient: setTasks(result.tasks) [replaces optimistic]

    Note over User,UserSettings: On next page load (SSR boot)
    User->>BackendAPI: "GET /tasks?sort=title_asc"
    BackendAPI->>BackendAPI: tasksListSortForRoute(query, settings)
    BackendAPI-->>User: "{tasks (sorted), tasksListSort, tasksListGroup}"
Loading

Reviews (9): Last reviewed commit: "fix(tasks): address list review comments" | Re-trigger Greptile

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/web/app/tasks/tasks-list-view.tsx Outdated
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 2m 12s —— View job


Code Review

  • Read changed files and PR diff
  • Review tasks-list-view.tsx
  • Review tasks-page-client.tsx
  • Review E2E test changes
  • Check previous review feedback was addressed
  • Post inline comments and summary

Findings

Blocker (must fix before merge)

  1. Dead file columns.tsx left behindapps/web/app/tasks/columns.tsx
    • Issue: columns.tsx is still present in the directory but no longer imported anywhere in the codebase. The refactor removed the getColumns/DataTable wiring from tasks-page-client.tsx but left the source file on disk.
    • Why: Dead files accumulate over PRs and confuse future contributors who grep imports or look at the directory listing. Greptile independently flagged this too.
    • Fix: git rm apps/web/app/tasks/columns.tsx in this PR.

Suggestion (recommended, doesn't block)

  1. debouncedQuery leaked into useTasksPageSetup's return valuetasks-page-client.tsx:342
    • return { ...viewState, ...ops, ...computed, activeWorkspaceId, debouncedQuery } exports debouncedQuery but TasksPageClient never reads s.debouncedQuery — it's an artifact of the removal of the old KanbanHeader isSearchLoading prop. Dropping it from the return keeps the hook's public surface tight.

What the previous review flagged — both addressed ✅

  • Tooltip on disabled Delete button (commit 22036f1): <span tabIndex={isDeleting ? 0 : -1} className="inline-flex"> wrapper is now in place at line 333.
  • Pagination hidden for single-page results (commit 22036f1): if (total === 0 || pageCount <= 1) return null is now at line 386.

What looks good

  • Correct useMemo for workflowMap/stepMap/repoMap inside TaskRows — avoids Map reconstruction on every render.
  • stopPropagation on the actions container correctly prevents archive/delete clicks from bubbling to row navigation.
  • event.target !== event.currentTarget guard in onKeyDown is the right keyboard-navigation pattern for a clickable row with inner focusable controls.
  • Both mount and unmount cleanup of setMobileSearchOpen(false) correctly prevents stale mobile-search state.
  • linkToTask used for row navigation instead of inline string construction.
  • E2E specs correctly adapted to the new tasks-list / toolbar-search DOM model.

Summary

Severity Count
Blocker 1
Suggestion 1

Verdict: Blocked — delete columns.tsx first, then ready to merge.

@carlosflorencio carlosflorencio force-pushed the feature/new-list-ux-tasks-als branch from 22036f1 to 464e129 Compare July 3, 2026 17:27
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 3m 28s —— View job


Code Review

  • Gather context and read changed files
  • Read SKILL.md for review guidelines
  • Review tasks-list-view.tsx (new component)
  • Review tasks-page-client.tsx (modified)
  • Review kanban-header.tsx (modified)
  • Review E2E test changes
  • Check previous review feedback was addressed

Findings

Blocker (must fix before merge)

  1. Dead file columns.tsx left behindapps/web/app/tasks/columns.tsx
    • Issue: columns.tsx still exists on disk. The refactor removed the import { getColumns } from "./columns" line and the DataTable wiring from tasks-page-client.tsx, but the source file was never deleted. No file anywhere in the repo imports it.
    • Why: Dead files accumulate over PRs and mislead future contributors reading the directory or searching for ColumnDef patterns. This was flagged as a blocker in the previous review and remains unaddressed.
    • Fix: git rm apps/web/app/tasks/columns.tsx in this PR.

What the previous review flagged — both addressed ✅

  • Tooltip on disabled Delete button: <span tabIndex={isDeleting ? 0 : -1} className="inline-flex"> wrapper is correctly in place at tasks-list-view.tsx:344.
  • Pagination hidden for single-page results: if (total === 0 || pageCount <= 1) return null is correctly at tasks-list-view.tsx:397.

What looks good

  • buildTaskNodes is correct and O(n): the visited set prevents infinite loops on circular parent references and prevents double-appending when a child's parent is on a different page.
  • useMemo on workflowMap/stepMap/repoMap inside TaskRows avoids Map reconstruction on every render.
  • stopPropagation on the actions container correctly gates archive/delete from bubbling to row navigation.
  • event.target !== event.currentTarget guard in onKeyDown is the right keyboard-navigation pattern for a clickable row with inner focusable elements.
  • Both mount and unmount cleanup of setMobileSearchOpen(false) correctly prevents stale mobile-search state when navigating to/from /tasks.
  • linkToTask used for row navigation instead of inline string construction.
  • Narrowing DESKTOP_HEADER_NARROW_PX from 1100 → 800 and removing the isHome guard in DesktopHeader correctly makes search always centered on desktop for both / and /tasks.
  • E2E specs correctly adapted: getByRole("table")getByTestId("tasks-list"), hierarchy test asserts data-level attributes, mobile search toggle behavior still covered.
  • All imports in tasks-page-client.tsx are used (MobileSearchBar, useResponsiveBreakpoint, debouncedQuery via s.debouncedQuery in isSearchLoading prop).

Summary

Severity Count
Blocker 1
Suggestion 0

Verdict: Blocked — delete columns.tsx first, then ready to merge.

@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 1m 57s —— View job


Code Review

  • Gather context and read SKILL.md
  • Check current state of changed files
  • Check for columns.tsx (previously flagged as blocker)
  • Review tasks-list-view.tsx
  • Review tasks-page-client.tsx
  • Review kanban-header.tsx
  • Review E2E test changes
  • Post inline comments and summary

Findings

Blocker (must fix before merge)

  1. Dead file columns.tsx left behindapps/web/app/tasks/columns.tsx
    • Issue: columns.tsx is still on disk and is not imported by anything in the codebase. The getColumns/DataTable wiring was removed from tasks-page-client.tsx in this PR, but the file was never deleted. Verified: grepping for any import of columns in apps/web/app/tasks/ returns no matches.
    • Why: Dead files mislead contributors reading the directory or searching for ColumnDef patterns. This has been flagged as a blocker in all three prior reviews and remains unaddressed.
    • Fix: git rm apps/web/app/tasks/columns.tsx in this PR.

What looks good

  • Previous review issues resolved ✅ — tooltip focusable-span wrapper for disabled Delete button (tasks-list-view.tsx:344) and single-page pagination guard (if (total === 0 || pageCount <= 1) return null at line 397) are both correctly in place.
  • debouncedQuery is not dead — the previous suggestion to drop it from useTasksPageSetup's return was incorrect; s.debouncedQuery is consumed at tasks-page-client.tsx:310 via isSearchLoading={s.isLoading && !!s.debouncedQuery}.
  • buildTaskNodes is correct — the visited set prevents infinite loops on circular parent references; the second for (const task of tasks) loop ensures cross-page orphans (parent on a different page) still render at level 0.
  • useMemo on workflowMap/stepMap/repoMap avoids Map reconstruction on every render.
  • stopPropagation on the actions container correctly prevents archive/delete clicks from bubbling to row navigation.
  • event.target !== event.currentTarget guard in onKeyDown is the right keyboard-navigation pattern for a clickable row with inner focusable controls.
  • Mount and unmount cleanup of setMobileSearchOpen(false) correctly prevents stale mobile-search state when navigating to/from /tasks.
  • Threshold change and isHome guard removal in kanban-header.tsxDESKTOP_HEADER_NARROW_PX lowered from 1100 → 800 and the isHome condition removed from centerSearch, so the centered search input now shows on both / and /tasks when the header is wide enough. isHome is still used for backLabel/variant — not dead.
  • E2E specs correctly adapted: getByRole("table")getByTestId("tasks-list"), new hierarchy test asserts data-level attributes, kanban-board spec has comment-only updates reflecting the new threshold.
  • File size — all three modified files are within the 600-line limit (434 / 334 / 373 lines).
  • No architecture violations — no direct data fetching in components, shadcn imports from @kandev/ui, store-based data flow preserved.

Summary

Severity Count
Blocker 1
Suggestion 0

Verdict: Blocked — git rm apps/web/app/tasks/columns.tsx and push, then ready to merge.

@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 1s —— View job


I'll analyze this and get back to you.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/web/app/tasks/page.tsx (1)

55-90: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Pass the selected sort through the tasks fetch

apps/web/app/tasks/page.tsx and apps/web/app/tasks/tasks-page-client.tsx both sort only the fetched page in memory. With pageSize: 25, options like “Created oldest” only reorder the current slice, so pagination and the overall task order stay inconsistent. Thread tasksListSort into listTasksByWorkspaceAction/backend sorting instead of re-sorting the returned batch.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/app/tasks/page.tsx` around lines 55 - 90, The tasks list is only
being sorted after fetching a single page, so pagination and “Created
oldest”/similar options stay inconsistent. Update fetchWorkspaceData in
tasks/page.tsx and the data flow from tasks-page-client.tsx to pass
tasksListSort into listTasksByWorkspaceAction so the backend applies the sort
before pagination. Keep sortTasksForList only if needed for a final stable pass,
but do not rely on it to reorder the fetched batch.
apps/web/app/tasks/tasks-page-client.tsx (1)

69-100: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Push task sorting into the API request

listTasksByWorkspace already supports sort/order, but this code re-sorts only the current page after pagination and refetches on every sort change. That makes “Sort by …” and “Group by …” page-local on multi-page workspaces. Pass the selected sort through the request and drop the extra client-side resorting; grouping should be handled over the full result set if it’s meant to be global.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/app/tasks/tasks-page-client.tsx` around lines 69 - 100, The task
list is being sorted only after fetching the current page, which makes sorting
and grouping page-local instead of applying across the full workspace result
set. Update the data load in tasks-page-client.tsx so listTasksByWorkspace
receives the selected sort/grouping via its supported sort/order parameters, and
remove the extra client-side sort call in the load flow. Keep the existing fetch
logic in the same effect/useCallback area and ensure tasksListSort is translated
into the API request rather than reordering result.tasks after pagination.
🧹 Nitpick comments (3)
apps/web/e2e/tests/kanban/kanban-board.spec.ts (1)

50-62: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Stale "1100px" references left after breakpoint change to 800.

Lines 52 and 58-59 still describe the old ~1100px narrow threshold and reasoning ("now leaves the header below the 1100px narrow threshold even with no preview open"), even though DESKTOP_HEADER_NARROW_PX is now 800 (kanban-header.tsx Line 47). With the lowered threshold, a default 1280px viewport (~960px header width after the sidebar) would no longer be "below threshold," so this explanation is now inaccurate and could mislead future readers about why the test forces a wider viewport.

📝 Suggested comment update
-  // preview panel opens, the kanban area shrinks (`kanbanWidth = container -
-  // previewWidth`); the header narrows along with it. Below ~1100px there is
+  // preview panel opens, the kanban area shrinks (`kanbanWidth = container -
+  // previewWidth`); the header narrows along with it. Below ~800px there is
   // no longer room between the left/right action groups for the centered
   // search, so the header hides it (see useIsHeaderNarrow in kanban-header).
   //
   // Post-overhaul: the always-on AppSidebar (~320px expanded) permanently eats
   // horizontal space, so the header's own clientWidth is viewport − sidebar.
-  // The default Desktop Chrome 1280px viewport now leaves the header below the
-  // 1100px narrow threshold even with no preview open, so this test forces a
+  // The default Desktop Chrome 1280px viewport leaves ~960px for the header,
+  // which is above the 800px narrow threshold, so this test forces a
   // viewport wide enough that the centered search shows with the sidebar
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/e2e/tests/kanban/kanban-board.spec.ts` around lines 50 - 62, The
comment in kanban-board.spec.ts still refers to the old narrow breakpoint and
should be updated to match the current 800px threshold used by useIsHeaderNarrow
in kanban-header.tsx. Revise the explanatory block around the viewport setup to
remove the stale “1100px” wording and adjust the reasoning so it explains that
the default 1280px viewport is no longer sufficient once the AppSidebar is
present, while the wider 1500px viewport keeps the header above the 800px cutoff
until the preview opens. Keep the description aligned with the test’s actual
viewport math and the current DESKTOP_HEADER_NARROW_PX value.
apps/backend/internal/user/service/service_test.go (1)

107-141: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Consider adding a test for the empty-string default path.

applyTasksListPreferences (per the provided service.go snippet) also defaults TasksListSort/TasksListGroup when the trimmed value is empty, but none of the three subtests here exercise that branch.

✅ Suggested additional subtest
+	t.Run("empty string applies default", func(t *testing.T) {
+		settings := &models.UserSettings{}
+		req := &UpdateUserSettingsRequest{
+			TasksListSort:  ptr("  "),
+			TasksListGroup: ptr(""),
+		}
+		if err := applyBasicSettings(settings, req); err != nil {
+			t.Fatalf("unexpected error: %v", err)
+		}
+		if settings.TasksListSort != tasksListSortDefault {
+			t.Fatalf("TasksListSort = %q, want default", settings.TasksListSort)
+		}
+		if settings.TasksListGroup != tasksListGroupDefault {
+			t.Fatalf("TasksListGroup = %q, want default", settings.TasksListGroup)
+		}
+	})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/backend/internal/user/service/service_test.go` around lines 107 - 141,
Add coverage for the empty-string default branch in
applyBasicSettings/applyTasksListPreferences, since the current
TestApplyBasicSettings_TasksListPreferences only checks valid and invalid
explicit values. Introduce a subtest that sets TasksListSort and/or
TasksListGroup to empty or whitespace-only input on UpdateUserSettingsRequest
and assert the resulting models.UserSettings fields are defaulted as intended
after applyBasicSettings runs.
apps/web/app/tasks/tasks-list-options.ts (1)

50-75: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing test coverage for new sort/parse utilities.

sortTasksForList, compareTasksForList, parseTasksListSort, and parseTasksListGroup contain non-trivial branching logic (secondary tiebreakers, default fallbacks) but no accompanying *.test.ts file is included in this cohort.

As per coding guidelines, apps/web/**/*.test.ts: "Frontend utility functions, hooks, API clients, and store slices must have tests in *.test.ts files when their logic changes."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/app/tasks/tasks-list-options.ts` around lines 50 - 75, Add frontend
unit tests for the updated tasks list utilities because the branching and
fallback logic in sortTasksForList, compareTasksForList, parseTasksListSort, and
parseTasksListGroup is not covered. Create a *.test.ts file alongside
tasks-list-options.ts and assert the key sort orders, secondary tie-breakers,
and default/invalid input fallbacks for compareTasksForList and the
parseTasksListSort/parseTasksListGroup helpers.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/backend/internal/user/service/service.go`:
- Around line 28-29: The allowed values for tasks_list_sort and tasks_list_group
are duplicated across the defaults, the validTasksListSort/validTasksListGroup
checks, and the error strings in service.go. Consolidate each field into a
single source of truth (for example, one slice or map per field) and update the
validation logic and error construction in the same place so the default
constants, switch/validation paths, and messages all derive from that shared
list.

In `@apps/backend/internal/user/store/sqlite.go`:
- Around line 583-608: The tasks-list sort/group allowed values are duplicated
across normalizeTasksListSort, normalizeTasksListGroup, and the backend
validTasksListSort/validTasksListGroup checks, which risks the sets drifting.
Extract a single shared backend source of truth for these enums (for example,
shared constants/helpers in a models or dto package) and update sqlite.go and
boot_state_routes.go to use it instead of hardcoded string lists; then keep the
frontend list in sync with that backend definition.

In `@apps/web/lib/ssr/user-settings.ts`:
- Around line 21-45: The task sort/group parsing logic is duplicated across
parseTasksListSort and parseTasksListGroup, causing drift from the canonical
definitions. Replace the local switch-based implementations in user-settings.ts
with imports from tasks-list-options.ts, and update the other copies in
spa-routes.tsx and tasks-page-client.tsx to reuse the same parser (or the shared
option constants/defaults) instead of hardcoded literals like "updated_desc" and
"state". Use the existing DEFAULT_TASKS_LIST_SORT, DEFAULT_TASKS_LIST_GROUP,
parseTasksListSort, and parseTasksListGroup symbols as the single source of
truth.

---

Outside diff comments:
In `@apps/web/app/tasks/page.tsx`:
- Around line 55-90: The tasks list is only being sorted after fetching a single
page, so pagination and “Created oldest”/similar options stay inconsistent.
Update fetchWorkspaceData in tasks/page.tsx and the data flow from
tasks-page-client.tsx to pass tasksListSort into listTasksByWorkspaceAction so
the backend applies the sort before pagination. Keep sortTasksForList only if
needed for a final stable pass, but do not rely on it to reorder the fetched
batch.

In `@apps/web/app/tasks/tasks-page-client.tsx`:
- Around line 69-100: The task list is being sorted only after fetching the
current page, which makes sorting and grouping page-local instead of applying
across the full workspace result set. Update the data load in
tasks-page-client.tsx so listTasksByWorkspace receives the selected
sort/grouping via its supported sort/order parameters, and remove the extra
client-side sort call in the load flow. Keep the existing fetch logic in the
same effect/useCallback area and ensure tasksListSort is translated into the API
request rather than reordering result.tasks after pagination.

---

Nitpick comments:
In `@apps/backend/internal/user/service/service_test.go`:
- Around line 107-141: Add coverage for the empty-string default branch in
applyBasicSettings/applyTasksListPreferences, since the current
TestApplyBasicSettings_TasksListPreferences only checks valid and invalid
explicit values. Introduce a subtest that sets TasksListSort and/or
TasksListGroup to empty or whitespace-only input on UpdateUserSettingsRequest
and assert the resulting models.UserSettings fields are defaulted as intended
after applyBasicSettings runs.

In `@apps/web/app/tasks/tasks-list-options.ts`:
- Around line 50-75: Add frontend unit tests for the updated tasks list
utilities because the branching and fallback logic in sortTasksForList,
compareTasksForList, parseTasksListSort, and parseTasksListGroup is not covered.
Create a *.test.ts file alongside tasks-list-options.ts and assert the key sort
orders, secondary tie-breakers, and default/invalid input fallbacks for
compareTasksForList and the parseTasksListSort/parseTasksListGroup helpers.

In `@apps/web/e2e/tests/kanban/kanban-board.spec.ts`:
- Around line 50-62: The comment in kanban-board.spec.ts still refers to the old
narrow breakpoint and should be updated to match the current 800px threshold
used by useIsHeaderNarrow in kanban-header.tsx. Revise the explanatory block
around the viewport setup to remove the stale “1100px” wording and adjust the
reasoning so it explains that the default 1280px viewport is no longer
sufficient once the AppSidebar is present, while the wider 1500px viewport keeps
the header above the 800px cutoff until the preview opens. Keep the description
aligned with the test’s actual viewport math and the current
DESKTOP_HEADER_NARROW_PX value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9e0badfb-b513-4092-9d4f-8e2a71a27ecc

📥 Commits

Reviewing files that changed from the base of the PR and between d1d56c1 and 3e08bb7.

📒 Files selected for processing (29)
  • apps/backend/internal/backendapp/boot_state_routes.go
  • apps/backend/internal/user/controller/controller.go
  • apps/backend/internal/user/dto/dto.go
  • apps/backend/internal/user/models/models.go
  • apps/backend/internal/user/service/service.go
  • apps/backend/internal/user/service/service_test.go
  • apps/backend/internal/user/store/sqlite.go
  • apps/backend/pkg/api/v1/user.go
  • apps/web/app/tasks/page.tsx
  • apps/web/app/tasks/tasks-list-options.ts
  • apps/web/app/tasks/tasks-list-view.tsx
  • apps/web/app/tasks/tasks-page-client.tsx
  • apps/web/components/kanban/kanban-header-mobile.tsx
  • apps/web/components/kanban/kanban-header.tsx
  • apps/web/components/settings/editors-settings-state.tsx
  • apps/web/e2e/helpers/api-client.ts
  • apps/web/e2e/tests/kanban/kanban-board.spec.ts
  • apps/web/e2e/tests/task/mobile-task-list-search.spec.ts
  • apps/web/e2e/tests/task/task-list-filters.spec.ts
  • apps/web/e2e/tests/task/task-list.spec.ts
  • apps/web/e2e/tests/task/workspace-switch-sidebar-isolation.spec.ts
  • apps/web/hooks/use-ensure-user-settings.test.ts
  • apps/web/hooks/use-user-display-settings.ts
  • apps/web/lib/ssr/user-settings.ts
  • apps/web/lib/state/slices/settings/settings-slice.ts
  • apps/web/lib/state/slices/settings/types.ts
  • apps/web/lib/types/http-user-settings.ts
  • apps/web/src/boot-payload.ts
  • apps/web/src/spa-routes.tsx

Comment thread apps/backend/internal/user/service/service.go Outdated
Comment thread apps/backend/internal/user/store/sqlite.go Outdated
Comment thread apps/web/lib/ssr/user-settings.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 issues found across 26 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread apps/web/app/tasks/tasks-page-client.tsx Outdated
Comment thread apps/web/app/tasks/tasks-list-view.tsx
Comment thread apps/web/lib/state/slices/settings/types.ts Outdated
Comment thread apps/web/app/tasks/page.tsx Outdated
Comment thread apps/web/lib/tasks/tasks-list-options.ts
Comment thread apps/web/lib/ssr/user-settings.ts Outdated
Comment thread apps/web/app/tasks/tasks-page-client.tsx
Comment thread apps/backend/internal/backendapp/boot_state_routes.go Outdated
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 0s —— View job


I'll analyze this and get back to you.

Comment thread apps/web/app/tasks/tasks-list-view.tsx
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 0s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 0s —— View job


I'll analyze this and get back to you.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/backend/internal/backendapp/boot_state_routes.go (1)

42-43: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Add tests for the boot-state sort/group routing logic
Cover tasksListSortForRoute, tasksListGroupForRoute, and the fallback task ordering in tasksPageBootData in a *_test.go file alongside apps/backend/internal/backendapp/boot_state_routes.go.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/backend/internal/backendapp/boot_state_routes.go` around lines 42 - 43,
Add a new *_test.go alongside boot_state_routes.go to cover the routing behavior
for tasksListSortForRoute and tasksListGroupForRoute, including explicit query
values and empty/invalid inputs that should fall back to the settings defaults.
Also add a test for tasksPageBootData that verifies the fallback task ordering
is used when the route values are not provided, so the boot-state data matches
the expected sort/group behavior.

Source: Path instructions

🧹 Nitpick comments (2)
apps/backend/internal/backendapp/boot_state_routes.go (1)

648-660: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Parameter name shadows the package-level queryValue function.

queryValue is also the name of the helper defined at Line 630 in this same file. Using it as a parameter name here works but shadows that function within this scope, which can confuse future edits (e.g., someone adding a call to the real queryValue(req, ...) inside these functions will hit a compile error or unexpected behavior).

♻️ Rename to avoid shadowing
-func tasksListSortForRoute(queryValue, settingsValue string) string {
-	if usermodels.IsValidTasksListSort(queryValue) {
-		return strings.TrimSpace(queryValue)
+func tasksListSortForRoute(rawSort, settingsValue string) string {
+	if usermodels.IsValidTasksListSort(rawSort) {
+		return strings.TrimSpace(rawSort)
 	}
 	return usermodels.NormalizeTasksListSort(settingsValue)
 }

-func tasksListGroupForRoute(queryValue, settingsValue string) string {
-	if usermodels.IsValidTasksListGroup(queryValue) {
-		return strings.TrimSpace(queryValue)
+func tasksListGroupForRoute(rawGroup, settingsValue string) string {
+	if usermodels.IsValidTasksListGroup(rawGroup) {
+		return strings.TrimSpace(rawGroup)
 	}
 	return usermodels.NormalizeTasksListGroup(settingsValue)
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/backend/internal/backendapp/boot_state_routes.go` around lines 648 -
660, The parameters in tasksListSortForRoute and tasksListGroupForRoute shadow
the existing queryValue helper in this file, which can cause confusion in future
changes. Rename the parameter currently called queryValue in both functions to a
distinct name, and update the internal references accordingly, keeping the logic
in these route helpers unchanged.
apps/web/app/tasks/tasks-list-view.tsx (1)

1-104: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

File bundles many components well past the 200-line guideline.

Per line-range details this file spans to ~603 lines and hosts TasksListView, TasksListControls, ListOptionSelect, TaskRows, TaskListRow, TaskListSectionView, TaskRowActions, and TasksPagination together. As per coding guidelines, "Keep components under 200 lines; prefer composition over props and extract domain components when a component grows too large." Consider splitting row/section rendering, controls, and pagination into separate files under a domain folder.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/app/tasks/tasks-list-view.tsx` around lines 1 - 104, The tasks list
view file is too large and mixes several domain components in one module, so
split it into smaller files and keep each component under the 200-line
guideline. Extract `TasksListControls`, `ListOptionSelect`, `TaskRows`,
`TaskListRow`, `TaskListSectionView`, `TaskRowActions`, and `TasksPagination`
into separate domain components, while keeping `TasksListView` as the
composition entry point that wires them together.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/backend/internal/task/repository/sqlite/task.go`:
- Around line 495-513: The taskListOrderBy helper currently hardcodes COLLATE
NOCASE in the title ordering, which breaks non-SQLite dialects. Update
taskListOrderBy to use a dialect-aware case-insensitive title sort by checking
the repository’s existing SQLite/Postgres branching logic and selecting an
appropriate fallback for Postgres. Keep the existing behavior for SQLite, but
ensure every case that orders by title in taskListOrderBy remains valid across
dialects. Use the taskListOrderBy symbol and the repository’s existing
dialect-specific helpers/tests to locate and verify the change.

---

Outside diff comments:
In `@apps/backend/internal/backendapp/boot_state_routes.go`:
- Around line 42-43: Add a new *_test.go alongside boot_state_routes.go to cover
the routing behavior for tasksListSortForRoute and tasksListGroupForRoute,
including explicit query values and empty/invalid inputs that should fall back
to the settings defaults. Also add a test for tasksPageBootData that verifies
the fallback task ordering is used when the route values are not provided, so
the boot-state data matches the expected sort/group behavior.

---

Nitpick comments:
In `@apps/backend/internal/backendapp/boot_state_routes.go`:
- Around line 648-660: The parameters in tasksListSortForRoute and
tasksListGroupForRoute shadow the existing queryValue helper in this file, which
can cause confusion in future changes. Rename the parameter currently called
queryValue in both functions to a distinct name, and update the internal
references accordingly, keeping the logic in these route helpers unchanged.

In `@apps/web/app/tasks/tasks-list-view.tsx`:
- Around line 1-104: The tasks list view file is too large and mixes several
domain components in one module, so split it into smaller files and keep each
component under the 200-line guideline. Extract `TasksListControls`,
`ListOptionSelect`, `TaskRows`, `TaskListRow`, `TaskListSectionView`,
`TaskRowActions`, and `TasksPagination` into separate domain components, while
keeping `TasksListView` as the composition entry point that wires them together.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b38f8bde-72d7-4f68-9cb6-674c627ae356

📥 Commits

Reviewing files that changed from the base of the PR and between 3e08bb7 and 1dd0113.

📒 Files selected for processing (32)
  • apps/backend/internal/backendapp/boot_state_routes.go
  • apps/backend/internal/backendapp/e2e_reset.go
  • apps/backend/internal/office/service/event_subscribers_fallback_test.go
  • apps/backend/internal/office/service/service.go
  • apps/backend/internal/office/service/workspace_deletion.go
  • apps/backend/internal/office/service/workspace_deletion_test.go
  • apps/backend/internal/orchestrator/executor/executor_mocks_test.go
  • apps/backend/internal/task/handlers/process_handlers_test.go
  • apps/backend/internal/task/handlers/task_http_handlers.go
  • apps/backend/internal/task/repository/archive_repository_test.go
  • apps/backend/internal/task/repository/interface.go
  • apps/backend/internal/task/repository/sqlite/task.go
  • apps/backend/internal/task/repository/task_repository_test.go
  • apps/backend/internal/task/service/handoff_workspace_test.go
  • apps/backend/internal/task/service/service_pr_search_test.go
  • apps/backend/internal/task/service/service_resources.go
  • apps/backend/internal/task/service/service_tasks.go
  • apps/backend/internal/user/models/tasks_list_preferences.go
  • apps/backend/internal/user/service/service.go
  • apps/backend/internal/user/store/sqlite.go
  • apps/web/app/actions/workspaces.ts
  • apps/web/app/tasks/page.tsx
  • apps/web/app/tasks/tasks-list-view.tsx
  • apps/web/app/tasks/tasks-page-client.tsx
  • apps/web/components/settings/editors-settings-state.tsx
  • apps/web/hooks/use-user-display-settings.ts
  • apps/web/lib/api/domains/kanban-api.ts
  • apps/web/lib/ssr/user-settings.ts
  • apps/web/lib/state/slices/settings/settings-slice.ts
  • apps/web/lib/state/slices/settings/types.ts
  • apps/web/lib/tasks/tasks-list-options.ts
  • apps/web/src/spa-routes.tsx
✅ Files skipped from review due to trivial changes (2)
  • apps/backend/internal/task/service/handoff_workspace_test.go
  • apps/backend/internal/task/repository/archive_repository_test.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • apps/web/lib/state/slices/settings/types.ts
  • apps/web/lib/state/slices/settings/settings-slice.ts
  • apps/web/components/settings/editors-settings-state.tsx
  • apps/web/hooks/use-user-display-settings.ts
  • apps/web/src/spa-routes.tsx
  • apps/backend/internal/user/store/sqlite.go
  • apps/web/app/tasks/page.tsx
  • apps/web/app/tasks/tasks-page-client.tsx
  • apps/backend/internal/user/service/service.go

Comment thread apps/backend/internal/task/repository/sqlite/task.go Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 27 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/web/app/tasks/tasks-list-view.tsx">

<violation number="1" location="apps/web/app/tasks/tasks-list-view.tsx:328">
P2: Grouping by workflow or repository now uses ID-based section keys, which is good for disambiguation, but the fallback title when a lookup map misses an entry stays generic (`"No workflow"` / `"No repository"`). If several tasks reference distinct deleted or hidden workflow/repository IDs, the list will render multiple separate sections that all have the same fallback title, making grouping look broken.

Consider collapsing missing-map entries into a single fallback group (e.g., by using a shared `workflow:none` / `repository:none` key when the title is missing), or include the raw ID in the fallback title so sections remain distinguishable.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread apps/backend/internal/task/repository/sqlite/task.go Outdated
Comment thread apps/web/app/tasks/tasks-list-view.tsx
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 1s —— View job


I'll analyze this and get back to you.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/backend/internal/task/repository/sqlite/task.go">

<violation number="1" location="apps/backend/internal/task/repository/sqlite/task.go:515">
P1: The PostgreSQL-specific `LOWER(t.title)` ordering added to `taskTitleOrder` will break `searchTasks` at runtime because `SELECT DISTINCT` in PostgreSQL requires every `ORDER BY` expression to appear in the select list. `LOWER(t.title)` is not included in `taskSelectColumns("t")`, so any non-empty task search on PostgreSQL will raise `for SELECT DISTINCT, ORDER BY expressions must appear in select list`.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread apps/backend/internal/task/repository/sqlite/task.go
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 1s —— View job


I'll analyze this and get back to you.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread apps/web/app/tasks/tasks-list-view.tsx
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 0s —— View job


I'll analyze this and get back to you.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread apps/backend/internal/task/repository/sqlite/task.go
@carlosflorencio

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 926bc12df6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/web/app/tasks/tasks-page-client.tsx
@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown

Claude finished @carlosflorencio's task in 0s —— View job


I'll analyze this and get back to you.

@carlosflorencio carlosflorencio merged commit c18a13c into main Jul 3, 2026
66 checks passed
@carlosflorencio carlosflorencio deleted the feature/new-list-ux-tasks-als branch July 3, 2026 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant