Real-world sources publish multiple chapters at the same number:
different scanlators ("Ch.52 from bloomingdale" + "Ch.52 from mina"),
translator notices and farewells, alt-translations. The (manga_id,
number) UNIQUE constraint from 0001 silently collapsed all of those
into a single row via the upsert path in repo::crawler. Migration 0013
drops the constraint; sync_manga_chapters now plain-INSERTs each
SourceChapterRef so every parsed chapter survives as its own row.
Identity moves from the (manga_id, number) tuple to the chapter UUID:
- `GET /api/v1/mangas/:manga_id/chapters/:chapter_id` (replaces :number)
- `GET /api/v1/mangas/:manga_id/chapters/:chapter_id/pages`
- `repo::chapter::find_by_id_in_manga` (replaces find_by_manga_and_number)
- Frontend reader route renamed to `/manga/[id]/chapter/[chapter_id]`
- Chapter links throughout (manga page list, continue-reading CTA,
reader prev/next, history rows, bookmark cards) use chapter.id
- API clients getChapter/getChapterPages take a chapter id string
read_progress + bookmarks already FK chapter_id; they only enrich with
chapter_number for display, which is preserved.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
19 lines
999 B
SQL
19 lines
999 B
SQL
-- Real-world sources publish multiple chapters at the same number:
|
|
-- different uploaders, translator notices/farewells, paid-vs-free
|
|
-- re-uploads, and our own users can legitimately have two versions of
|
|
-- "Ch.52" with different scanlations. The (manga_id, number) UNIQUE
|
|
-- from 0001_init silently collapses all of those into a single row via
|
|
-- ON CONFLICT, dropping data. Drop the constraint and lean on the
|
|
-- chapter id (UUID) as the only chapter identity going forward.
|
|
|
|
ALTER TABLE chapters DROP CONSTRAINT chapters_manga_id_number_key;
|
|
|
|
-- The UNIQUE was also our only index on (manga_id, number) since
|
|
-- 0007 dropped the redundant explicit one. Chapter list pages
|
|
-- ORDER BY number ASC and the manga page is a hot read path, so put
|
|
-- the index back without the uniqueness. Secondary sort by created_at
|
|
-- so duplicate-numbered chapters have a stable order in lists and
|
|
-- prev/next navigation.
|
|
CREATE INDEX chapters_manga_id_number_idx
|
|
ON chapters (manga_id, number, created_at);
|