--- id: ML-176.1 title: "API: accept search query parameter on GET /api/v1/collection" status: To Do assignee: [] created_date: "2026-05-10 13:35" labels: - api - backend - collection milestone: m-0 dependencies: [] references: - lib/music_library/records/search.ex (FTS5 search implementation) - lib/music_library_web/controllers/collection_json.ex (response format) modified_files: - lib/music_library_web/controllers/collection_controller.ex parent_task_id: ML-176 priority: medium --- ## Description Extend the existing `GET /api/v1/collection` endpoint to accept an optional `q` query parameter for full-text search. When `q` is present and non-empty, pass it to `Collection.search_records/2` instead of the current empty-string default. When absent or empty, preserve existing behavior (return all collection records). The existing FTS5 search in `Records.Search` handles the query — no new search logic is needed. It searches across all indexed fields (title, artists, genres) and supports the `artist:`, `album:`, etc. structured syntax, though the Presto client will only send plain text. **Response format**: unchanged — the existing `CollectionJSON.index/1` already returns `{total, limit, offset, records}` with all fields the Presto needs. **Key decisions** (from user): - Collection-only scope (purchased_at IS NOT NULL) — already the default for this endpoint - Alphabetical ordering — already the default - Plain text query — passed as-is to FTS5 - Always returns paginated (limit/offset) — existing behavior ## Acceptance Criteria - [ ] #1 GET /api/v1/collection returns all records when q is absent (existing behavior unchanged) - [ ] #2 GET /api/v1/collection?q=beatles returns only records matching FTS5 query for 'beatles' - [ ] #3 GET /api/v1/collection?q= returns all records (empty string treated as no query) - [ ] #4 GET /api/v1/collection?q=beatles&limit=5&offset=0 respects pagination with search - [ ] #5 Response format matches existing schema: {total, limit, offset, records} with all record fields - [ ] #6 Controller test covers: no q param, empty q, populated q, q with no matches, q with pagination