DNB rewrite:
- Multiple query strategies with fallback (title+author+mat=ton →
title+author → title+mat=ton → title-only → fulltext). Returns on
first hit. Most German audiobooks aren't tagged mat=ton in DNB,
which was killing all searches.
- Strip CQL wildcard chars (?, *, <, >, =, /, quotes) from search
terms. The "???" in "Die drei ???" was breaking the CQL parser.
- Log HTTP status, body snippet on non-200, and numberOfRecords on
every query so log shows exactly what DNB returned.
- Parse SRU diagnostic elements (DNB error messages buried in XML).
- Convert author/narrator from "Lastname, Firstname" to
"Firstname Lastname" for consistency with other sources.
Matcher:
- Split series patterns: WITH_EPISODE (need digit) and SERIES_ONLY
(just the series name). "Die drei ??? und der Fluch des Rubins"
now properly detects "Die drei ???" as series even without folge#.
- New _build_search_title: removes ??? sequences, trailing parens,
collapses whitespace, before sending to APIs.
- Manual search also passes through normalization. Logs source +
hit count per query.
Debug endpoint:
- GET /api/items/match/debug?title=...&author=... returns raw results
from all 4 sources with status, error messages, and full metadata.
- "Debug" button added in BookDetail — shows what each API actually
returns inline, so the user can see if it's a search problem,
parse problem, or threshold problem.
- "Cover aus Datei" button — triggers local cover extraction
(folder.jpg or embedded artwork) on demand.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MatchResult was missing subtitle field, causing AttributeError in
_apply_match that silently killed every background match task
- Wrap _apply_match in try/except with exc_info logging so failures
are visible in docker compose logs backend
- New POST /api/libraries/:id/match-all endpoint to trigger matching
for all unlocked items (useful for items scanned before the fix)
- Admin UI: Match button per library next to the Scan button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>