cloud-browser-bugs.md 3.9 KB

Cloud Browser Bugs — Category Navigation & Year Parsing

Problem

Cloud library browsing is half-built. Users can see the list of artists, genres, years, etc., but tapping any item does nothingCategoryDetailView renders plain HStack rows instead of NavigationLinks. This makes 5 of the 8 browsing categories (artist, genre, year, publisher, country) decoration-only. Albums is the only category that actually works end-to-end.

Separately, the bug notes mention years displaying as 2.012 / 1.972 (float format from Chad Music). Investigation shows ChadAlbum.year is declared as Int? and decodes correctly in the model. However, the category endpoint (/api/cat/year) returns ChadCategory items where the item field is a string — it may contain the float representation there. Needs verification at the API level, but the fix location is clear regardless.

Goal

Tapping an artist/genre/year/publisher/country in CategoryDetailView navigates to a filtered album list showing all albums matching that category value.

Non-goals

  • No new Chad Music API endpoints — use client-side filtering of the full album list
  • No new models or SwiftData changes
  • No changes to macOS MixBoard in this brief (parity later)

Acceptance Criteria

  • Tapping an artist in CategoryDetailView shows all albums by that artist
  • Tapping a genre shows all albums in that genre
  • Tapping a year shows all albums from that year
  • Tapping a publisher/country/type/status shows filtered albums (same pattern)
  • Each filtered album list allows drilling into AlbumDetailView (existing)
  • Year category items display as clean integers (e.g., "2012" not "2.012")
  • Back navigation works correctly (no broken nav stack)
  • Empty states handled (category value with 0 albums after filtering)

Appetite

  • 2 files changed max: CloudBrowserView.swift (CategoryDetailView) + possibly ChadMusicAPIClient.swift (if a filtered fetch helper is needed)
  • Existing patterns only — copy the AlbumListView pattern
  • No new dependencies
  • Small scope — should be < 100 lines of new code

Technical Constraints

  • iOS 17+ / SwiftUI — use NavigationLink with value-based navigation or inline destination
  • ChadMusicAPIClient.fetchAlbums() returns all albums — filter client-side by matching album.artist, album.genre, album.year, etc. against the selected category item
  • ChadCategoryType has a rawValue that matches the ChadAlbum property name (artist, genre, year, etc.) — use this for generic filtering via KeyPath or switch
  • Year comparison: parse ChadCategory.item (String) to Int, compare with ChadAlbum.year (Int?)
  • Reuse existing AlbumDetailView for the final drill-down — don't duplicate album display logic

Implementation Hint (for Builder)

The simplest approach:

  1. In CategoryDetailView, wrap each list item in a NavigationLink that pushes a new FilteredAlbumListView(category:, value:)
  2. FilteredAlbumListView fetches all albums via fetchAlbums(), then filters by the category field matching the selected value
  3. For year items, strip dots/parse to int when comparing
  4. Each filtered album row is a NavigationLink to existing AlbumDetailView

Dependencies & Blockers

None — all building blocks exist.

Risks

  • If the album list is very large (10k+), client-side filtering could be slow on first load. Acceptable for v1 — cache or API filter is v2.
  • Year float format: if the API returns "2.012" as the category item string, the builder must handle parsing (remove dot, parse as integer). If it returns "2012", it's just a string-to-int conversion. Builder should test with real API data.

Not Now (Deferred)

  • macOS MixBoard parity (same bug exists there)
  • Server-side filtered album endpoint
  • Search within filtered results
  • Album count badges on category items (already shown via item.count)