feat(metadata): implement single-track metadata editor API (§A7/§1H)
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled

Adds inline AcoustID match-finding (multiple ranked candidates via
lookup_all) and PUT /tracks/{id}/metadata for manual edits, resolving
artist/album and setting metadata_status=manual. Extends TrackOut with
genre/year/track_number.
This commit is contained in:
Senko-san
2026-06-13 14:34:43 +03:00
parent 73d7da440f
commit 63c7d05eca
14 changed files with 438 additions and 16 deletions
@@ -26,6 +26,7 @@ def _to_entity(row: TrackModel) -> Track:
duration_seconds=row.duration_seconds,
genre=row.genre,
year=row.year,
track_number=row.track_number,
metadata_status=row.metadata_status,
metadata_error=row.metadata_error,
enriched_at=row.enriched_at,
@@ -162,6 +163,9 @@ class SqlAlchemyTrackRepository:
title: str | None,
genre: str | None,
year: int | None,
artist_id: uuid.UUID | None = None,
album_id: uuid.UUID | None = None,
track_number: int | None = None,
) -> Track:
row = await self._session.get(TrackModel, track_id)
if row is None:
@@ -172,6 +176,12 @@ class SqlAlchemyTrackRepository:
row.genre = genre
if year is not None:
row.year = year
if artist_id is not None:
row.artist_id = artist_id
if album_id is not None:
row.album_id = album_id
if track_number is not None:
row.track_number = track_number
row.metadata_status = "manual"
await self._session.flush()
await self._session.refresh(row)