fix(e5): address code-review findings (TMDB guid media_type, search ingest guard, discover keying)
Follow-ups from the epic-end /code-review of the E5 branch: - tmdb.resolve_recs + people._resolve_known_for: match recommendations/ credits to the library bucketed by media_type. TMDB movie ids and tv ids are independent sequences, so a bare `tmdb:<id>` match could deep-link a movie rec to an unrelated show (or vice-versa) on a numeric collision. Regression test added (test_resolve_recs_matches_by_media_type_not_bare_id). - routes/search: wrap the _ingest_candidates call so a DB/enrich failure degrades to a 422 with a message instead of a bare 500 hidden behind the FE's generic "search failed" (extends the B-core-1 rationale); rollback on failure. Stamp enriched_at with its own timestamp taken after the enrich, not the stub-insert placeholder. - routes/plex/discover: key serialized cards back by rating_key (globally unique in Plex) instead of id(obj); fix the stale rows 3-tuple annotation.
This commit is contained in:
@@ -212,3 +212,45 @@ def test_enrich_batch_skips_shows_without_guid(db):
|
||||
assert tmdb.enrich_batch(db, FakeTmdb(), 50) == 0
|
||||
db.refresh(sh)
|
||||
assert sh.tmdb_enriched_at is None
|
||||
|
||||
|
||||
def test_resolve_recs_matches_by_media_type_not_bare_id(db):
|
||||
# TMDB movie ids and tv ids are independent, so tmdb:500 can be BOTH a show (in our library) and a
|
||||
# movie recommendation. The match must respect media_type — a bare-id match would deep-link the movie
|
||||
# rec to the unrelated show (and vice-versa).
|
||||
mlib = _lib(db, key="10", kind="movie")
|
||||
slib = _lib(db, key="11", kind="show")
|
||||
show500 = PlexShow(rating_key="s500", library_id=slib.id, title="Show 500", guid="tmdb:500")
|
||||
movie900 = PlexItem(
|
||||
rating_key="m900", library_id=mlib.id, kind="movie", title="Movie 900", guid="tmdb:900"
|
||||
)
|
||||
db.add_all([show500, movie900])
|
||||
db.commit()
|
||||
|
||||
# A movie rec for id 500 must NOT match show s500; a tv rec for id 900 must NOT match movie m900.
|
||||
miss = {
|
||||
r["tmdb_id"]: r
|
||||
for r in tmdb.resolve_recs(
|
||||
db,
|
||||
[
|
||||
{"tmdb_id": 500, "title": "Movie 500", "media_type": "movie"},
|
||||
{"tmdb_id": 900, "title": "Show 900", "media_type": "tv"},
|
||||
],
|
||||
)
|
||||
}
|
||||
assert miss[500]["in_library"] is False and miss[500]["rating_key"] is None
|
||||
assert miss[900]["in_library"] is False and miss[900]["rating_key"] is None
|
||||
|
||||
# The right media_type DOES resolve to the right row.
|
||||
hit = {
|
||||
r["tmdb_id"]: r
|
||||
for r in tmdb.resolve_recs(
|
||||
db,
|
||||
[
|
||||
{"tmdb_id": 900, "media_type": "movie"},
|
||||
{"tmdb_id": 500, "media_type": "tv"},
|
||||
],
|
||||
)
|
||||
}
|
||||
assert hit[900]["in_library"] is True and hit[900]["rating_key"] == "m900"
|
||||
assert hit[500]["in_library"] is True and hit[500]["rating_key"] == "s500"
|
||||
|
||||
Reference in New Issue
Block a user