Skip to content

fix(analytics): calculate project completion percentages - #399

Merged
martian56 merged 2 commits into
Devlaner:mainfrom
dogukangoker:fix/398-analytics-project-completion
Aug 5, 2026
Merged

fix(analytics): calculate project completion percentages#399
martian56 merged 2 commits into
Devlaner:mainfrom
dogukangoker:fix/398-analytics-project-completion

Conversation

@dogukangoker

@dogukangoker dogukangoker commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

What was broken

Project completion percentages in the Analytics Overview active-project list were always displayed as 0%, regardless of completed work items.

Linked issues

Fixes #398

Root cause

AnalyticsOverviewPage.tsx rendered a hardcoded 0% badge and did not load project workflow states needed to determine which work items belonged to the completed state group. Additionally, the page requested issues with limit: 200, while the API accepts a maximum limit of 100 and falls back to 50 when the supplied limit is invalid. This could produce incomplete work-item totals and inaccurate completion ratios for larger projects.

The fix

  • Fetch workflow states for every visible project.
  • Fetch all project work items using API-compatible limit: 100 and offset pagination.
  • Group work items by project_id.
  • Resolve each work item's state group using its state_id.
  • Calculate and display the rounded completed-to-total percentage.
  • Keep backlog, unstarted, and started work items in the denominator.
  • Exclude cancelled and canceled work items from both the numerator and denominator.
  • Default projects without applicable work items to 0%.
  • Clear stale issue and state data when a workspace has no projects.

Backend aggregation, polling, and real-time subscriptions were deliberately left out of scope to keep the change aligned with the frontend-only approach agreed upon in the issue.

Why this fix is correct

The calculation uses each project's complete work-item collection rather than a truncated first page. State IDs are resolved against the loaded project states, and only work items in the completed state group contribute to the numerator. Backlog, unstarted, and started work items remain part of the denominator because project completion is calculated against the total actionable work-item pool. Cancelled work items do not affect either side of the ratio. Projects with no applicable work items use a 0% fallback, preventing division-by-zero errors or invalid values. The change is isolated to the Analytics Overview page and does not alter shared API contracts or backend behavior.

Reproduction

  1. Create a project with at least one completed and one incomplete work item.
  2. Open the workspace Analytics Overview page.
  3. Observe that main displays 0% for the project regardless of the completed work items.
  4. Open the same page on this branch.
  5. Confirm that the percentage matches the completed-to-total ratio.
  6. Change a work item's state, create a new work item, or delete an existing work item.
  7. Return to Analytics Overview and confirm that the percentage is recalculated.

Test plan

  • npm run validate green
  • Reproduction above no longer triggers the failure
  • Added a regression test that fails on main and passes on this branch
    • Not added because apps/web does not currently provide a page-level test runner. Covered through manual regression testing and the
      existing validation suite.
  • Manually verified neighboring flows that share the affected code path
  • Verified status changes recalculate the percentage
  • Verified work-item creation and deletion recalculate the percentage
  • Verified cancelled work items are excluded
  • Verified backlog work items remain in the denominator
  • Verified empty projects display 0%
  • Verified multiple projects calculate independently
  • Verified pagination requests use the supported 100-item limit

Regression risk

The page now performs one workflow-state request per project and additional issue requests for projects containing more than 100 work items. This can increase Analytics Overview loading time in workspaces containing many large projects. The additional requests are limited to the Analytics Overview route. Existing project, work-item, and analytics API contracts are unchanged. Manual verification covered status changes, creation, deletion, cancelled work items, backlog work items, empty projects, multiple projects, and paginated issue loading.

Screenshots / logs (if applicable)

Not included; this change updates the displayed percentage values without changing the page layout.

AI assistance

  • No AI tools were used for this PR
  • AI tools were used — tool(s): ____ — and AI-assisted commits include a Co-Authored-By: trailer

Checklist

  • PR title is fix(<scope>): … and ≤ 100 chars
  • Regression test added (or explained why one isn't possible)
  • No --no-verify bypass

Summary by CodeRabbit

  • New Features

    • Active projects now display calculated completion percentages based on their issues.
    • Completion metrics include issues across all pages and exclude cancelled issues.
  • Bug Fixes

    • Improved handling of empty projects, loading cancellations, and data-loading errors.
    • Analytics data now resets appropriately to prevent stale results from being displayed.
    • Added a clear error state when analytics data cannot be loaded.

@dogukangoker
dogukangoker requested a review from a team as a code owner August 4, 2026 12:02
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Analytics now loads all project issues and states, calculates per-project completion percentages excluding cancelled issues, and displays the results in the Active Projects list.

Changes

Analytics completion metrics

Layer / File(s) Summary
Load project issues and states
apps/web/src/pages/AnalyticsOverviewPage.tsx
The page fetches paginated issues and project states. It uses cancellable async loading, handles empty and failed loads, resets datasets, and displays an analytics error state.
Calculate and render completion percentages
apps/web/src/pages/AnalyticsOverviewPage.tsx
The page memoizes completion statistics, counts completed issues, excludes cancelled issues, rounds percentages, and replaces the fixed 0% display.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested labels: UI, improvement

Suggested reviewers: martian56

Poem

A rabbit counts tasks in a bright meadow row,
Done carrots make completion numbers grow.
Cancelled ones leave the tally with care,
Each project now shows its measured share.
“Hop!” says the rabbit, “the results are there!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary change and follows the required Conventional Commits format.
Description check ✅ Passed The description explains the bug, root cause, fix, scope, validation, regression risk, and linked issue in sufficient detail.
Linked Issues check ✅ Passed The implementation satisfies issue #398 by calculating project percentages, handling empty projects, and updating after work-item changes.
Out of Scope Changes check ✅ Passed The changes are limited to Analytics Overview percentage calculation and related frontend data loading described in issue #398.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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/web/src/pages/AnalyticsOverviewPage.tsx`:
- Around line 99-100: Separate the workspace lookup error handling from the
derived-data requests in the effect around setWorkspace: only setWorkspace(null)
when the workspace lookup itself fails. If project, member, issue-page, or state
loading fails after setWorkspace(w) succeeds, preserve the workspace and expose
the data-load error through the existing error state or handling path.
- Around line 82-87: Update the data-loading flow around the projects fetch and
its useMemo-derived percentages so work-item mutations invalidate or refetch the
project issues and states while the page remains mounted. Ensure create, delete,
reopen, and completion events trigger the existing fetch path and cause the
displayed percentages to recalculate, rather than relying only on workspaceSlug,
issues, or states changes.
- Around line 101-103: In the request-failure path of the analytics effect,
check cancelled and return before invoking any reset setter, including
setMembers, setProjects, setIssues, and setStates. Only clear state for the
active request so stale failures cannot erase data loaded after a workspace
switch.
🪄 Autofix

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 Plus

Run ID: df48f8a9-673d-4bf6-ae2c-b89788ebc562

📥 Commits

Reviewing files that changed from the base of the PR and between 508f5d6 and 4095e81.

📒 Files selected for processing (1)
  • apps/web/src/pages/AnalyticsOverviewPage.tsx

Comment thread apps/web/src/pages/AnalyticsOverviewPage.tsx Outdated
Comment thread apps/web/src/pages/AnalyticsOverviewPage.tsx Outdated
Comment thread apps/web/src/pages/AnalyticsOverviewPage.tsx
@martian56

Copy link
Copy Markdown
Member

@dogukangoker Please take a look at coderabbit's comments

@dogukangoker

Copy link
Copy Markdown
Contributor Author

@dogukangoker Please take a look at coderabbit's comments

Reviewed all three CodeRabbit comments.

  • Fixed the workspace/data-loading error seperation
  • Fixed stale cancelled requests clearing the current workspace data.
  • Replied inline to the live percentage refresh comment with the scope rationale. The current behavior refetches when returning to Analytics; cross-route live invalidation is outside this PR's scope.

Typecheck, lint, formatting and production build all pass. @martian56

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/web/src/pages/AnalyticsOverviewPage.tsx (1)

27-43: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Stop stale pagination after cleanup.

If a workspace switch occurs after these requests start, each old fetchAllProjectIssues call continues to request pages until completion. The cleanup flag only prevents later state writes. Stop future page requests when cleanup runs. Use AbortSignal for the active request if the API client supports it.

Proposed minimal cancellation propagation
 async function fetchAllProjectIssues(
   workspaceSlug: string,
   projectId: string,
+  isCancelled: () => boolean,
 ): Promise<IssueApiResponse[]> {
   const issues: IssueApiResponse[] = [];
   let offset = 0;

-  while (true) {
+  while (!isCancelled()) {
     const page = await issueService.list(workspaceSlug, projectId, {
       limit: ISSUE_PAGE_SIZE,
       offset,
     });
+    if (isCancelled()) return issues;
     issues.push(...page);

     if (page.length < ISSUE_PAGE_SIZE) return issues;
     offset += page.length;
   }
+  return issues;
 }
 
-              Promise.all(projs.map((p) => fetchAllProjectIssues(workspaceSlug, p.id))),
+              Promise.all(
+                projs.map((p) =>
+                  fetchAllProjectIssues(workspaceSlug, p.id, () => cancelled),
+                ),
+              ),

Also applies to: 90-95

🤖 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/src/pages/AnalyticsOverviewPage.tsx` around lines 27 - 43, Update
fetchAllProjectIssues to accept an AbortSignal and check it before each
paginated issueService.list request, stopping immediately when the signal is
aborted. Propagate the signal from the cleanup-aware caller so workspace
switches cancel active requests when supported by the API client, while
preserving existing pagination and state-write guards.
🤖 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.

Nitpick comments:
In `@apps/web/src/pages/AnalyticsOverviewPage.tsx`:
- Around line 27-43: Update fetchAllProjectIssues to accept an AbortSignal and
check it before each paginated issueService.list request, stopping immediately
when the signal is aborted. Propagate the signal from the cleanup-aware caller
so workspace switches cancel active requests when supported by the API client,
while preserving existing pagination and state-write guards.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fa0cedc9-0a66-40f1-a37f-a5577f2fc53a

📥 Commits

Reviewing files that changed from the base of the PR and between 4095e81 and a6f5c39.

📒 Files selected for processing (1)
  • apps/web/src/pages/AnalyticsOverviewPage.tsx

@martian56
martian56 merged commit 568ce40 into Devlaner:main Aug 5, 2026
2 checks passed
@martian56

Copy link
Copy Markdown
Member

@dogukangoker Thank you for your contribution)

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.

[FEAT] When marking a work-item as done, the analytics % for this project should go up

2 participants