31d4ba67fa
* perf(stats): split stats endpoint per-section and rewrite GetGlobalStats Stats page used to wait on a single endpoint that ran 7 SQL queries in parallel and rendered nothing until the slowest one returned. Cold first-paint was the bottleneck users actually hit. - Backend: split /api/v1/workspaces/:id/stats into 7 per-section endpoints (global, tasks, daily-activity, completed-activity, agent-usage, repositories, git). Each handler runs one repo call and returns its DTO. - Backend: rewrote GetGlobalStats from 9 independent correlated subqueries into 4 CTEs (task / session / turn / message). Each underlying table is now scanned at most once per request instead of 1-3 times. - Frontend: replaced the monolithic fetchStats + single PanelState with useStatsSections hook (7 parallel fetches, per-section SectionStatus). Each panel renders skeleton -> data -> error independently; light queries (overview, agent usage, git) paint immediately, heavy ones stream in. - Tests: added TestGetGlobalStats_AggregatesAcrossTables to lock the CTE-based query against regressions for turns, user/tool messages, and total duration. * fix(stats): address PR review feedback - Restore cache: "no-store" on section fetches; Gin emits no Cache-Control headers so the browser could otherwise serve stale stats on revisit (Greptile P1, Cubic). - Stop blanking the Overview panel when /git fails: render OverviewCards as soon as `global` is ready and treat `git` as optional, falling back to the Averages card. Updates GitOrAveragesCard / OverviewCards types (Claude). - Fix TaskStatsHasMore off-by-one at exactly taskStatsLimit rows: probe taskStatsLimit+1, slice back to the page size, only flag hasMore on a confirmed extra row (Claude, Cubic). - Rename anyError → firstError with a comment documenting the deterministic insertion-order iteration; clearer signal that callers should use it as "any section failed?" and surface per-section errors in their own panels (Claude). --------- Co-authored-by: Kandev Agent <agent@kandev.dev>