Skip to content

Task board undercounts tasks when workspace snapshot is truncated before archived-project filtering #272

Description

@gcp007-ops

Summary

Task Board and getWorkspaceSummary() can undercount or hide tasks when a workspace has more than 200 tasks and the first workspace task page is dominated by archived projects.

In that state, active visible projects can show up with 0 tasks in the Task Board even though direct project-level task queries return the expected tasks.

Root cause

Two snapshot-style consumers request a very large page size and then treat result.items as if it were the full workspace:

  • TaskBoardDataController.loadBoardData() calls taskService.listWorkspaceTasks(workspace.id, { pageSize: 10000 }), then filters tasks by non-archived projects afterward.
  • TaskService.getWorkspaceSummary() calls taskRepo.getByWorkspace(workspaceId, { pageSize: 10000 }), then computes task counts, status counts, next actions, and recently completed tasks from that single page.

However, BaseRepository.queryPaginated() clamps page size to 200:

const pageSize = Math.min(options.pageSize ?? 25, 200);

That cap is reasonable, but these callers are snapshot consumers. If archived project tasks consume the first 200 workspace tasks, non-archived project tasks outside that first page are never considered.

This also creates inconsistent summaries: pagination metadata may report the full totalItems, while status counts and project task counts are calculated from only the first page.

Impact

  • Task Board can display active projects as empty.
  • Workspace summaries can report taskCount: 0 for active projects that do have tasks.
  • nextActions and recentlyCompleted can miss tasks outside the first page.
  • Archived project tasks can affect active/visible workspace views by consuming the truncated workspace task page before filtering happens.

Suggested fix

Keep the repository-level page-size cap, but make snapshot consumers paginate explicitly.

For TaskBoardDataController:

  • Load all project pages for each workspace.
  • Filter out archived projects first.
  • Load all task pages per visible project using taskService.listTasks(project.id, { page, pageSize: 200, includeSubtasks: true }).
  • Stop using a single listWorkspaceTasks() page as the board snapshot.

For TaskService.getWorkspaceSummary():

  • Add a small helper to collect all pages from a paginated repository call.
  • Collect all workspace project pages and task pages before computing derived summary fields.
  • Use tasks belonging to non-archived projects for visible task totals/status counts/recently completed.
  • Use tasks belonging to active projects for nextActions.

Regression tests

The fix should include tests for:

  • Task Board loading multiple pages for a visible project.
  • Task Board not querying tasks for archived projects.
  • getWorkspaceSummary() finding an active project task that appears only on page 2 of the workspace task query, after an archived project task on page 1.
  • Visible summary counts excluding archived project tasks.

Local verification

I tested a local patch with:

npm test -- TaskBoardDataController.test.ts TaskService.test.ts
npm run lint
npx tsc --noEmit --skipLibCheck
npm run build

All passed locally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions