feat(dashboard): add GET /api/dashboard endpoint for aggregated PR health summary#280
feat(dashboard): add GET /api/dashboard endpoint for aggregated PR health summary#280ojaswa072 wants to merge 3 commits intoOWASP-BLT:mainfrom
Conversation
|
👋 Thanks for opening this pull request, @ojaswa072! Before your PR is reviewed, please ensure:
🔍 Our team will review your PR shortly. If you have questions, feel free to ask in the comments. 🚀 Keep up the great work! — OWASP BLT |
📊 Monthly LeaderboardHi @ojaswa072! Here's how you rank for March 2026:
Scoring this month (across OWASP-BLT org): Open PRs (+1 each), Merged PRs (+10), Closed (not merged) (−2), Reviews (+5; first two per PR in-month), Comments (+2, excludes CodeRabbit). Run |
|
👋 Hi @ojaswa072! This pull request needs a peer review before it can be merged. Please request a review from a team member who is not:
Once a valid peer review is submitted, this check will pass automatically. Thank you!
|
🍃 PR Readiness CheckCheck the readiness of this PR on Leaf: Leaf reviews pull requests for operational readiness, security risks, and production-impacting changes before they ship. |
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository: OWASP-BLT/coderabbit/.coderabbit.yml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughAdded a new async dashboard endpoint GET /api/dashboard that aggregates PR health metrics from the database (summary counts, readiness distribution, CI status, top blocked repos, most active authors), returns a structured JSON payload with Cache-Control headers, and notifies Slack on errors. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant API as Dashboard Handler
participant DB as Database
participant Slack
Client->>API: GET /api/dashboard
API->>DB: run aggregated queries (summary, readiness, CI, blocked repos, active authors)
DB-->>API: query results
API->>API: assemble JSON payload + Cache-Control headers
API-->>Client: 200 OK with dashboard JSON
alt error during processing
API->>Slack: send error notification
API-->>Client: 500 Internal Server Error (error payload)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 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)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/handlers.py`:
- Around line 907-911: The exception handler in handle_dashboard currently
returns internal exception details to callers; keep the notify_slack_exception
call but replace the response body with a generic 500 JSON (e.g.,
{"error":"Internal server error"}) and appropriate headers/status using
Response.new instead of echoing type(e) and str(e); update the except block
around notify_slack_exception and Response.new to remove exception content while
preserving Slack reporting via notify_slack_exception(getattr(env,
'SLACK_ERROR_WEBHOOK', ''), e, context={'handler':'handle_dashboard'}).
- Around line 791-793: Add a new aggregation for PRs that only have skipped CI
checks so they aren't left out of the CI breakdown: create a COALESCE(SUM(...),
0) CASE that checks WHEN checks_skipped > 0 AND checks_passed = 0 AND
checks_failed = 0 THEN 1 ELSE 0 END and alias it (e.g., skipped_only), alongside
the existing has_ci_failures, all_ci_passing, and no_checks aggregates; update
any downstream uses of ci buckets/ci_health to include this new skipped_only
count.
- Line 794: The SQL compares TEXT ISO-8601 timestamps (last_updated_at) against
datetime('now','-30 days') lexicographically, causing incorrect stale_prs;
update the CASE expression to normalize last_updated_at into SQLite datetime (or
a numeric time like julianday) before comparing—for example convert/replace the
"T" and strip trailing "Z" or pass last_updated_at into datetime()/julianday so
the condition in COALESCE(SUM(CASE WHEN ... THEN 1 ELSE 0 END), 0) AS stale_prs)
uses datetime(replace(last_updated_at,'T',' ','...')) or
julianday(last_updated_at) < julianday('now','-30 days') to ensure chronological
comparison.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository: OWASP-BLT/coderabbit/.coderabbit.yml
Review profile: CHILL
Plan: Pro
Run ID: b3a1eba1-b6d0-4d5f-a5ca-97289f210eb1
📒 Files selected for processing (2)
src/handlers.pysrc/index.py
…comparison, hide internal error details
| COUNT(*) AS blocked_count | ||
| FROM prs | ||
| WHERE is_merged = 0 AND state = 'open' | ||
| AND blockers IS NOT NULL |
There was a problem hiding this comment.
AND blockers IS NOT NULL - This line is redundant ig
Summary
Adds
GET /api/dashboard— a single endpoint returning aggregated health metrics for all tracked PRs.Problem
Getting a system-wide overview required multiple calls (
/api/prs,/api/repos,/api/authors). This consolidates all key metrics into one response.What it returns
Implementation
Files Changed
src/handlers.py— addedhandle_dashboard()src/index.py— added import andGET /api/dashboardrouteSummary by CodeRabbit