Two changes:
1. Replaced positional `GROUP BY 1` (not used anywhere else in this
codebase) with the conventional pattern of repeating the actual
grouped expression — matches every other groupBy call site in the app.
2. Switched Promise.all -> Promise.allSettled across the six independent
aggregate queries feeding the six charts, defaulting a failed one to
an empty array (that chart just renders "No data yet") instead of
taking the whole page down. Logs the failure server-side either way.
Couldn't reproduce locally (no DB in this sandbox), but confirmed the
allSettled path works: the production build itself hit a real connection
failure against the (absent) local DB and degraded cleanly instead of
crashing, which is exactly the resilience this fixes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New Admin > Insights: signups/day and recipes-created/day (manual vs AI)
over the last 30 days, users by tier, recipes by visibility, monthly AI
call totals (6 months), and support tickets by status.
Two hand-rolled SVG chart components (bar-chart.tsx, time-series-chart.tsx)
instead of pulling in a charting library — avoids a new dependency and
any React 19 peer-dep risk. Both ship a hover tooltip (crosshair for the
time series, per-bar for the bar chart) and a "show as table" toggle per
the dataviz method's accessibility requirement.
Repurposed the app's existing (previously unused, grayscale-only)
shadcn --chart-1..5 CSS variables with a validated categorical palette —
run through the dataviz skill's CVD/contrast validator for both light and
dark surfaces (both pass; three light-mode slots fall under 3:1 contrast
by design, mitigated by the charts' direct value/axis labels).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>