feat(library): remote browse status + save/materialize API (§Phase2-3)
Search results now report whether a hit is already saved (in_library,
track_id, availability). New RemoteLibraryService backs POST
/tracks/remote (idempotent placeholder save) and POST
/tracks/{id}/materialize (on-demand fetch via a new materialize_track
arq task, reusing in-flight jobs).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ is an admin action and runs in a worker — the endpoint only enqueues it.
|
||||
|
||||
from fastapi import APIRouter, Query
|
||||
|
||||
from app.api.deps import CurrentUser, SourceRegistryDep, SuperUser
|
||||
from app.api.deps import CurrentUser, SourceRegistryDep, SuperUser, TrackRepoDep
|
||||
from app.api.schemas.external_search import ExternalSearchResponse, ExternalSearchResultOut
|
||||
from app.api.schemas.source import ScanResponse, SourceHealthOut, SourceInfoOut
|
||||
from app.domain.errors import DependencyUnavailableError
|
||||
@@ -42,6 +42,7 @@ async def search_source(
|
||||
source: str,
|
||||
_: CurrentUser,
|
||||
registry: SourceRegistryDep,
|
||||
track_repo: TrackRepoDep,
|
||||
q: str = Query(min_length=1),
|
||||
limit: int = Query(20, ge=1, le=50),
|
||||
) -> ExternalSearchResponse:
|
||||
@@ -49,7 +50,8 @@ async def search_source(
|
||||
if not backend.is_available():
|
||||
raise DependencyUnavailableError(f"Source {source!r} is not available.")
|
||||
results = await backend.search(q, limit=limit)
|
||||
return ExternalSearchResponse(
|
||||
results=[ExternalSearchResultOut.from_entity(r) for r in results],
|
||||
searched_sources=[source],
|
||||
)
|
||||
out: list[ExternalSearchResultOut] = []
|
||||
for r in results:
|
||||
existing = await track_repo.get_by_source(r.source, r.source_id)
|
||||
out.append(ExternalSearchResultOut.from_entity(r, existing=existing))
|
||||
return ExternalSearchResponse(results=out, searched_sources=[source])
|
||||
|
||||
Reference in New Issue
Block a user