Files
Mangalord/backend/migrations/0030_page_analysis_analyzed_at_index.sql
MechaCat02 c6a6d1690d feat(admin): time-series trend charts on the metrics tabs (0.87.0)
Turn the dormant timing data in crawl_metrics / page_analysis into "is it
healthy over time" views. New bucketed series queries (GROUP BY date_trunc,
hour|day via a closed Bucket enum so the unit can't be attacker-controlled)
behind GET /v1/admin/{crawler,analysis}/metrics/series, with a shared
SeriesParams/resolve_bucket helper (bad bucket → 400) and migration 0030
indexing page_analysis(analyzed_at) for the analysis scan.

Frontend: a dependency-free SVG TrendChart (line+area, null buckets render as
gaps, empty-state, role=img) embedded above the per-op tables in Crawler and
Analysis → Metrics, driven by each panel's existing window selector with
AbortController-cancelled fetches. A buildSeries() util fills the continuous
bucket axis (throughput 0 for empty buckets, success/duration null) — unit
tested alongside the chart and the series API client.

Closes the Phase-1 observability set (audit log · health checks · trends).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 11:48:56 +02:00

9 lines
519 B
SQL

-- Index for the Analysis trend-chart series, which buckets terminal page
-- analyses by `analyzed_at` (date_trunc) over a recent window. Without it the
-- bucketed GROUP BY falls back to a full scan of page_analysis (one row per
-- page in the library). Partial to the rows the series query actually reads
-- (terminal status with a timestamp), keeping the index small.
CREATE INDEX IF NOT EXISTS page_analysis_analyzed_at_idx
ON page_analysis (analyzed_at)
WHERE status <> 'pending' AND analyzed_at IS NOT NULL;