From cc0d97b160ded9c09b1bf5990c2c3e7b72a72f31 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sun, 10 May 2026 14:39:03 +0100 Subject: [PATCH] ML-176: requirements --- ...rch-application-with-on-screen-keyboard.md | 41 +++++++ ...uery-parameter-on-GET-api-v1-collection.md | 52 ++++++++ ...een-search-views-and-on-screen-keyboard.md | 115 ++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 backlog/tasks/ml-176 - Presto-add-search-application-with-on-screen-keyboard.md create mode 100644 backlog/tasks/ml-176.1 - API-accept-search-query-parameter-on-GET-api-v1-collection.md create mode 100644 backlog/tasks/ml-176.2 - Presto-add-splash-screen-search-views-and-on-screen-keyboard.md diff --git a/backlog/tasks/ml-176 - Presto-add-search-application-with-on-screen-keyboard.md b/backlog/tasks/ml-176 - Presto-add-search-application-with-on-screen-keyboard.md new file mode 100644 index 00000000..89df483e --- /dev/null +++ b/backlog/tasks/ml-176 - Presto-add-search-application-with-on-screen-keyboard.md @@ -0,0 +1,41 @@ +--- +id: ML-176 +title: "Presto: add search application with on-screen keyboard" +status: To Do +assignee: [] +created_date: "2026-05-10 13:34" +updated_date: "2026-05-10 13:36" +labels: + - presto + - search + - feature +milestone: m-0 +dependencies: + - ML-176.1 + - ML-176.2 +priority: medium +--- + +## Description + + + +Add a search feature to the Presto application that lets users type a query on an on-screen QWERTY keyboard, search the collection via a new API query parameter, and browse results reusing the existing record list and detail views. + +The app is unified with the existing "Records On This Day" calendar: boot shows a splash screen with two entry points — "Search Collection" and "Today's Records". + + + +## Acceptance Criteria + + + +- [ ] #1 Splash screen on boot shows 'Search Collection' and 'Today's Records' entry points +- [ ] #2 User can search the collection by typing on an on-screen QWERTY keyboard and tapping OK +- [ ] #3 Search results display as a scrollable list of records with cover art, title, artist, format, and year +- [ ] #4 Tapping a search result opens the record detail view (same as day view detail) +- [ ] #5 Back navigation is context-aware: returns to search results from search detail, to day view from day detail +- [ ] #6 Existing 'Records On This Day' calendar flow is unchanged +- [ ] #7 GET /api/v1/collection accepts optional q parameter for FTS5 full-text search +- [ ] #8 Empty query on API returns all records (backward compatible) + diff --git a/backlog/tasks/ml-176.1 - API-accept-search-query-parameter-on-GET-api-v1-collection.md b/backlog/tasks/ml-176.1 - API-accept-search-query-parameter-on-GET-api-v1-collection.md new file mode 100644 index 00000000..3e81904f --- /dev/null +++ b/backlog/tasks/ml-176.1 - API-accept-search-query-parameter-on-GET-api-v1-collection.md @@ -0,0 +1,52 @@ +--- +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 + diff --git a/backlog/tasks/ml-176.2 - Presto-add-splash-screen-search-views-and-on-screen-keyboard.md b/backlog/tasks/ml-176.2 - Presto-add-splash-screen-search-views-and-on-screen-keyboard.md new file mode 100644 index 00000000..e0c2a7ce --- /dev/null +++ b/backlog/tasks/ml-176.2 - Presto-add-splash-screen-search-views-and-on-screen-keyboard.md @@ -0,0 +1,115 @@ +--- +id: ML-176.2 +title: "Presto: add splash screen, search views, and on-screen keyboard" +status: To Do +assignee: [] +created_date: "2026-05-10 13:35" +labels: + - presto + - search + - micropython +milestone: m-0 +dependencies: [] +references: + - presto/AGENTS.md (constraints and patterns) + - presto/README.md (API contract) +modified_files: + - presto/records_on_the_day.py +parent_task_id: ML-176 +priority: medium +--- + +## Description + + + +Refactor `presto/records_on_the_day.py` into a unified app with a splash screen, search capability, and the existing calendar. All work is in the single MicroPython file. + +## New states + +- `STATE_HOME` (new, default on boot/wake) +- `STATE_SEARCH_INPUT` (new — search box + on-screen keyboard) +- `STATE_SEARCH_RESULTS` (new — results list, reuses day-view rendering) +- `STATE_MONTH` / `STATE_DAY` / `STATE_RECORD` (existing, unchanged logic) + +## Splash screen (STATE_HOME) + +- Two large touch targets: "Search Collection" and "Today's Records" +- "Today's Records" → transitions to existing `STATE_MONTH` / today's records flow +- "Search Collection" → transitions to `STATE_SEARCH_INPUT` +- On boot and display wake: always show `STATE_HOME` + +## On-screen keyboard (part of STATE_SEARCH_INPUT) + +- 3-row QWERTY layout: qwertyuiop / asdfghjkl / zxcvbnm +- Bottom row: [123 toggle] [space] [⌫ backspace] [OK] +- Numbers keyboard: 1234567890 / symbols row / [ABC toggle] [space] [⌫] [OK] +- Space and ⌫ are shared between both layouts +- Lowercase only, no shift/caps +- OK button disabled (dimmed) when query is empty +- Each key is a rounded rectangle, touch-mapped to append/delete chars +- Visual feedback on key press (brief highlight) +- Query buffer displayed in a text field area above the keyboard, max ~50 chars + +## Search triggering + +- User types query, presses OK +- OK calls `fetch_search_results(query)` → API +- Transitions to `STATE_SEARCH_RESULTS` + +## Search results (STATE_SEARCH_RESULTS) + +- Reuses existing `_draw_record_list()`, scroll, and row rendering from day view +- Header shows "Search: " with Back button +- Back returns to `STATE_SEARCH_INPUT` (preserving query so user can refine) +- Tapping a record → `STATE_RECORD` (detail view, unchanged) +- Back from detail → returns to search results +- Empty results: "No records found" full-screen message +- Error: "Could not reach server" with retry-on-tap (same as day view) +- 20 results per page, no infinite scroll + +## API client + +- New `fetch_search_results(query)` function +- Calls `GET /api/v1/collection?q=&limit=20` +- Parses `{total, records, ...}` response +- Returns `(records_list, error_flag)` tuple (same shape as `fetch_records`) + +## Navigation state + +- Track previous state to know where "Back" in detail view should go +- Detail Back → search results when entered from search +- Detail Back → day view when entered from day +- Month view and search views both have "Back to Home" + +## Constraints + +- Must reuse existing record row rendering (`_draw_record_row`), detail view (`draw_record_detail`), thumbnail fetching, WiFi, NTP, display sleep logic +- Scroll performance rules from AGENTS.md still apply +- Memory: no large buffers, keep GC pressure low + + +## Acceptance Criteria + + + +- [ ] #1 On boot, splash screen shows with 'Search Collection' and 'Today's Records' buttons +- [ ] #2 Tapping 'Today's Records' opens the existing month calendar (unchanged behavior) +- [ ] #3 Tapping 'Search Collection' opens search input view with on-screen QWERTY keyboard +- [ ] #4 Keyboard: tapping letter keys builds query string shown in input field +- [ ] #5 Keyboard: backspace removes last character +- [ ] #6 Keyboard: 123/ABC toggle switches between QWERTY and numbers keyboard layouts +- [ ] #7 Keyboard: OK button is visually disabled (dimmed) when query is empty +- [ ] #8 Keyboard: OK button triggers API search when query is non-empty +- [ ] #9 Search results display using same record row layout as day view (cover, title, artist, format, year) +- [ ] #10 Search results: Back button returns to search input view with query preserved +- [ ] #11 Search results: tapping a record opens detail view +- [ ] #12 Detail view Back returns to search results when entered from search +- [ ] #13 Detail view Back returns to day view when entered from day +- [ ] #14 Empty results show 'No records found' full-screen message +- [ ] #15 API error shows 'Could not reach server' with retry-on-tap +- [ ] #16 Display sleep/wake always returns to splash screen +- [ ] #17 Scroll in search results works identically to day view scroll +- [ ] #18 Keyboard renders correctly at 720×720: all keys visible and tappable +- [ ] #19 Back-to-Home navigation available from month view and search views +