docs: move Phase 8 §8.1-§8.5 from PLAN to COMPLETED (landed 2026-06-12)
This commit is contained in:
@@ -18,6 +18,56 @@ Newest entries at the top. Group by phase/wave header (mirroring `PLAN.md` / `CM
|
||||
|
||||
**Completion note:** `ReleaseEntity` table and EF configuration implemented in `DeepDrftData`. Two EF migrations landed (`NormalizeReleaseTrack` and `AddReleaseUniqueTitleArtist`) with full data migration backfill. `ReleaseDto` and slimmed `TrackDto` (with nested `Release` property) implemented in `DeepDrftModels`. Repository updated with JOIN-projecting queries. API controllers updated to return nested DTOs. Public-client consumers (`TrackCard`, `TrackDetail`, `NowPlayingCard`) and CMS surfaces (`TrackEdit`, `TrackNew`, `BatchUpload`, `TrackList`) all updated to point to `track.Release.*` fields. All five waves complete and merged to dev. Build clean, 155 tests pass. §8.1–§8.5 now unblocked.
|
||||
|
||||
### 8.1 URL scheme + mode toggle
|
||||
|
||||
**Landed:** 2026-06-11 on dev.
|
||||
|
||||
- **What:** `/tracks` (Track mode, default), `/tracks/albums`, `/tracks/genres` as route segments; a toggle inside the existing "Tracks" tab switches mode and pushes the matching URL. The Waveform Pre-Processing tab is untouched.
|
||||
- **Why:** The public home page hard-codes these as cross-host deep-links; a route segment reads as a stable address and matches the app's existing segment-based routing (`/tracks/upload`, `/tracks/{id}`). Query-param mode (`?mode=`) was the alternative — rejected as transient-looking view state, optionally tolerated as an alias.
|
||||
- **Shape:** One `TrackList` component carrying three `@page` directives (or three thin wrappers passing an `InitialMode`); the toggle drives `Mode` + `NavigationManager.NavigateTo`. See notes §3, §9.
|
||||
|
||||
**Completion note:** `TrackList.razor` refactored to support three route modes via `@page` directives (Track/Album/Genre). Mode-toggle control added to the UI, wired to `NavigationManager.NavigateTo` to push the matching URL. Toggle persists selection across navigation.
|
||||
|
||||
### 8.2 `CmsTrackGrid` — the reusable flat track table (DRY core)
|
||||
|
||||
**Landed:** 2026-06-11 on dev.
|
||||
|
||||
- **What:** Extract today's `MudTable<TrackDto>` into a standalone `CmsTrackGrid.razor` taking `AlbumFilter`/`GenreFilter` params. Apply the new column layout: Track # → 40×40 art thumb → Track Name → Artist → Album → Genre → Release Date (`d MMMM, yyyy`) → **Waveform Status** → Actions. Entry Key + File Name move out of the grid into an Info-icon tooltip (monospace). Art thumb reuses the public `TrackCard` fallback pattern, defined locally CMS-side.
|
||||
- **Why:** Single source of truth for the track-table layout — consumed by both Track mode (no filter) and Genre mode (genre filter), so no duplicated table markup. Decluttering Entry Key / File Name into a tooltip keeps the grid scannable while the data stays reachable. The Waveform column replaces the removed Waveform Pre-Processing tab (status visible inline; per-row Generate when no profile; page-level "Generate All Missing" in the Track-mode header).
|
||||
- **Shape:** Owns its own `MudTable` + `LoadServerData` + delete-confirm (lifted from `TrackList`). `GetPagedAsync` gains optional `album`/`genre` filter params — the one filter data-contract change (the endpoint already supports the filters); post-§0 the filter joins through `releases`. Waveform status comes from a new `HasWaveformProfile` bool on `TrackDto` (recommended over a second per-page lookup; fold into the §8.0 DTO pass). Display date format is presentation-only; sort key stays the raw `DateOnly`. See notes §8, §9, §11.
|
||||
|
||||
**Completion note:** New `CmsTrackGrid.razor` component implemented with full table layout (Track #, art thumb, name, artist, album, genre, release date, waveform status, actions). `ICmsTrackService.GetPagedAsync` extended with optional `album` and `genre` filter parameters. `HasWaveformProfile` bool added to `TrackDto`. Waveform status column displays profile state; per-row and page-level Generate actions wired. Info tooltip displays Entry Key and File Name. Grid consumed by Track mode (no filter) and Genre mode (genre filter); single source of truth for table markup.
|
||||
|
||||
### 8.3 Album mode
|
||||
|
||||
**Landed:** 2026-06-11 on dev.
|
||||
|
||||
- **What:** `CmsAlbumBrowser` — parent release rows (art, title, artist, track count, genre, release date, release-type chip, Edit + Delete) that expand to child track rows (track # + name only). Edit → Batch Edit page (§8.5); Delete → album-scoped delete of every track.
|
||||
- **Why:** A scannable release catalogue is the CMS analogue of the public `AlbumsView`, and the natural place to manage a release as a unit.
|
||||
- **Shape:** Post-§0, parent rows are `ReleaseEntity`/`ReleaseDto` rows — `GetReleasesAsync` (eager, once) supplies title/artist/genre/date/type directly, no derivation. Child tracks lazy via `GetPagedAsync(album:)` (joins through `releases`) on first expand, cached per row — no new endpoint. Expandable `MudTable` over `MudTreeView` (parent rows are multi-column, not tree-shaped). **The old `AlbumSummaryDto` widening question is dissolved by §8.0 normalization** — the Release table has all the fields, so the parent row is fully populated at rest with no DTO widening and no lazy derivation. See notes §6, §10, §0.5.
|
||||
|
||||
**Completion note:** New `CmsAlbumBrowser.razor` component implemented as an expandable release-row browser. Parent rows display `ReleaseDto` data (art, title, artist, track count, genre, release date, release-type chip). Child tracks loaded lazily on expand via `GetPagedAsync(album:)`, cached per row. Edit action navigates to Batch Edit page; Delete action removes album and all its tracks with confirmation. Leverages normalized `ReleaseEntity` from §8.0 — Release rows are fully populated at rest, no lazy derivation required.
|
||||
|
||||
### 8.4 Genre mode
|
||||
|
||||
**Landed:** 2026-06-11 on dev.
|
||||
|
||||
- **What:** `CmsGenreBrowser` — a responsive `MudCard` grid (one card per genre: name + track count); clicking a card expands it (accordion, one open at a time) to reveal a `CmsTrackGrid` filtered to that genre.
|
||||
- **Why:** CMS analogue of the public `GenresView`; the card-to-grid expand is the cheapest second mode because the grid is already built (§8.2).
|
||||
- **Shape:** `GetGenreSummariesAsync` once; the expanded panel renders `CmsTrackGrid` with `GenreFilter` set and the Add button suppressed — zero duplicated table markup. The embedded grid gets the waveform status column + per-row generate for free. See notes §7, §9.
|
||||
|
||||
**Completion note:** New `CmsGenreBrowser.razor` component implemented as a responsive card-grid accordion. Each card displays genre name and track count. Clicking a card expands it to reveal `CmsTrackGrid` filtered to that genre (Add button suppressed). One card open at a time. Grid embedded within each expanded panel inherits waveform status column and per-row generate actions. Zero duplicated table markup — consumes the single `CmsTrackGrid` source built in §8.2.
|
||||
|
||||
### 8.5 Batch Edit page
|
||||
|
||||
**Landed:** 2026-06-11 on dev.
|
||||
|
||||
- **What:** New page `/tracks/album/{albumName}/edit`, reached from an Album-mode row's Edit action. `BatchUpload`'s master-detail mechanics with the release's data preloaded; submit swaps per-row `UploadTrackAsync` for `UpdateAsync` on existing tracks (new tracks still upload). Distinct from the existing single-track edit at `/tracks/{id}`.
|
||||
- **Why:** Editing a release as a unit (rename tracks, reorder, swap cover, add tracks) without round-tripping the single-track editor per track.
|
||||
- **Shape:** **Confirmed:** a *new* `BatchEdit.razor` sharing extracted sub-components with `BatchUpload` — album-header fields block (post-§0 edits the `ReleaseDto`), batch track list (move-up/down/remove + status chips), track detail pane — over growing `BatchUpload` with an `isEdit` flag (the flag breeds conditional soup across preload/detail/submit). Cover art uses the established upload-once-then-link-via-`UpdateAsync` two-step. **Open:** does remove-in-edit delete an existing track (with confirm) or just detach? See notes §10, §12(8).
|
||||
|
||||
**Completion note:** New `BatchEdit.razor` page implemented at `/tracks/album/{releaseName}/edit`. Shares extracted sub-components with `BatchUpload`: `AlbumHeaderFields`, `BatchTrackList`, `BatchTrackDetail`, `BatchRowModel`. Two-panel layout with release-header block (album name, artist, genre, release date, cover art, release type) and left queue + right detail sections. Submit path swaps per-row `UploadTrackAsync` for `UpdateAsync` on existing tracks; new tracks still upload. Cover art uploaded once, linked via `UpdateAsync`. Remove-in-edit deletes existing track with confirmation. Reusable sub-components extracted for consistency across `BatchUpload` and `BatchEdit`.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1.2 — Audio format diversity
|
||||
|
||||
Reference in New Issue
Block a user