Waves 1-2: scrobble_live/index, scrobbled_tracks_live/index, release_group_show, release_show. Dropped unwrap/2 bridges and page_title/1 usage. Search form tests use visit with query params. page_title tests use assert_has("title", ...).
Import workers now broadcast :records_index_changed on
"records:index_changed" after successful import via
Records.broadcast_index_changed/0.
CollectionLive.Index and WishlistLive.Index subscribe to the
topic in mount/3 and reload their record streams on receipt,
with a live_action guard to skip reloads when the grid is
hidden behind a modal (:import, :barcode_scan).
IndexActions.handle_index_changed/1 refreshes total_entries
before reloading to keep the pagination bar accurate.
Replace phx-click server event with Fluxon.open_dialog for zero-latency
modal opening. The modal DOM is now always present (no :if conditional) so
it can be shown instantly; the server syncs state in the background.
Fix test selectors that now match the always-present modal form by scoping
to forms without phx-target (which the modal form always has).
- show/2: use case instead of bare Integer.parse match so
/api/v1/errors/not-an-id returns 404 instead of crashing
- index/2: clamp limit to >= 1 and offset to >= 0 to prevent
SQLite from treating negative values as unlimited
- Add 3 tests: non-integer id 404, negative limit/offset clamping
Closes ML-143 review findings:
- cast_id/1 uses Integer.parse instead of String.to_integer
- add_to_cart validates against server-side release_groups
- JS.push payload trimmed to {id, format} only
- Oban.insert_all result checked for partial failures
- handle_async success resets @importing? to false
- ImportFromMusicbrainzReleaseGroup gets unique constraint
- Record.parse_datetime/1 made public with safe match
- Workers delegate to Record.parse_datetime/1
- Test coverage: change_format, clear_cart, wishlist single import
Covers all action handlers on LiveHelpers.RecordActions and all
update/event clauses on Components.Chat — including streaming
chunk/done/error transitions and the retry re-send path.
Closes#179