-- Partial indexes that back the admin crawler dashboard hot reads:
--   * mangas with no cover — drives count_missing_covers /
--     list_missing_cover_mangas (the cover backlog the metadata pass drains).
--   * dead jobs              — drives list_dead_jobs / requeue_dead_jobs.
-- Both filters are highly selective in steady state (the working sets are a
-- tiny fraction of the full tables), so the partials stay small and hot.
-- ORDER BY updated_at DESC matches the LIMIT/OFFSET page reads.
--
-- Not CONCURRENTLY: sqlx::migrate! wraps each migration in a transaction;
-- CREATE INDEX CONCURRENTLY can't run inside one. Tables are small at our
-- scale (online deploy still safe).

CREATE INDEX IF NOT EXISTS mangas_missing_cover_idx
    ON mangas (updated_at DESC)
    WHERE cover_image_path IS NULL;

CREATE INDEX IF NOT EXISTS crawler_jobs_dead_idx
    ON crawler_jobs (updated_at DESC)
    WHERE state = 'dead';
