Skip to content

fix(bindery): stop deriving a book's series from its own title#121

Merged
bndct-devops merged 1 commit into
mainfrom
fix/bindery-series-derivation
Jul 5, 2026
Merged

fix(bindery): stop deriving a book's series from its own title#121
bndct-devops merged 1 commit into
mainfrom
fix/bindery-series-derivation

Conversation

@bndct-devops

Copy link
Copy Markdown
Owner

Problem

Books imported through the Bindery review flow could come out with their series set to their own title (the "Good Guys" incident: 4 EPUBs each landed as series="" instead of "The Good Guys"). Three defects compounded:

  1. The bare-trailing-number heuristic misfired on novels. Dukes and Ladders 5.epub → series "Dukes and Ladders", content type "chapter". That convention is right for manga (One Piece 1050.cbz) but wrong for prose.
  2. The real series marker was destroyed before parsing. (The Bad Guys Book 8)-style parentheticals — the standard Amazon/Calibre naming — were stripped as noise. A prod file literally carried the correct series in its name and lost it.
  3. Embedded metadata never reached the review form. /bindery/preview extracts calibre:series (and EPUB3 collections) into file_metadata, but the frontend discarded it — only the filename guess reached the form, and the external candidate apply kept it whenever the candidate had no series.

Fix

  • filename_parser.py: parse (Series Book N) / (Series, Book N) / (Series #N) before noise-stripping; understand the organizer's NN. Title - Author (Year) layout (now extracting the author, which the review form previously always left blank); bare trailing numbers on EPUB/PDF set the index but no longer fabricate a series — CBZ/CBR keep the chapter convention.
  • BinderyPage.tsx: merge embedded file_metadata into the review form before the candidate auto-apply — same "file beats filename" precedence auto-import has always had. Applies to single review and Match All.
  • bindery.py: list endpoint returns the parsed author; main.py auto-import uses it as a fallback when nothing is embedded.

Verification

  • 13 new parser regression tests, including the literal prod filename from the incident; full suite 859 green; frontend tsc -b build clean.
  • End-to-end through the review UI with fixture EPUBs: the original incident shape (Dukes and Ladders 5.epub with embedded calibre:series) now lands as series="The Good Guys" idx 5; (Cradle, Book 1) parses from the parenthetical; 07. Back to One - Eric Ugland (2021).epub pre-fills author.

Deliberately untouched (pre-existing): the review screen auto-applies the top external candidate with no confidence gate — a book absent from the catalogs can still get confidently wrong metadata. Worth its own issue if it bites.

Three compounding defects made Bindery imports come out with
series = the book's own title (the "Good Guys" incident):

- The bare-trailing-number heuristic ("Dukes and Ladders 5.epub")
  fabricated series=title and typed novels as chapters. It now only
  applies to comic formats; prose ebooks keep the index but no series.
- The real series name in "(Series Book N)" parentheticals — standard
  Amazon/Calibre naming — was deleted as noise before parsing. It is
  now parsed first ("(The Bad Guys Book 8)", "(Cradle, Book 1)",
  "(Series #7)").
- The review UI extracted embedded metadata (calibre:series etc.) on
  preview and then discarded it; only the filename guess reached the
  form. file_metadata now merges into the form before the candidate
  auto-apply, with the same file-beats-filename precedence auto-import
  has always had (single review + Match All).

The parser also understands the organizer's "NN. Title - Author (Year)"
layout, so the review form now pre-fills the author (and auto-import
uses it as fallback when nothing is embedded).

Verified end-to-end via fixture EPUBs through the review flow: the
original incident shape now lands as series="The Good Guys" idx 5.
859 tests green (13 new parser regressions incl. the literal prod
filename), frontend build clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bndct-devops bndct-devops merged commit edeaa98 into main Jul 5, 2026
2 checks passed
@bndct-devops bndct-devops deleted the fix/bindery-series-derivation branch July 5, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant