fix(ui): make TaskStats phase-aware to fix late-joining user bug - #234
Conversation
TaskStats now correctly displays task counts during planning phase by using issuesData (REST API) instead of agent state (WebSocket) which is empty until development begins. Changes: - Add phase and issuesData props to TaskStats component - Implement conditional data source selection based on phase - Add calculateStatsFromIssues helper for planning phase stats - Update Dashboard to pass phase and issuesData to TaskStats - Add 8 new tests for phase-aware behavior and edge cases This fixes the bug where TaskStats showed 0 tasks during planning phase even though the tab badge showed "Review (24)". Related: codeframe-7pya (documents other at-risk components)
WalkthroughThe PR implements phase-aware data sourcing for TaskStats, where planning-phase views use REST API data while development/review phases use real-time WebSocket updates from useAgentState. TaskStats gains new props (phase, issuesData) with a conditional data-source selector and helper function. Dashboard is updated to pass these props. Comprehensive tests and code-review documentation accompany the implementation. Changes
Sequence DiagramsequenceDiagram
participant Dashboard
participant TaskStats
participant DataSource as Data Source<br/>(Conditional)
participant REST as REST API<br/>(issuesData)
participant WS as WebSocket<br/>(useAgentState)
Dashboard->>TaskStats: Render with phase & issuesData props
TaskStats->>DataSource: Check phase
alt Planning Phase
DataSource->>REST: Fetch issuesData
REST-->>DataSource: Return issues with tasks
DataSource->>TaskStats: Provide stats from REST
else Development/Review Phase
DataSource->>WS: Use useAgentState hook
WS-->>DataSource: Return agent state tasks
DataSource->>TaskStats: Provide stats from agent state
end
TaskStats->>TaskStats: Memoize computed stats
TaskStats-->>Dashboard: Render task counts
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
Code Review: Phase-Aware TaskStats ImplementationI've reviewed PR #234 and the implementation looks excellent. This is a well-designed fix for the "late-joining user" bug with comprehensive test coverage and proper architectural considerations. ✅ Strengths1. Solid React Best Practices
2. Excellent Test Coverage
3. Defensive Programming
4. Clear Documentation
5. Architectural Thinking 📝 Minor Observations (Non-blocking)Performance Optimization Opportunity (TaskStats.tsx:67-70) // Current (3 passes)
return {
total: allTasks.length,
completed: allTasks.filter((t) => t.status === 'completed').length,
blocked: allTasks.filter((t) => t.status === 'blocked').length,
inProgress: allTasks.filter((t) => t.status === 'in_progress').length,
};
// Single-pass alternative
const counts = { total: allTasks.length, completed: 0, blocked: 0, inProgress: 0 };
for (const task of allTasks) {
if (task.status === 'completed') counts.completed++;
else if (task.status === 'blocked') counts.blocked++;
else if (task.status === 'in_progress') counts.inProgress++;
}
return counts;Assessment: Low priority - typical planning phase task counts are small (<100 tasks), and memoization ensures this runs infrequently. The current implementation is more readable. Acceptable as-is. Type Safety Enhancement (TaskStats.tsx:37) // Current
phase?: string;
// More specific
phase?: 'discovery' | 'planning' | 'development' | 'review' | 'complete' | 'shipped';Assessment: Low priority - the component only checks for 🎯 Consistency CheckThe change in Dashboard.tsx:702 correctly passes both props: <TaskStats phase={normalizePhase(projectData.phase)} issuesData={issuesData} />This ensures TaskStats receives the normalized phase string and the issues data loaded from the REST API. 📊 Test Results
🔄 Future ConsiderationsThe technical debt issue
This demonstrates good system thinking about consistent data source selection across the application. ✅ RecommendationAPPROVE & MERGE - This PR is production-ready. The implementation is clean, well-tested, and follows React best practices. The minor observations noted above are optimization opportunities, not functional issues. The comprehensive test suite and backward compatibility ensure this change is safe to deploy. Great work on identifying the root cause (dual data systems) and implementing a pattern that can be applied to other components! 🎉 |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
web-ui/src/components/tasks/TaskStats.tsx (1)
37-37: Consider using a union type forphaseprop.The
phaseprop is typed asstring, but the component only checks for'planning'. A union type would provide better type safety and IDE autocomplete:phase?: 'discovery' | 'planning' | 'development' | 'review' | 'complete' | 'shipped';This aligns with the
normalizePhasefunction in Dashboard.tsx which defines these exact values.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.beads/issues.jsonldocs/code-review/2026-01-08-taskstats-phase-awareness-review.mdweb-ui/__tests__/components/tasks/TaskStats.test.tsxweb-ui/src/components/Dashboard.tsxweb-ui/src/components/tasks/TaskStats.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Documentation files must be sized to fit in a single agent context window (spec.md ~200-400 lines, plan.md ~300-600 lines, tasks.md ~400-800 lines)
Files:
docs/code-review/2026-01-08-taskstats-phase-awareness-review.md
web-ui/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
web-ui/src/**/*.{ts,tsx}: Use TypeScript 5.3+ for frontend development with React 18, Next.js 14, Tailwind CSS, and Hugeicons for icons
Use TypeScript strict mode and ensure 100% type safety with no hardcoded types or any usage in frontend code
Files:
web-ui/src/components/Dashboard.tsxweb-ui/src/components/tasks/TaskStats.tsx
web-ui/src/components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
web-ui/src/components/**/*.tsx: Use shadcn/ui Nova template components with semantic color palette (bg-card, text-foreground, etc.) and avoid hardcoded color values
Use cn() utility for conditional Tailwind CSS classes and follow Nova's compact spacing conventions
Files:
web-ui/src/components/Dashboard.tsxweb-ui/src/components/tasks/TaskStats.tsx
web-ui/src/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Replace all icon usage with Hugeicons (@hugeicons/react) and do not mix with lucide-react
Files:
web-ui/src/components/Dashboard.tsxweb-ui/src/components/tasks/TaskStats.tsx
web-ui/src/components/Dashboard.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
Use React.memo on all Dashboard sub-components and useMemo for derived state to optimize performance with multi-agent support
Files:
web-ui/src/components/Dashboard.tsx
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T19:08:54.154Z
Learning: Applies to specs/*/tasks.md : Feature task files (tasks.md) must include phase-by-phase task breakdown with unique task identifiers (T001, T002, etc.), acceptance criteria per task, beads issue references, and estimated effort
📚 Learning: 2025-11-25T19:08:54.154Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T19:08:54.154Z
Learning: Applies to specs/*/tasks.md : Feature task files (tasks.md) must include phase-by-phase task breakdown with unique task identifiers (T001, T002, etc.), acceptance criteria per task, beads issue references, and estimated effort
Applied to files:
docs/code-review/2026-01-08-taskstats-phase-awareness-review.mdweb-ui/src/components/Dashboard.tsxweb-ui/src/components/tasks/TaskStats.tsxweb-ui/__tests__/components/tasks/TaskStats.test.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/components/Dashboard.tsx : Use React.memo on all Dashboard sub-components and useMemo for derived state to optimize performance with multi-agent support
Applied to files:
web-ui/src/components/Dashboard.tsxweb-ui/src/components/tasks/TaskStats.tsx
📚 Learning: 2026-01-04T06:26:12.870Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-04T06:26:12.870Z
Learning: Applies to web-ui/src/contexts/AgentStateContext.ts : Use context-based state management with React Context + useReducer pattern for Dashboard with AgentStateContext, agentReducer, and useAgentState hook
Applied to files:
web-ui/src/components/tasks/TaskStats.tsx
📚 Learning: 2025-11-25T19:08:37.203Z
Learnt from: CR
Repo: frankbria/codeframe PR: 0
File: docs/CLAUDE.md:0-0
Timestamp: 2025-11-25T19:08:37.203Z
Learning: Applies to docs/web-ui/**/__tests__/**/*.test.{ts,tsx} : Create JavaScript test files colocated or in __tests__/ as *.test.ts
Applied to files:
web-ui/__tests__/components/tasks/TaskStats.test.tsx
🧬 Code graph analysis (1)
web-ui/src/components/tasks/TaskStats.tsx (2)
web-ui/src/types/api.ts (1)
IssuesResponse(106-112)web-ui/src/hooks/useAgentState.ts (1)
useAgentState(156-469)
🪛 markdownlint-cli2 (0.18.1)
docs/code-review/2026-01-08-taskstats-phase-awareness-review.md
43-43: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
49-49: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
215-215: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Backend Unit Tests
- GitHub Check: Frontend Unit Tests
- GitHub Check: E2E Smoke Tests (Chromium)
🔇 Additional comments (15)
web-ui/src/components/tasks/TaskStats.tsx (5)
1-19: Well-documented component header.The JSDoc clearly explains the phase-aware behavior, data sources for each phase, and the bug this fixes. This documentation will help future maintainers understand the dual-data-source pattern.
27-45: Props interface is well-designed with clear documentation.The optional props maintain backward compatibility while enabling phase-aware behavior. The JSDoc for each prop clearly explains the expected values and behavior.
51-72: Helper function correctly handles edge cases.The
calculateStatsFromIssuesfunction properly handles:
- Missing
issuesData(line 57)- Issues without a
tasksarray (line 63 with|| [])- Correct status matching for all task states
The multiple
.filter()calls (lines 68-70) iterate the array 3 times. For typical planning phase task counts (<100), this is acceptable and more readable than a single-pass loop. The outeruseMemoensures this runs infrequently.
85-112: Correct React hooks usage and memoization.The implementation correctly:
- Calls
useAgentState()unconditionally (line 87) - following React hooks rules- Uses the hook's data conditionally based on phase
- Memoizes stats with all relevant dependencies (line 112)
The dependency array includes all values that affect the computation, ensuring correct cache invalidation.
177-178: Good use of React.memo for performance.Wrapping the export with
React.memoprevents unnecessary re-renders when parent components update but props remain unchanged. This follows the coding guidelines for Dashboard sub-components.web-ui/src/components/Dashboard.tsx (1)
702-702: Correct integration of phase-aware TaskStats.The props are properly passed:
phaseis normalized using the existingnormalizePhasehelperissuesDatacomes from the SWR fetch (may be undefined during loading, which TaskStats handles gracefully)This change enables TaskStats to display accurate task counts during the planning phase while maintaining the existing real-time behavior during development/review.
.beads/issues.jsonl (1)
99-99: Good technical debt tracking.The new issue (codeframe-7pya) properly documents:
- The root cause of phase-awareness bugs (dual REST/WebSocket data systems)
- At-risk components that may need similar fixes
- The pattern to apply (phase prop, data source selection)
- Testing strategy for phase transitions
This ensures the broader implications of this fix are tracked for future work.
docs/code-review/2026-01-08-taskstats-phase-awareness-review.md (1)
1-243: Comprehensive code review documentation.This review report provides valuable project documentation:
- Clear executive summary with issue counts
- Detailed analysis of minor optimization opportunities
- Positive findings highlighting good practices
- Action items categorized by priority
- Testing recommendations with coverage status
The static analysis hints about markdown emphasis vs headings (lines 43, 49, 215) are stylistic preferences that don't affect the document's usefulness. The bold text works well for these section markers.
web-ui/__tests__/components/tasks/TaskStats.test.tsx (7)
349-356: Well-structured test documentation.The comment block clearly explains what the phase-aware tests verify and the data source selection logic. This helps future developers understand the test intent.
359-470: Comprehensive mock data setup.The mock data structures:
- Match the
IssuesResponseinterface with all required fields- Include tasks with various statuses (pending, completed, in_progress, blocked)
- Provide an
emptyAgentStatehelper for consistent test setupThe inline mock objects are verbose but improve test readability by keeping test data close to assertions.
472-488: Core bug fix test: planning phase uses issuesData.This test directly validates the bug fix - during planning phase with empty agent state, TaskStats should display counts from
issuesDatarather than showing zeros. The assertions correctly verify all four statistics.
490-526: Development and review phase tests verify agent state usage.These tests confirm that during development/review phases, TaskStats ignores
issuesDataand uses real-time agent state. This ensures the existing WebSocket-based behavior is preserved.
528-572: Edge case tests for graceful degradation.Good coverage of edge cases:
undefinedissuesData during planning (line 533) - shows zeros without crashing- Issues without tasks array (line 568) - handles missing property gracefully
These tests verify the defensive programming in
calculateStatsFromIssues.
592-619: Phase transition test validates data source switching.This test simulates a real-world scenario where a project transitions from planning to development. Using
rerender()to verify the component correctly switches from issuesData (4 tasks) to agent state (8 tasks) is an excellent approach.
621-711: API consistency test ensures UI matches backend counts.This test validates that TaskStats' calculated total matches
issuesData.total_tasks. This is important because the Dashboard tab badge usestotal_tasksdirectly, and the values should be consistent to avoid user confusion.
Issue LinkageThis PR fixes #233 (P0-blocker-beta: Tasks do not display on the Task tab). Related Issues
When this PR is merged, issue #233 should be closed. |
The previous phase-aware fix (#234) still failed because it tried to flatten the issues[].tasks arrays, which the API does not populate. The fix now uses issuesData.total_tasks directly as the authoritative count during planning phase. Root cause: API response includes total_tasks count but not nested task objects. The tab badge correctly used total_tasks (showing 24) while TaskStats flattened empty arrays (showing 0). Changes: - calculateStatsFromIssues now uses total_tasks field for total count - Still calculates status counts from nested tasks when available - Added test for production-like scenario with empty tasks arrays - Added edge case test for missing total_tasks field
…iew (#236) * fix(ui): use total_tasks field directly in TaskStats planning phase The previous phase-aware fix (#234) still failed because it tried to flatten the issues[].tasks arrays, which the API does not populate. The fix now uses issuesData.total_tasks directly as the authoritative count during planning phase. Root cause: API response includes total_tasks count but not nested task objects. The tab badge correctly used total_tasks (showing 24) while TaskStats flattened empty arrays (showing 0). Changes: - calculateStatsFromIssues now uses total_tasks field for total count - Still calculates status counts from nested tasks when available - Added test for production-like scenario with empty tasks arrays - Added edge case test for missing total_tasks field * fix(ui): TaskReview now requests tasks with include=tasks param The API's /issues endpoint only populates issue.tasks[] arrays when include=tasks query param is passed. Without this, TaskReview displayed "No tasks available for approval" during planning phase. Changes: - api.ts: getIssues now accepts options object with cursor and include - TaskReview: passes { include: 'tasks' } to get nested task data - Tests: Updated expected API call signatures * fix: address PR review feedback TaskReview: - Add validation guard for non-numeric projectId before approval API call - Surface user-facing error if projectId is invalid (NaN or <= 0) TaskStats: - Replace emoji icons (📋, ✅, 🚫, ⚙️) with Hugeicons components - Use CheckListIcon, CheckmarkCircle01Icon, Alert02Icon, Loading03Icon - Aligns with repo guidelines for consistent iconography Jest mocks: - Add missing Hugeicons to @hugeicons/react mock - Refactor mock creation with helper function
…stDashboard Implements the phase-awareness pattern (established in TaskStats PR #234) for three additional components to fix the "late-joining user" bug during planning phase. Components updated: - AgentList: Shows "Agents Ready for Development" message with task count during planning phase instead of misleading "No Agents Assigned" - QualityGatesPanel: Shows "Quality Gates Ready" message during planning phase instead of "No tasks available for quality gate evaluation" - CostDashboard: Shows "Cost Metrics" informational message during planning phase and skips unnecessary API calls (performance optimization) Implementation details: - Created shared utilities in phaseAwareData.ts: - isPlanningPhase(): Check if phase requires special handling - extractTasksFromIssuesData(): Flatten nested tasks from API response - calculateProgressFromIssuesData(): Compute progress metrics from REST data - getPlanningPhaseMessage(): Get component-specific planning messages - Dashboard passes phase and issuesData props to all updated components - All components maintain backward compatibility (work without phase prop) Testing: - 25 unit tests for phaseAwareData utilities - 13 unit tests for AgentList phase-awareness - 8 unit tests for QualityGatesPanel phase-awareness - 6 unit tests for CostDashboard phase-awareness - All 1558 tests pass, build succeeds
…stDashboard (#241) * feat(ui): add phase-awareness to AgentList, QualityGatesPanel, and CostDashboard Implements the phase-awareness pattern (established in TaskStats PR #234) for three additional components to fix the "late-joining user" bug during planning phase. Components updated: - AgentList: Shows "Agents Ready for Development" message with task count during planning phase instead of misleading "No Agents Assigned" - QualityGatesPanel: Shows "Quality Gates Ready" message during planning phase instead of "No tasks available for quality gate evaluation" - CostDashboard: Shows "Cost Metrics" informational message during planning phase and skips unnecessary API calls (performance optimization) Implementation details: - Created shared utilities in phaseAwareData.ts: - isPlanningPhase(): Check if phase requires special handling - extractTasksFromIssuesData(): Flatten nested tasks from API response - calculateProgressFromIssuesData(): Compute progress metrics from REST data - getPlanningPhaseMessage(): Get component-specific planning messages - Dashboard passes phase and issuesData props to all updated components - All components maintain backward compatibility (work without phase prop) Testing: - 25 unit tests for phaseAwareData utilities - 13 unit tests for AgentList phase-awareness - 8 unit tests for QualityGatesPanel phase-awareness - 6 unit tests for CostDashboard phase-awareness - All 1558 tests pass, build succeeds * fix(ui): address code review feedback for phase-awareness - Add aria-hidden to decorative icons for accessibility (AgentList, QualityGatesPanel) - Add data-testid="bot-icon" to BotIcon in AgentList for test selection - Update React.memo comment in QualityGatesPanel to reflect all props - Add phase transition test to CostDashboard (planning → development) - Add performance note to extractTasksFromIssuesData JSDoc * Add OpenCode workflow for PR review * ci: add OpenCode PR review workflow with Z.ai model Creates opencode-review.yml that mirrors claude-code-review.yml functionality using the Z.ai model via opencode action: - Triggers on PR open/synchronize - Skips documentation and config-only changes - Only reviews substantial changes (5+ files OR 20+ lines) - Uses same review prompt structure as Claude review - Leverages ZHIPU_API_KEY for Z.ai model access This provides an alternative "different model" perspective on PR reviews. * fix(ci): resolve duplicate Authorization header in OpenCode workflow * fix(ci): enable write permissions for PR comments * fix(ci): refine paths-ignore to review workflow changes * fix(ci): clear global git auth configs to prevent duplicate headers --------- Co-authored-by: Test User <test@example.com>
Summary
Problem
When a user views the Dashboard during the planning phase, the Tasks tab badge showed "Review (24)" (from issuesData API), but TaskStats showed 0 for all counts (from empty agent state). This inconsistency confused users about the actual number of tasks.
Root Cause
TaskStats used
useAgentState()hook exclusively, which only has data during development when agents are actively working. During planning phase, agent state is empty but tasks exist in the issues API.Solution
Made TaskStats phase-aware:
phaseandissuesDatapropsphase === 'planning': Calculate stats fromissuesDataphase === 'development'or'review': UseuseAgentState()(existing behavior)Changes
TaskStats.tsxcalculateStatsFromIssueshelper, phase-aware logicDashboard.tsxphaseandissuesDataprops to TaskStatsTaskStats.test.tsxcode-review/Test Plan
Manual Testing
Related Issues
codeframe-7pyadocumenting other at-risk componentsSummary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.