Skip to content

feat(v3 library): genre field in the Fix-metadata popup#780

Merged
byrongamatos merged 1 commit into
mainfrom
feat/v3-genre-in-details
Jul 5, 2026
Merged

feat(v3 library): genre field in the Fix-metadata popup#780
byrongamatos merged 1 commit into
mainfrom
feat/v3-genre-in-details

Conversation

@ChrisBeWithYou

@ChrisBeWithYou ChrisBeWithYou commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Adds Genre as a fifth field in the popup's Details tab (stacked on #779#778#777).

What

  • Genre gets the same treatment as the other fields — edit, lock (pin against auto-match), revert, and Yours/Pack provenance — backed by the existing override store (which already allowed genre).
  • Made it actually useful: the genre filter and facet (/api/library/genres + the genre= filter) now resolve the per-song override — effective genre = your override else the scanned pack genre — so a corrected or added genre is immediately browsable. Guarded on _has_genre_overrides() so the common no-override case stays on the plain indexed column (zero cost).
  • Genre stays a library-only overlay — it is deliberately not a write-to-file field. WRITE_FIELDS (the four file-safe fields) is split from the five DETAIL_FIELDS, so Write to file writes title/artist/album/year and leaves the genre override in place; the copy says "genre stays a library-only tag."
  • The Match→Details bridge (feat(v3 library): Match→Details "use these values" bridge #779) also carries a candidate's first genre into the field.

Why genre isn't written to the pack

POST /api/song/{fn}/meta (the write path) handles the four catalog fields; the feedpak genres list is a separate shape and genre works best as a fast, reversible library-side facet (fix it, browse by it, never touch the file). Locking still protects it from auto-match.

Testing

  • New tests: the effective-genre facet + filter surface/return an overridden song; a value-less genre lock doesn't invent an effective genre. Full test_field_overrides + test_library_filters green (57).
  • Verified live on the testbed: overriding a city-pop pack's genre to "City Pop" makes it appear in the facet and filterable (1 song matched), cleared cleanly.

Stacks on #779#778#777. Merge bottom-up.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Genre overrides now count in library browsing and filtering, so the app shows the effective genre instead of only the stored file value.
    • The metadata review screen now displays Genre in the pending details view.
  • Bug Fixes
    • Writing metadata now preserves genre overrides instead of clearing them.
    • Genre lookups and filters now stay consistent when a song has an overridden genre value.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f6e354b6-e9e0-4c02-b7a7-6a6cd84ceb32

📥 Commits

Reviewing files that changed from the base of the PR and between 6397a95 and 007c435.

📒 Files selected for processing (3)
  • server.py
  • static/v3/match-review.js
  • tests/test_field_overrides.py

📝 Walkthrough

Walkthrough

This PR makes genre queries use override-aware effective values on the server, shows candidate genre in the match-review Details view, keeps genre out of file writes, and adds API tests for facet/filter behavior.

Changes

Genre override support

Layer / File(s) Summary
Effective genre SQL expression and query wiring
server.py
Adds an override-aware SQL expression preferring per-song genre overrides when present, and uses it for genre filtering and the /api/library/genres facet query.
Match-review Details genre display and write-to-file exclusion
static/v3/match-review.js
Adds genre to the Details field list, pre-fills it from candidate genres, updates helper text, and limits write-to-file plus post-write cleanup to non-genre fields.
API tests for genre override facet and filter behavior
tests/test_field_overrides.py
Adds tests verifying override-driven genre facets and filtering, and that lock-only genre overrides do not change the effective genre expression.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant API as /api/library/genres
  participant MetadataDB
  participant DB as SQLite

  Client->>API: GET /api/library/genres
  API->>MetadataDB: resolve effective genre expression
  MetadataDB->>DB: query distinct effective genres
  DB-->>MetadataDB: genre values
  MetadataDB-->>API: facet list
  API-->>Client: genres list
Loading

Related issues: None found.

Related PRs: None found.

Suggested labels: backend, frontend, tests

Suggested reviewers: None specified.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/v3-genre-in-details
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/v3-genre-in-details

Comment @coderabbitai help to get the list of available commands.

@ChrisBeWithYou

Copy link
Copy Markdown
Contributor Author

📋 Merge order — metadata-curation epic (7 PRs)

  1. feat(v3 library): "Fix metadata" popup — per-song override + lock, cover picker, MusicBrainz + AcoustID #777 — Fix-metadata popup
  2. feat(v3 library): "Write to file" in the Fix-metadata popup #778 — Write to file
  3. feat(v3 library): Match→Details "use these values" bridge #779 — Match→Details bridge
  4. feat(v3 library): genre field in the Fix-metadata popup #780 — Genre in Details
  5. feat(v3 library): persistent "no match" badge + Unmatched quick filter #781 — No-match badge + Unmatched filter (independent of 1–4 — fine to merge any time)
  6. feat(v3 library): batch→popup handoff + English-base romaji (metadata-curation capstone) #782 — Batch→popup handoff + romaji (capstone)
  7. feat(v3 library): searchable Cover Art Archive picker in Change-cover #783 — Searchable cover picker

#778#780 are stacked (each based on the branch above), so GitHub re-points each to main automatically as the previous one merges — just merge #777#778#779#780 top-down. #781 is independent (base: main).

⚠️ Hold #782 and #783 until #777#781 are all in main. #782's branch is a combined branch that already contains #777#781, so merging it early would double-merge the stack. Once #777#781 land, the author will rebase #782 (then #783) onto main — they shrink to just their own commits — and they're then ready to merge.

Adds Genre as a fifth Details field (edit / lock / revert / Yours-Pack
provenance), backed by the existing override store. To make it actually useful,
the genre FILTER and FACET now resolve the per-song override (effective genre =
override else scanned pack genre) — guarded so the common no-override case stays
on the plain indexed column — so a corrected/added genre is immediately
browsable. Genre stays a library-only overlay: it is NOT a write-to-file field
(split WRITE_FIELDS = the four file-safe fields from the five DETAIL_FIELDS), so
Write to file leaves the genre override in place and the copy says so. The
Match→Details bridge also carries a candidate's first genre.

Tests: effective-genre facet + filter, and that a value-less lock doesn't invent
an effective genre.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@byrongamatos
byrongamatos changed the base branch from feat/v3-match-details-bridge to main July 5, 2026 19:12
@byrongamatos
byrongamatos force-pushed the feat/v3-genre-in-details branch from bee4f12 to 007c435 Compare July 5, 2026 19:12
@byrongamatos
byrongamatos merged commit 3100d68 into main Jul 5, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants