src/
main.jsx # App entry, React Query provider
App.jsx # Router setup, protected route wrapper
api/
client.js # Axios instance, token interceptor, refresh logic
auth.js
repos.js
metrics.js
hooks/
useAuth.js # Auth state, login/logout
useRepos.js # React Query wrappers
useMetrics.js
components/
ui/ # Primitives: Button, Card, Badge, Spinner
charts/
CommitHeatmap.jsx # D3 calendar heatmap (hand-rolled)
CycleTimeChart.jsx # Recharts LineChart
TurnaroundBar.jsx # Recharts BarChart
layout/
AppShell.jsx # Sidebar + topbar layout
Sidebar.jsx
Topbar.jsx
pages/
Login.jsx # OAuth entry point
Dashboard.jsx # Summary metrics, all repos
RepoDetail.jsx # Single repo deep-dive
RepoSettings.jsx # Add/remove repos
Compare.jsx # Period comparison view
utils/
dates.js # Date range helpers
formatters.js # Hours → "2d 4h" etc
AppShell — layout wrapper, renders sidebar nav and outlet. Handles responsive collapse.
Dashboard — fetches /api/metrics/summary, renders top-level KPI cards (total commits, avg cycle time, avg review turnaround), renders CommitHeatmap for last 52 weeks.
RepoDetail — fetches /api/metrics/cycle-time and /api/metrics/commits filtered by repoId. Renders CycleTimeChart (line over time) and TurnaroundBar (per-reviewer breakdown).
Compare — two DateRangePicker inputs, fetches /api/metrics/compare, renders side-by-side stat cards with delta indicators (↑ / ↓).
CommitHeatmap — hand-rolled D3 SVG calendar grid. This is your portfolio centerpiece — do not use a library for this. 52 columns × 7 rows, color-scaled by commit count.
api/client.js — Axios instance with a request interceptor that attaches the JWT from memory (not localStorage), and a response interceptor that catches 401s and hits /api/auth/refresh before retrying.