b855009ea0
Foundation slice of Playlists feature parity with Flutter v2026.05.21.0.
Replaces the ComingSoon stub on the Playlists route with a real
two-section list screen (System playlists / Your playlists), cache-first
against `cached_playlists`.
New:
- models/Playlist.kt — PlaylistRef + PlaylistTrackRef domain models.
Mirrors `flutter_client/lib/models/playlist.dart` (id + name +
isSystem + cover + ownerUsername etc.; PlaylistTrack carries the
full per-row display fields since cached_playlist_tracks only holds
ordered (playlistId, trackId, position) triples).
- models/wire/PlaylistWire.kt — @Serializable wire types
(PlaylistWire / PlaylistsListWire / PlaylistTrackWire /
PlaylistDetailWire), matching `internal/api/playlists.go`.
- api/endpoints/PlaylistsApi.kt — Retrofit interface (list + get).
Read-only for now; create/append/refreshSystem land with the
mutation-queue phase.
- playlists/data/PlaylistsRepository.kt — observe (all / user /
system) cache-first reads + refreshList / refreshDetail that
upsert Room and return a hydrated PlaylistDetailRef. Internal
entity↔wire↔domain mappers kept private.
- playlists/widgets/PlaylistCard.kt — 176dp tile sized to match
AlbumCard for visual consistency in the upcoming Home carousel.
Subtitle shows the system-variant label ("For You" / "Discover" /
"Songs like…" / etc.) or "N tracks" for user playlists.
- playlists/ui/PlaylistsListScreen.kt — Scaffold + TopAppBar +
MainAppBarActions; LazyVerticalGrid with adaptive 176dp cells.
Renders both `System playlists` and `Your playlists` sections via
full-width section headers (`GridItemSpan(maxLineSpan)`).
Modified:
- cache/db/DatabaseModule.kt — adds @Provides for CachedPlaylistDao
+ CachedPlaylistTrackDao (DAOs existed on AppDatabase since slice 1
but had no consumer until now).
- nav/MinstrelNavGraph.kt — swaps the ComingSoon stub for
`PlaylistsListScreen(navController = navController)`.
PlaylistDetail route still ComingSoon; lands in the next commit along
with Home-page Playlists row integration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>