feat(service-storage-harness): slice 3 — migrate MediaIndex onto harness (scoped replace_items, +service_id)

Register MediaIndex as a harness concern with ALTER TABLE migration to add
service_id column (idempotent). Scope replace_items by service_id (FIXES latent
global-clear bug where building for one Jellyfin wiped another's rows). Scope
query by service_id (empty-string = all rows, backward-compat). Thread
service_id through build_media_index + worker + query_media router. New
regression test proves scoped replace preserves other services' rows.

Backend: 321 pytest pass, ruff clean. Frontend: build green.
This commit is contained in:
Developer
2026-07-09 09:00:31 +00:00
parent 1fb12b8a0a
commit c87f398e37
5 changed files with 93 additions and 7 deletions
@@ -282,6 +282,7 @@ def query_media(
sort_order: str = Query("Ascending", description="Ascending or Descending"),
limit: int = Query(100, ge=1, le=1000),
offset: int = Query(0, ge=0),
jellyfin_service_id: str | None = None,
client: JellyfinClient = Depends(get_jellyfin_client),
user_id: str = Depends(get_user_id),
index: MediaIndex = Depends(get_media_index),
@@ -316,6 +317,7 @@ def query_media(
sort_order=sort_order,
limit=limit,
offset=offset,
service_id=jellyfin_service_id or "",
)
logger.info("Media query returned total=%s rows=%s", total, len(rows))