refactor: extract Records sub-contexts (Search, Import, Enrichment)
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.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
---
|
||||
id: ML-150
|
||||
title: Extract Records sub-contexts to reduce module size
|
||||
status: To Do
|
||||
status: Done
|
||||
assignee: []
|
||||
created_date: '2026-04-30 10:47'
|
||||
updated_date: '2026-04-30 16:08'
|
||||
labels:
|
||||
- refactor
|
||||
- records
|
||||
@@ -30,9 +31,56 @@ The `SearchIndex` schema, `Record` schema, `Similarity` module, `TracklistPdf`,
|
||||
|
||||
## Acceptance Criteria
|
||||
<!-- AC:BEGIN -->
|
||||
- [ ] #1 `Records.Search`, `Records.Import`, and `Records.Enrichment` modules exist with focused responsibilities
|
||||
- [ ] #2 Public `Records` module 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 `@moduledoc` for each new module explains its responsibility
|
||||
- [x] #1 `Records.Search`, `Records.Import`, and `Records.Enrichment` modules exist with focused responsibilities
|
||||
- [x] #2 Public `Records` module re-exports all previously-public functions through delegation
|
||||
- [x] #3 All callers (LiveViews, workers, controllers, tests) continue to work without changes to their import/alias lines
|
||||
- [x] #4 Full test suite passes with no regressions
|
||||
- [x] #5 `@moduledoc` for each new module explains its responsibility
|
||||
<!-- AC:END -->
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
<!-- SECTION:NOTES:BEGIN -->
|
||||
## 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_alphabetically` macro from `Records` (one-direction dependency, no cycle)
|
||||
|
||||
**`Records.Import`** (`lib/music_library/records/import.ex`):
|
||||
- `get_release_status/2`, `get_artist_records/1`
|
||||
- `import_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/1` and `Records.Search.essential_fields/0`
|
||||
|
||||
**`Records.Enrichment`** (`lib/music_library/records/enrichment.ex`):
|
||||
- `populate_genres/1`, `populate_genres_async/1`
|
||||
- `refresh_cover/1`, `refresh_cover_async/1`
|
||||
- `extract_colors/1`, `resize_cover/1`
|
||||
- `refresh_musicbrainz_data/1`, `refresh_musicbrainz_data_async/1`
|
||||
- `best_effort_extract_colors/1` (public, called from `Records.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 `defdelegate` calls covering all moved functions (compile-time safety)
|
||||
- `order_alphabetically` macro stays in `Records` for backward compatibility
|
||||
- CRUD (`get_record`, `create_record`, `update_record`, `delete_record`, `change_record`) and PubSub (`subscribe`, `notify_update`) stay directly in `Records`
|
||||
|
||||
### 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)
|
||||
<!-- SECTION:NOTES:END -->
|
||||
|
||||
Reference in New Issue
Block a user