ML-176.1: support search in collection api controller
This commit is contained in:
+59
-9
@@ -1,10 +1,11 @@
|
||||
---
|
||||
id: ML-176.1
|
||||
title: "API: accept search query parameter on GET /api/v1/collection"
|
||||
status: To Do
|
||||
assignee: []
|
||||
status: Done
|
||||
assignee:
|
||||
- pi
|
||||
created_date: "2026-05-10 13:35"
|
||||
updated_date: "2026-05-10 13:41"
|
||||
updated_date: "2026-05-10 13:49"
|
||||
labels:
|
||||
- api
|
||||
- backend
|
||||
@@ -44,12 +45,12 @@ The existing FTS5 search in `Records.Search` handles the query — no new search
|
||||
|
||||
<!-- AC:BEGIN -->
|
||||
|
||||
- [ ] #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
|
||||
- [x] #1 GET /api/v1/collection returns all records when q is absent (existing behavior unchanged)
|
||||
- [x] #2 GET /api/v1/collection?q=beatles returns only records matching FTS5 query for 'beatles'
|
||||
- [x] #3 GET /api/v1/collection?q= returns all records (empty string treated as no query)
|
||||
- [x] #4 GET /api/v1/collection?q=beatles&limit=5&offset=0 respects pagination with search
|
||||
- [x] #5 Response format matches existing schema: {total, limit, offset, records} with all record fields
|
||||
- [x] #6 Controller test covers: no q param, empty q, populated q, q with no matches, q with pagination
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Plan
|
||||
@@ -140,3 +141,52 @@ No cost impact. No external API calls, no additional storage, no compute changes
|
||||
No documentation updates needed. The API endpoint already exists in `router.ex`. The `q` parameter is additive and optional — existing API consumers are unaffected. If project API docs exist externally, note that `GET /api/v1/collection` now accepts `?q=<search term>` as an optional parameter, but this is self-documenting via the REST pattern.
|
||||
|
||||
<!-- SECTION:PLAN:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
|
||||
Implementation complete. Changes:
|
||||
|
||||
1. **Controller** (`lib/music_library_web/controllers/collection_controller.ex`):
|
||||
- Added `query = normalize_query(params["q"])` in `index/2`
|
||||
- Pass `query` to `search_records_count/1` and `search_records/2` instead of hardcoded `""`
|
||||
- Added private `normalize_query/1` helper: nil → "", "" → "", otherwise passthrough
|
||||
|
||||
2. **Tests** (`test/music_library_web/controllers/collection_controller_test.exs`):
|
||||
- 5 new tests added:
|
||||
- `q` param matches → returns filtered results
|
||||
- Empty `q` string → returns all records
|
||||
- `q` with no matches → returns `total: 0`, empty `records`
|
||||
- `q` with pagination → respects limit/offset on filtered results
|
||||
- Response shape validation → confirms schema is unchanged
|
||||
|
||||
3. **Full test suite**: 968 passed (0 failures), no regressions
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
## Final Summary
|
||||
|
||||
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
||||
|
||||
## Summary
|
||||
|
||||
Extended `GET /api/v1/collection` to accept an optional `q` query parameter for FTS5 full-text search.
|
||||
|
||||
### Changes
|
||||
|
||||
**Controller** (`lib/music_library_web/controllers/collection_controller.ex`):
|
||||
|
||||
- `index/2` now reads `params["q"]` and normalizes nil/empty → `""` via a new private `normalize_query/1` helper
|
||||
- Passes the query string to the existing `Collection.search_records_count/1` and `Collection.search_records/2` pipeline (previously hardcoded `""`)
|
||||
|
||||
**Tests** (`test/music_library_web/controllers/collection_controller_test.exs`):
|
||||
|
||||
- 5 new tests: matching query, empty query string, no-match query, pagination with search, and response shape validation
|
||||
|
||||
### Key points
|
||||
|
||||
- No new search logic — reuses existing `Records.Search.build_search/3` which already handled empty queries as a no-op
|
||||
- Response format unchanged — `CollectionJSON.index/1` returns the same shape
|
||||
- No route/schema/migration changes required
|
||||
- Full suite: 968 passed, 0 regressions
|
||||
<!-- SECTION:FINAL_SUMMARY:END -->
|
||||
|
||||
Reference in New Issue
Block a user