Import issue history in backlog.md
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
---
|
||||
id: ML-123
|
||||
title: Hide collected release input and details for wishlisted records
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:59'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/40'
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2025-05-07 · updated 2025-05-08 · closed 2025-05-08 · not planned_
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: ML-16
|
||||
title: Inconsistent HTTP timeout configuration across API clients
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:50'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/163'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-09 · closed 2026-04-08 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
HTTP timeout configuration varies significantly across API integrations with no documented rationale for the differences.
|
||||
|
||||
## Evidence
|
||||
|
||||
- **Last.fm**: Custom `pool_timeout: 10_000`, `receive_timeout: 2500`, `connect_timeout: 2500`
|
||||
- **OpenAI GPT**: `receive_timeout: 10_000`, `connect_timeout: 2_500`
|
||||
- **OpenAI Chat stream**: `receive_timeout: 60_000`, `connect_timeout: 5_000`
|
||||
- **MusicBrainz, Discogs, Wikipedia, Brave Search**: Default timeouts only (no custom configuration)
|
||||
|
||||
## Why This Matters
|
||||
|
||||
- No consistency in how timeouts are configured
|
||||
- Unclear whether defaults are appropriate for each API's characteristics
|
||||
- Last.fm applied custom timeouts based on observed issues; other APIs may have similar unaddressed problems
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
1. Audit each API's typical response times
|
||||
2. Set explicit, documented timeout values for all API clients
|
||||
3. Consider making timeouts configurable via each API's Config module
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- All API clients have explicit, intentional timeout configuration
|
||||
- Timeout choices are documented (e.g., in Config module comments)
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 All API clients have explicit, intentional timeout configuration
|
||||
- [ ] #2 Timeout choices are documented (e.g., in Config module comments)
|
||||
<!-- AC:END -->
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: ML-18
|
||||
title: Three representations of artists without clear canonical source
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:50'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/161'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-09 · closed 2026-04-08 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
Artist data exists in three different forms with no clear canonical source:
|
||||
1. `Record` embeds `:artists` (embedded schema in record)
|
||||
2. `ArtistRecord` — separate lookup table/view
|
||||
3. `ArtistInfo` — external metadata store
|
||||
|
||||
## Why This Matters
|
||||
|
||||
- Unclear which representation is authoritative for a given use case
|
||||
- Updates to one representation don't automatically propagate to others
|
||||
- New developers must understand all three to work with artist data
|
||||
|
||||
## Affected Files
|
||||
|
||||
- `lib/music_library/records/record.ex` (embedded `:artists`)
|
||||
- `lib/music_library/records/artist_records.ex`
|
||||
- `lib/music_library/artists/artist_info.ex`
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
Document the purpose and canonical use case for each representation. Consider whether `ArtistRecord` (DB view) can be simplified or whether the embedded artists on Record should be the single source for record-artist relationships.
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- Clear documentation of each representation's purpose
|
||||
- Reduced confusion about which to use in new features
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 Clear documentation of each representation's purpose
|
||||
- [ ] #2 Reduced confusion about which to use in new features
|
||||
<!-- AC:END -->
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: ML-19
|
||||
title: Circular dependency between Records and Collection/Wishlist
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:50'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/160'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-09 · closed 2026-04-06 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
`Collection` and `Wishlist` call `Records.search_records(base_search(), ...)`, creating a circular dependency where Records is called by modules that exist primarily as query filters on Records.
|
||||
|
||||
## Why This Matters
|
||||
|
||||
- The only difference between Collection and Wishlist is the base query filter (`purchased_at IS NOT NULL` vs `IS NULL`)
|
||||
- These aren't independent contexts — they're query filters on Records
|
||||
- The circular call pattern (Records <- Collection <- Records) makes the dependency graph confusing
|
||||
|
||||
## Affected Files
|
||||
|
||||
- `lib/music_library/collection.ex` (line 22)
|
||||
- `lib/music_library/wishlist.ex` (line 20)
|
||||
- `lib/music_library/records.ex`
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
Make Collection and Wishlist sub-modules of Records (`Records.Collection`, `Records.Wishlist`) or simple functions within Records that accept a filter parameter.
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- No circular dependency between context modules
|
||||
- Collection/Wishlist filtering remains functional
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 No circular dependency between context modules
|
||||
- [ ] #2 Collection/Wishlist filtering remains functional
|
||||
<!-- AC:END -->
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
---
|
||||
id: ML-20
|
||||
title: Missing indexes on JSON extraction queries in ListeningStats
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:50'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/159'
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-12 · closed 2026-04-12 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
`ListeningStats` filters tracks by `artist.musicbrainz_id` and `album.musicbrainz_id` via JSON extraction, and `Artists` searches by `artist ->> '$.name'` with LIKE. These patterns benefit from expression-based indexes that don't currently exist.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `lib/music_library/listening_stats.ex` lines 100-105: filtering by `artist.musicbrainz_id` (JSON extraction)
|
||||
- `lib/music_library/listening_stats.ex` lines 474-478: filtering by `album.musicbrainz_id` and album title
|
||||
- `lib/music_library/artists.ex` lines 92-96: LIKE search on `artist ->> '$.name'`
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
Add expression-based indexes on the most frequently queried JSON paths:
|
||||
|
||||
```sql
|
||||
CREATE INDEX idx_tracks_artist_mbid ON tracks(json_extract(artist, '$.musicbrainz_id'));
|
||||
CREATE INDEX idx_tracks_album_mbid ON tracks(json_extract(album, '$.musicbrainz_id'));
|
||||
```
|
||||
|
||||
Profile queries before and after to confirm impact.
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- Expression-based indexes exist for hot JSON extraction paths
|
||||
- Query plans show index usage for filtered ListeningStats queries
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 Expression-based indexes exist for hot JSON extraction paths
|
||||
- [ ] #2 Query plans show index usage for filtered ListeningStats queries
|
||||
<!-- AC:END -->
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: ML-23
|
||||
title: StatsLive.Index runs 4+ sequential queries in mount
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:51'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/156'
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-09 · closed 2026-04-09 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
`StatsLive.Index` mount calls `get_latest_record()`, `count_records_by_artist()`, `count_records_by_genre()`, `count_records_by_release_year()`, and more as separate sequential queries with no batching or async loading.
|
||||
|
||||
## Why This Matters
|
||||
|
||||
- Each query is a separate database round-trip
|
||||
- Mount blocks until all queries complete, delaying initial page render
|
||||
- Lines 54-91 assign 9+ data structures simultaneously
|
||||
|
||||
## Affected Files
|
||||
|
||||
- `lib/music_library_web/live/stats_live/index.ex` (lines 54-91)
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
Use `start_async` or `assign_async` to load stats data concurrently after mount, showing placeholder/loading states for each section.
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- Stats page initial render is faster
|
||||
- Data loads concurrently where possible
|
||||
- Loading states are shown while data is fetched
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 Stats page initial render is faster
|
||||
- [ ] #2 Data loads concurrently where possible
|
||||
- [ ] #3 Loading states are shown while data is fetched
|
||||
<!-- AC:END -->
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: ML-26
|
||||
title: No retry/backoff strategy for non-Last.fm APIs
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:51'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/153'
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-09 · closed 2026-04-08 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
Only the Last.fm integration has structured error responses with retry classification (`{:snooze, seconds}`). All other API integrations (MusicBrainz, Discogs, Wikipedia, Brave Search, OpenAI) use simple `max_attempts: 3` with no backoff, causing immediate retries that can trigger upstream rate limits.
|
||||
|
||||
## Why This Matters
|
||||
|
||||
- Immediate retries on transient failures can cause thundering herd effects
|
||||
- Rate limit errors are treated identically to other transient errors
|
||||
- No exponential backoff means the same failure is likely to repeat
|
||||
|
||||
## Evidence
|
||||
|
||||
- `lib/last_fm/api/error_response.ex` — comprehensive error classification (70 lines)
|
||||
- All other API modules return raw bodies on error with no classification
|
||||
- `lib/music_library/worker/refresh_scrobbles.ex` (lines 26-32) — only worker with `{:snooze, seconds}`
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
1. Add structured error response modules for MusicBrainz, Discogs, and Wikipedia
|
||||
2. Implement backoff strategies in their respective workers
|
||||
3. Classify rate-limit responses separately from transient errors
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- API-specific workers handle rate-limit responses with appropriate snooze durations
|
||||
- Transient errors use exponential backoff rather than immediate retry
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 API-specific workers handle rate-limit responses with appropriate snooze durations
|
||||
- [ ] #2 Transient errors use exponential backoff rather than immediate retry
|
||||
<!-- AC:END -->
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: ML-27
|
||||
title: 11 copy-pasted Oban workers for refresh operations
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:51'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/152'
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-12 · closed 2026-04-12 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
Single-record refresh workers and their batch counterparts are nearly identical, differing only in the delegated function call. 11 workers share the same ~10-line structure.
|
||||
|
||||
## Affected Workers
|
||||
|
||||
Single-record (6): `ArtistRefreshDiscogsData`, `ArtistRefreshMusicBrainzData`, `ArtistRefreshWikipediaData`, `FetchArtistLastFmData`, `RecordRefreshMusicBrainzData`, `GenerateRecordEmbedding`
|
||||
|
||||
Batch (5): `ArtistRefreshAllDiscogsData`, `ArtistRefreshAllMusicBrainzData`, `ArtistRefreshAllWikipediaData`, `RecordRefreshAllMusicBrainzData`, `RecordGenerateAllEmbeddings`
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
Consider a generic worker pattern or macro that accepts the delegated function as a parameter, reducing boilerplate while keeping each worker as a distinct module for queue routing.
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- Boilerplate is reduced
|
||||
- Each worker remains individually identifiable for Oban queue routing and monitoring
|
||||
- No change in worker behaviour
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 Boilerplate is reduced
|
||||
- [ ] #2 Each worker remains individually identifiable for Oban queue routing and monitoring
|
||||
- [ ] #3 No change in worker behaviour
|
||||
<!-- AC:END -->
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
id: ML-28
|
||||
title: Records context has 8+ responsibilities
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:51'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/151'
|
||||
priority: medium
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-05 · updated 2026-04-11 · closed 2026-04-11 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
The `Records` context module handles search, genre management, cover art operations, color extraction, embeddings, MusicBrainz data refresh, artist metadata refresh, CRUD, and PubSub notifications — too many concerns in one module.
|
||||
|
||||
## Why This Matters
|
||||
|
||||
- Hard to navigate and understand at a glance
|
||||
- Changes to one concern risk affecting others
|
||||
- Testing is harder when responsibilities are interleaved
|
||||
|
||||
## Affected Files
|
||||
|
||||
- `lib/music_library/records.ex`
|
||||
|
||||
## Suggested Fix
|
||||
|
||||
Extract into focused sub-modules:
|
||||
- `Records.Search` — search operations
|
||||
- `Records.Metadata` — MusicBrainz sync, genre population
|
||||
- `Records.Assets` — covers, colors
|
||||
- `Records.Embeddings` — AI embedding generation
|
||||
|
||||
Keep the `Records` module as the public API that delegates to sub-modules.
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- Each sub-module has a single clear responsibility
|
||||
- Public API remains unchanged for callers
|
||||
- No regression in functionality
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
- [ ] #1 Each sub-module has a single clear responsibility
|
||||
- [ ] #2 Public API remains unchanged for callers
|
||||
- [ ] #3 No regression in functionality
|
||||
<!-- AC:END -->
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
---
|
||||
id: ML-3
|
||||
title: Document intentional async-only coupling from Records to Artists
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:44'
|
||||
updated_date: '2026-04-20 08:44'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/181'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-04-16 · updated 2026-04-19 · closed 2026-04-19 · not planned_
|
||||
|
||||
## Summary
|
||||
|
||||
`Records.create_record/1` calls `Artists.refresh_artist_info_async/1` and `Records.delete_record/1` calls `Artists.prune_artist_info_async/1`. Both are deliberately `*_async` (Oban enqueues) to avoid a runtime cycle with the embedding/genre regeneration path in `Artists`. The intent is not captured inline.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `lib/music_library/records.ex:385` — `Artists.refresh_artist_info_async/1` call
|
||||
- `lib/music_library/records.ex:415` — `Artists.prune_artist_info_async/1` call
|
||||
|
||||
No comment explaining why the async form is required. A future refactor that decides to "just inline the synchronous version" would reintroduce runtime coupling.
|
||||
|
||||
## Fix
|
||||
|
||||
Add a short inline comment above each call site explaining:
|
||||
|
||||
```elixir
|
||||
# async to avoid a runtime cycle:
|
||||
# Records.create/delete -> Artists.refresh/prune (sync) -> Records (embedding regeneration)
|
||||
Artists.refresh_artist_info_async(artist)
|
||||
```
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 Inline comments added at records.ex:385 and :415
|
||||
- [ ] #2 Comments explain the runtime-cycle motivation, not just "it's async"
|
||||
<!-- AC:END -->
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: ML-66
|
||||
title: Large modules unchanged since last audit
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:55'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/109'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-03-12 · updated 2026-04-09 · closed 2026-03-16 · not planned_
|
||||
|
||||
## Description
|
||||
|
||||
The four modules flagged in #99 remain at the same size:
|
||||
|
||||
| File | LOC |
|
||||
|------|-----|
|
||||
| `lib/music_library_web/live/artist_live/show.ex` | 804 |
|
||||
| `lib/music_library_web/components/record_components.ex` | 761 |
|
||||
| `lib/music_library_web/components/record_form.ex` | 652 |
|
||||
| `lib/music_brainz/api.ex` | 564 |
|
||||
|
||||
Not urgent — only refactor when new feature work naturally touches these files.
|
||||
|
||||
## Expected behavior
|
||||
|
||||
Monitor and consider extraction when adding new features to these modules.
|
||||
|
||||
## Source
|
||||
|
||||
From technical debt audit (2026-03-12). Continuation of #99.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: ML-68
|
||||
title: Random data in test fixtures
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:55'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/107'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-03-12 · updated 2026-04-09 · closed 2026-03-16 · not planned_
|
||||
|
||||
## Description
|
||||
|
||||
Test fixtures use non-deterministic random values, which can make test failures harder to reproduce:
|
||||
|
||||
- `test/support/fixtures/music_library/records.ex:74` — `Enum.random(@artists)`
|
||||
- `test/support/fixtures/music_library/records.ex:86` — `Enum.take_random(@genres, :rand.uniform(3))`
|
||||
- `test/support/fixtures/music_library/records.ex:91` — `Enum.random(@titles)`
|
||||
- `test/support/fixtures/music_library/records.ex:93` — `Enum.random(Record.formats())`
|
||||
- `test/support/fixtures/music_library/records.ex:95` — `Enum.random(1969..2024)`
|
||||
- `test/support/fixtures/scrobbled_tracks_fixtures.ex:16` — `Enum.random(0..86_400)`
|
||||
|
||||
Previously tracked in #85 (closed) but the randomness remains.
|
||||
|
||||
## Expected behavior
|
||||
|
||||
Use deterministic sequences (e.g., based on `System.unique_integer`) or seeded randomness for reproducible tests.
|
||||
|
||||
## Source
|
||||
|
||||
From technical debt audit (2026-03-12). Residual from #85.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
id: ML-69
|
||||
title: ArgumentError raises in ScrobbleActivity
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:55'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/106'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-03-12 · updated 2026-04-09 · closed 2026-03-14 · not planned_
|
||||
|
||||
## Description
|
||||
|
||||
`lib/music_library/scrobble_activity.ex:19,61,116` raises `ArgumentError` when both `started_at` and `finished_at` are provided to scrobble functions. Per Elixir conventions, public API functions should return `{:error, _}` tuples for input validation rather than raising. These functions are called from LiveComponent event handlers where a crash would kill the LiveView process.
|
||||
|
||||
## Expected behavior
|
||||
|
||||
Return `{:error, :invalid_options}` (or similar) and handle upstream with a user-facing toast message.
|
||||
|
||||
## Source
|
||||
|
||||
From technical debt audit (2026-03-12).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
id: ML-70
|
||||
title: Bare catch blocks in telemetry storage
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:55'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/105'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-03-12 · updated 2026-04-09 · closed 2026-03-16 · not planned_
|
||||
|
||||
## Description
|
||||
|
||||
`lib/music_library_web/telemetry/storage.ex:106-107,123-124` uses bare catch blocks that silently swallow all errors. While reasonable for telemetry resilience (ETS table may not exist during shutdown), they make debugging harder when the table is unexpectedly missing during normal operation.
|
||||
|
||||
## Expected behavior
|
||||
|
||||
Add `Logger.debug` calls inside the catch blocks to aid troubleshooting ETS table issues without affecting production resilience.
|
||||
|
||||
## Source
|
||||
|
||||
From technical debt audit (2026-03-12).
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: ML-76
|
||||
title: Large modules approaching refactoring threshold
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:57'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/99'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-03-05 · updated 2026-03-06 · closed 2026-03-06 · not planned_
|
||||
|
||||
## Priority: Low
|
||||
|
||||
## Description
|
||||
|
||||
Several modules are approaching or exceeding a reasonable size threshold and may benefit from extraction:
|
||||
|
||||
- `lib/music_library_web/live/artist_live/show.ex` — 804 LOC
|
||||
- `lib/music_library_web/components/record_components.ex` — 761 LOC
|
||||
- `lib/music_library_web/components/record_form.ex` — 649 LOC
|
||||
- `lib/music_brainz/api.ex` — 564 LOC
|
||||
|
||||
Previously listed `lib/music_library/scrobble_rules.ex` was reduced from 819 to 543 LOC and no longer qualifies.
|
||||
|
||||
## Expected behavior
|
||||
|
||||
Monitor these modules and consider extraction when adding new features touches them. Not urgent — only refactor when it naturally fits the work being done.
|
||||
|
||||
## Source
|
||||
|
||||
From technical debt audit (2026-03-05), updated 2026-03-06.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: ML-89
|
||||
title: Random data in test fixtures
|
||||
status: To Do
|
||||
assignee: []
|
||||
created_date: '2026-04-20 08:57'
|
||||
labels: []
|
||||
dependencies: []
|
||||
references:
|
||||
- 'https://github.com/cloud8421/music_library/issues/85'
|
||||
priority: low
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
<!-- SECTION:DESCRIPTION:BEGIN -->
|
||||
_GitHub: created 2026-02-17 · updated 2026-03-06 · closed 2026-03-06 · not planned_
|
||||
|
||||
## Priority: Low
|
||||
|
||||
## Description
|
||||
|
||||
`test/support/fixtures/music_library/records.ex` uses `Enum.random/1` (lines 74, 91, 93) and `:rand.uniform/1` (line 86) for generating test data (artist names, titles, formats, genres). This can make test failures harder to reproduce.
|
||||
|
||||
## Expected behavior
|
||||
|
||||
Consider using deterministic sequences or seeded randomness for reproducible tests.
|
||||
|
||||
## Source
|
||||
|
||||
From technical debt audit (2026-02-17), item #12.
|
||||
<!-- SECTION:DESCRIPTION:END -->
|
||||
Reference in New Issue
Block a user