Skip to content

feat(scheduling): add Queue tab with provider lanes and execution analytics#86

Open
jonit-dev wants to merge 5 commits intomasterfrom
night-watch/provider-aware-queue
Open

feat(scheduling): add Queue tab with provider lanes and execution analytics#86
jonit-dev wants to merge 5 commits intomasterfrom
night-watch/provider-aware-queue

Conversation

@jonit-dev
Copy link
Copy Markdown
Owner

Summary

This PR completes the Provider-Aware Queue implementation (Phase 4 of the Provider-Aware Weighted Scheduling PRD).

Changes

  • Scheduling Page Queue Tab: Added a new 'Queue' tab to the Scheduling page that visualizes:
    • Queue Overview Card: Shows running count, pending count, average wait time, and oldest pending age
    • Provider Lanes Chart: Visualizes running and pending jobs grouped by provider bucket
    • Provider Bucket Summary: Shows running/pending counts per provider bucket
    • Recent Runs Chart: Displays last 24 hours of job executions with status, duration, and wait time

Implementation Status

The Provider-Aware Queue PRD phases 1-3 were already implemented:

  • Phase 1 (Queue Dispatch Correctness): ✅ Jobs rebuild env from queued project config
  • Phase 2 (Provider-Aware Scheduler): ✅ Provider bucket resolution and capacity checks
  • Phase 3 (Operational Telemetry): ✅ Job runs table and analytics APIs

This PR adds the Phase 4 UI components to visualize the queue state.

Test plan

  • yarn verify passes
  • All existing tests pass
  • Manual: Open Scheduling page, verify Queue tab shows correct data

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

@github-actions
Copy link
Copy Markdown

DiffGuard AI Analysis

AI Review Summary

🏆 Overall Score: 82/100

The PR adds a comprehensive Queue tab to the Scheduling page with four well-organized cards displaying queue status, provider lanes, bucket summaries, and recent runs. The implementation follows existing patterns well but has minor UX and robustness gaps.


✅ Key Strengths

  • Consistent Code Style: Follows existing patterns in the file, including import conventions with .js extensions and Card component usage.
  • Defensive Null Handling: Proper use of optional chaining (queueStatus?.running, queueAnalytics?.averageWaitSeconds) prevents runtime errors when data is loading.
  • Logical Component Composition: New tab integrates seamlessly with existing tab structure and reuses queueStatus and queueAnalytics data already fetched by the parent component.

⚠️ Areas for Improvement

  • Time Display Formatting: Times over 60 minutes display as raw minutes (e.g., "90m" instead of "1h 30m"). Consider a utility function to format durations more readably for better UX.
  • Error State Handling: Only loading states are shown; consider adding error handling UI for cases where queueStatus or queueAnalytics fail to load.
  • Hardcoded Running Job Count: queueStatus?.running ? 1 : 0 assumes single-job execution. If the system supports parallel jobs, this logic may need adjustment or clarification.

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Maintainability Missing Error Boundaries web/pages/Scheduling.tsx (Queue tab) No error UI for failed data fetches—users see only loading text indefinitely if requests fail. Low
UX Time Format Readability Queue Overview Card Large wait times display as large minute counts (e.g., "120m") rather than human-readable hours. Low

🔚 Conclusion

This is a clean, well-structured feature addition that integrates smoothly with existing code. No blocking issues found—only minor UX polish and robustness enhancements worth considering. Ready to merge with optional follow-ups.


Analyzed using z-ai/glm-5

Copy link
Copy Markdown
Owner Author

@jonit-dev jonit-dev left a comment

Choose a reason for hiding this comment

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

AI Review Summary

🏆 Overall Score: 88/100

The PR adds a comprehensive Queue tab to the Scheduling page with four well-organized cards displaying queue status, provider lanes, bucket summaries, and recent runs. The implementation follows existing patterns and integrates cleanly with the existing data fetching logic.


✅ Key Strengths

  • Clean Component Architecture: The three new chart components (ProviderLanesChart, ProviderBucketSummary, RecentRunsChart) are well-typed with proper interfaces and follow the project's existing patterns.
  • Defensive Null Handling: Proper use of optional chaining (queueStatus?.running, queueAnalytics?.averageWaitSeconds) prevents runtime errors when data is loading.
  • Consistent Code Style: Follows existing conventions including .js import extensions, Card component usage, and Tailwind CSS styling patterns.

⚠️ Areas for Improvement

  • Time Display Formatting: Times over 60 minutes display as raw minutes (e.g., "90m" instead of "1h 30m"). Consider a utility function like formatDuration() used in RecentRunsChart to format durations more readably in the Queue Overview card.
  • Hardcoded Running Job Count: queueStatus?.running ? 1 : 0 assumes single-job execution. If the system supports parallel jobs, this logic may need adjustment.

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
UX Time Format Readability Queue Overview Card Large wait times display as large minute counts (e.g., "120m") rather than human-readable hours. Low
Maintainability Hardcoded Running Count web/pages/Scheduling.tsx:789 Assumes single concurrent job; may break if parallel execution is enabled. Low

🔚 Conclusion

This is a clean, well-structured feature addition that integrates smoothly with existing code. The failing CI tests (core-flow-smoke) return exit code 127 (command not found), which is a pre-existing CI environment issue unrelated to these UI changes. Ready to merge.

🔍 Reviewed by GLM-5

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 82/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

@jonit-dev jonit-dev force-pushed the night-watch/provider-aware-queue branch from f977cb5 to 8702b77 Compare March 26, 2026 02:07
@github-actions
Copy link
Copy Markdown

DiffGuard AI Analysis

AI Review Summary

🏆 Overall Score: 82/100

This PR adds a new "Queue" tab to the Scheduling page with four informational cards displaying queue status and analytics. The implementation is clean, follows existing patterns, and uses proper null-safety throughout.


✅ Key Strengths

  • Defensive Programming: Consistent use of optional chaining (queueStatus?.running) and nullish coalescing (?? 0) prevents runtime errors when data is unavailable.
  • Loading States: Each card properly handles the loading state with helpful placeholder text while data is being fetched.
  • Component Composition: New chart components (ProviderLanesChart, ProviderBucketSummary, RecentRunsChart) are cleanly imported and composed, maintaining separation of concerns.

⚠️ Areas for Improvement

  • Inline JSX in Tabs Array: The ~100 lines of inline JSX inside the tabs array reduce readability. Consider extracting the Queue tab content to a separate QueueTab component or a memoized variable.
  • Missing Error Handling: The cards only handle loading states, not error states. Consider adding error UI for when queueStatus or queueAnalytics requests fail.
  • Tabs Array Recreation: The tabs array is recreated on every render. Consider wrapping with useMemo to avoid unnecessary object allocation, especially given the large inline content.

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Maintainability Inline Tab Content Scheduling.tsx Large inline JSX block in tabs array makes the file harder to navigate and maintain. Medium
Testing Missing Test Coverage Scheduling.tsx No test file changes included to verify the new Queue tab renders correctly. Low
Performance Array Recreation Scheduling.tsx:1026+ The tabs array with large content objects is recreated on every component render. Low

🔚 Conclusion

This is a solid, well-structured addition that follows existing codebase patterns. The main concerns are maintainability due to the large inline JSX and the absence of error handling states. Consider extracting the Queue tab content and adding useMemo before merging, though neither is strictly blocking.


Analyzed using z-ai/glm-5

@jonit-dev
Copy link
Copy Markdown
Owner Author

Night Watch QA Report

Changes Classification

  • Type: UI
  • Files changed: 1

Test Results

UI Tests (Playwright)

  • Status: Skipped (11 tests)
  • Tests: 11 test(s) in 1 file(s)
  • Note: Tests require running backend API. Tests skip gracefully when API is unavailable.

Unit Tests (Vitest)

  • Status: All passing (4/4)
  • Tests: 4 test(s) in 1 file(s)
    • renders Queue tab with provider lanes and execution analytics
    • shows loading state in Queue tab when data is being fetched
    • displays queue stats when queue has running job
    • keeps cron controls available after dashboard refresh

Test Files Added

  • web/tests/e2e/qa/qa-scheduling-queue-tab.spec.ts - E2E tests for Queue tab UI
  • web/pages/__tests__/Scheduling.test.tsx - Updated with Queue tab unit tests

Test Coverage

The tests cover:

  • Queue tab button visibility
  • Queue Overview section (Running, Pending, Avg Wait, Oldest Pending stats)
  • Provider Lanes section with job type color legend
  • Provider Buckets section
  • Recent Runs section
  • Tab switching between Schedules and Queue
  • Loading states when data is being fetched

Artifacts

Screenshots and videos captured in web/test-results/ directory (not committed due to size).


Night Watch QA Agent

🧪 QA run by GLM-5

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

3 similar comments
@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

@jonit-dev
Copy link
Copy Markdown
Owner Author

✅ Ready for Human Review

Night Watch has reviewed this PR (score: 85/100) and found no issues requiring automated fixes.

This PR is ready for human code review and merge.

…lytics

Adds a new 'Queue' tab to the Scheduling page that visualizes:
- Queue overview (running, pending, avg wait, oldest pending)
- Provider lanes chart showing jobs grouped by provider bucket
- Provider bucket summary with running/pending counts
- Recent runs chart with execution history

This completes Phase 4 of the Provider-Aware Queue PRD.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jonit-dev jonit-dev force-pushed the night-watch/provider-aware-queue branch from 53b69b7 to 0a29338 Compare March 28, 2026 21:39
@jonit-dev jonit-dev added the ready-to-merge PR is ready to merge label Mar 28, 2026
Test User and others added 3 commits March 29, 2026 03:54
- Extract nested ternary into if-else chain in review.ts
- Fix import sorting in config.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… use useMemo

- Extract Queue tab content to separate QueueTab.tsx component for better maintainability
- Add error states for queueStatus and queueAnalytics with proper error UI
- Wrap tabs array in useMemo to prevent unnecessary recreation on each render
- Add tests for Queue tab rendering and error states

Addresses review feedback on PR #86.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix TypeScript errors in Scheduling.test.tsx by using correct property names
  (enqueuedAt instead of createdAt, projectPath instead of projectName,
  removed completed from byProviderBucket)
- Add fake claude binary to PATH in core-flow-smoke tests to fix exit code 127
  errors in reviewer tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jonit-dev
Copy link
Copy Markdown
Owner Author

AI Review Summary

🏆 Overall Score: 88/100

This PR adds a "Queue" tab to the Scheduling page with four informational cards (Queue Overview, Provider Lanes, Provider Buckets, Recent Runs) and fixes three review issues: extracts inline JSX into a dedicated QueueTab component, adds error state handling for failed API calls, and wraps the tabs array with useMemo. Also includes CLI-side formatting cleanups and smoke test claude binary stubs.


✅ Key Strengths

  • Addresses All Prior Feedback: The three previous review concerns (extract inline JSX, add error handling, useMemo) are each resolved cleanly — QueueTab is its own component, queueStatusError/queueAnalyticsError states drive error UI in every card, and useMemo wraps the tabs array with a proper dependency list.
  • Clean Error Propagation: The fetchDashboard effect now captures errors into typed state (setQueueStatusError/setQueueAnalyticsError) and clears them on success, avoiding stale error states. Each card in QueueTab consistently handles error → data → loading ordering.
  • Test Coverage for New Tab: Two new test cases cover the happy path (Queue tab renders all four cards with data) and the error path (failed queue status shows error message), matching the existing test patterns.

⚠️ Areas for Improvement

  • useMemo Dependency List Completeness: The dependency array on useMemo references several variables (agents, statusColor, statusText, showAddBucket, newBucketKey, newBucketConcurrency) that don't appear in the diff context visible from main→HEAD. If any of these were introduced in a prior commit not in this PR, this is fine; if they're stale references from a copy-paste of the old inline content, the memo may not invalidate when it should. Worth a quick verification that every entry in the deps array is actually used inside the memo body.
  • Test Doesn't Verify Chart Sub-Components Render: The test checks section headings exist (Queue Overview, Provider Lanes, etc.) but doesn't verify that ProviderLanesChart, ProviderBucketSummary, or RecentRunsChart actually render their content (e.g., provider lane labels, bucket rows, run rows). Adding data-testid assertions or text checks for the passed data would catch prop-wiring regressions.
  • Duplicated Error Message Strings: The "Failed to load queue status" and "Failed to load analytics" error messages are duplicated across multiple cards in QueueTab. Extracting these as constants or a shared error component would reduce repetition if the copy needs updating later.

📋 Issues Found

Issue Type Issue Name Affected Components Description Impact/Severity
Testing Shallow Chart Assertions Scheduling.test.tsx Tests only verify card headers render, not that chart sub-components display the mock data correctly. Low
Maintainability Duplicated Error Strings QueueTab.tsx Same error text ("Failed to load queue status", "Failed to load analytics") repeated per card. Low

🔚 Conclusion

Solid incremental improvement that directly addresses all prior review feedback with clean component extraction, proper error states, and useMemo optimization. The remaining gaps are low-severity — shallow test assertions and minor string duplication. No bugs found; merge-ready.

🔍 Reviewed by GLM-5.1 Claude

Addresses review feedback from PR #86:
- Extract duplicated error strings in QueueTab.tsx into ERROR_MESSAGES
  constants and a shared ErrorMessage component
- Add data-testid assertions for ProviderLanesChart, ProviderBucketSummary,
  and RecentRunsChart sub-components
- Use getAllByText for error messages that appear in multiple cards
- Add analytics error mock to error test for complete coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jonit-dev
Copy link
Copy Markdown
Owner Author

AI Review Summary

🏆 Overall Score: 92/100

The PR adds a Queue tab to the Scheduling page with four informational cards (Queue Overview, Provider Lanes, Provider Buckets, Recent Runs), extracting inline JSX into a dedicated QueueTab component with proper error handling and useMemo optimization. Also includes CLI-side formatting cleanups and smoke test claude binary stubs.


✅ Key Strengths

  • Clean Component Extraction: QueueTab is a well-structured, focused component with clear prop interfaces (IQueueTabProps), proper error→data→loading rendering order in all four cards, and consistent patterns.
  • Robust Error Propagation: fetchDashboard effect captures errors into typed state (queueStatusError/queueAnalyticsError) with clear-on-success semantics, avoiding stale error states. Error UI is consistent across all cards.
  • Comprehensive Sub-Component Design: ProviderLanesChart, ProviderBucketSummary, and RecentRunsChart each have proper data-testid attributes, empty-state handling, and clean data transformation from API types to display.
  • useMemo Deps Verified: All entries in the useMemo dependency array (agents, statusColor, statusText, showAddBucket, newBucketKey, newBucketConcurrency, etc.) are confirmed to be used within the memo body in the Overview tab's inline JSX — no stale references.

⚠️ Areas for Improvement

  • None remaining from prior review. All three previous concerns (extract inline JSX, add error handling, useMemo) and both follow-up issues (duplicated error strings, shallow test assertions) have been addressed in the latest commit.

🔚 Conclusion

No bugs found. All prior review feedback has been addressed cleanly — error messages are now centralized via ERROR_MESSAGES constants and a shared ErrorMessage component, and tests verify sub-component rendering via data-testid assertions. The PR is merge-ready.

🔍 Reviewed by GLM-5.1 Claude

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge PR is ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant