Files
Mangalord/backend/migrations/0033_mangas_updated_at_index.sql
MechaCat02 78edea4277 fix(mangas): address review on sort feature — alias, index, validation, a11y
Backend
- sort=recent stays a back-compat alias for created (parse_sort); invalid
  sort/order now return the structured 422 envelope instead of plain-text 400
- per-field default direction on omitted order (dates desc, text asc), matching
  the frontend so a bare ?sort=<field> reads the same in UI and API
- migration 0033: index mangas(updated_at DESC, id) backing the default sort
  and its id tie-break; NULLS LAST now applied only to the nullable author key
- tests: recent alias, per-field default (title+author), invalid-value 422,
  and a tie-break test that pins ordering by ascending id (mutation-verified)

Frontend
- pure sort helpers extracted to $lib/mangaSort with unit tests; coerceSort
  honors the recent alias so pasted/legacy URLs resolve to the same field
- SegmentedControl: roving tabindex + arrow/Home/End keyboard nav, anchored on
  focus so rapid keypresses don't stick
- UX: visible "Direction" labels (desktop + mobile), mobile sort-sheet section
  headings and a "Done" button; README sort/order contract updated

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 07:15:33 +02:00

17 lines
917 B
SQL

-- Back the default catalog ordering. Since 0.88.0 the catalog list defaults to
-- `ORDER BY updated_at DESC, id` (the no-filter default path), but the only
-- existing updated_at index on mangas is the PARTIAL `mangas_missing_cover_idx`
-- (WHERE cover_image_path IS NULL), which Postgres can't use for the unfiltered
-- ordering. `created_at` and `lower(title)` already have full indexes from
-- 0001; this gives the new default sort column the same treatment.
--
-- `id` is included as a trailing key so the index also covers the stable
-- `, id` tie-break the listing appends for deterministic pagination.
--
-- Not CONCURRENTLY: sqlx::migrate! wraps each migration in a transaction, and
-- CREATE INDEX CONCURRENTLY can't run inside one. The table is small at our
-- scale, so a brief lock on an online deploy is acceptable.
CREATE INDEX IF NOT EXISTS mangas_updated_at_idx
ON mangas (updated_at DESC, id);