Split the 450+ line Records context into focused modules: - Records.Search — FTS5 search, SearchParser integration, genre listing - Records.Import — MusicBrainz release/group import, release status - Records.Enrichment — genre population, cover refresh, color extraction, MusicBrainz data refresh - Records.Query — shared helpers (essential_fields, order_alphabetically macro) Records module is now a facade with defdelegate for compile-time safety. CRUD and PubSub stay directly in Records. Tests moved alongside each sub-module. Zero callers changed, 886 tests pass.
3.9 KiB
id, title, status, assignee, created_date, updated_date, labels, dependencies, references, priority
| id | title | status | assignee | created_date | updated_date | labels | dependencies | references | priority | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ML-150 | Extract Records sub-contexts to reduce module size | Done | 2026-04-30 10:47 | 2026-04-30 16:08 |
|
|
medium |
Description
The Records context module (450+ lines in lib/music_library/records.ex) handles CRUD, FTS5 search, MusicBrainz import, cover management, genre population, color extraction, PubSub notifications, and similarity embedding dispatch — too many responsibilities for a single module.
Extract focused sub-contexts:
Records.Search— FTS5 search,SearchParserintegration, search result formattingRecords.Import— MusicBrainz release/group import, barcode scan integrationRecords.Enrichment— genre population, color extraction, cover management, embedding dispatch
Keep the public Records module as a facade that re-exports key functions for backward compatibility with all existing callers (LiveViews, workers, controllers).
The SearchIndex schema, Record schema, Similarity module, TracklistPdf, and Batch sub-modules stay as-is. Only records.ex itself is being split.
Acceptance Criteria
- #1
Records.Search,Records.Import, andRecords.Enrichmentmodules exist with focused responsibilities - #2 Public
Recordsmodule re-exports all previously-public functions through delegation - #3 All callers (LiveViews, workers, controllers, tests) continue to work without changes to their import/alias lines
- #4 Full test suite passes with no regressions
- #5
@moduledocfor each new module explains its responsibility
Implementation Notes
Implementation Summary
New modules created
Records.Search (lib/music_library/records/search.ex):
essential_fields/0,search_records/3,search_records_count/2,list_genres/0- Private:
build_search/3,fts_escape/1,fts_query_escape/1 - Imports
order_alphabeticallymacro fromRecords(one-direction dependency, no cycle)
Records.Import (lib/music_library/records/import.ex):
get_release_status/2,get_artist_records/1import_from_musicbrainz_release/2,import_from_musicbrainz_release_group/2- Private:
get_cover_art_or_default/1,build_record_attrs/2 - Calls
Records.create_record/1andRecords.Search.essential_fields/0
Records.Enrichment (lib/music_library/records/enrichment.ex):
populate_genres/1,populate_genres_async/1refresh_cover/1,refresh_cover_async/1extract_colors/1,resize_cover/1refresh_musicbrainz_data/1,refresh_musicbrainz_data_async/1best_effort_extract_colors/1(public, called fromRecords.create_record/1)- Private:
maybe_extract_colors/1,enqueue_worker/3,record_meta/1 - Calls
Records.update_record/2
Facade (lib/music_library/records.ex)
- 15
defdelegatecalls covering all moved functions (compile-time safety) order_alphabeticallymacro stays inRecordsfor backward compatibility- CRUD (
get_record,create_record,update_record,delete_record,change_record) and PubSub (subscribe,notify_update) stay directly inRecords
Dependency graph (one direction only):
Records.Search → imports macro from Records
Records.Import → calls Records, Records.Search
Records.Enrichment → calls Records
Records → delegates to Search, Import, Enrichment (compile-time: defdelegate only, no runtime cycle)
Tests
test/music_library/records_test.exs— CRUD tests (6 tests)test/music_library/records/search_test.exs— search tests (13 tests)test/music_library/records/import_test.exs— import tests (3 tests)test/music_library/records/enrichment_test.exs— enrichment tests (3 tests)