docs: resolve Wave 8 open questions, add 8.L name consolidation, finalize 8.K visualizer design
This commit is contained in:
@@ -1,13 +1,20 @@
|
||||
# Phase 9 — Wave 8: Remediation
|
||||
|
||||
Status: spec (CMS + public tracks) / **design-pending-interview** (Mix Visualizer, 8.K).
|
||||
Status: **spec** (CMS + public tracks — open questions resolved 2026-06-13).
|
||||
Author: product-designer. Date: 2026-06-13.
|
||||
**Plan only — no code edits made by this doc.**
|
||||
|
||||
Cross-references: `PLAN.md §9.8` (the concise Wave 8 entry), `COMPLETED.md §9.1–9.7`
|
||||
(the landed Phase 9 waves this remediates), `product-notes/phase-9-release-medium-types.md`
|
||||
(the originating design — §3 CMS surface, §5 public surface), `product-notes/phase-9-mix-visualizer-redesign.md`
|
||||
(the 8.K interview question set), memory *One source, multiple views*.
|
||||
(the 8.K finished design doc — **now a complete spec, pulled out of Phase-9-completion scope**),
|
||||
memory *One source, multiple views*.
|
||||
|
||||
**Open questions are resolved (2026-06-13).** Daniel answered the whole decision list in §6 and ran
|
||||
the 8.K interview. This doc no longer carries forks: 8.H is decided (H2 — a release-cardinal
|
||||
all-releases browser at `/archive`), 8.I/8.F/8.E defaults are baked into their acceptance criteria, a
|
||||
new consolidation track **8.L** is added, and **8.K is moved out of Phase-9-completion scope** to a
|
||||
finished post-Phase-9 design doc. Phase 9 can close without 8.K.
|
||||
|
||||
---
|
||||
|
||||
@@ -17,21 +24,23 @@ Daniel tested the landed Phase 9 surface (Waves 1–7, all on `dev`) and produce
|
||||
wave is the gap between what the specs *built* and what hands-on use *wants*. It is **remediation, not
|
||||
new feature work** — every item corrects or reshapes a surface that already exists.
|
||||
|
||||
Three clusters:
|
||||
Clusters:
|
||||
|
||||
1. **CMS Release Archive (8.A–8.E)** — the card-grid landing is the wrong shape. Daniel wants the
|
||||
medium varieties as **tab modes** that swap the grid in place, with an `ALL` tab on the left, and
|
||||
working edit + add affordances in every mode. The current `ReleaseArchiveBrowser` (three cards that
|
||||
navigate to separate `/tracks/sessions`, `/tracks/mixes` pages) is retired.
|
||||
2. **CMS upload/label polish (8.F–8.G)** — compose the Session hero image into the upload form (retire
|
||||
the two-step), and rename "Album Name" → "Release Name."
|
||||
2. **CMS upload/label polish (8.F–8.G, 8.L)** — compose the Session hero image into the upload form
|
||||
(retire the two-step), rename "Album Name" → "Release Name," and **consolidate the
|
||||
release-name/track-name pair into a single name for single-track media (Session/Mix)** so the admin
|
||||
enters one name, not two.
|
||||
3. **Public site (8.H–8.J)** — the three-card `/archive` overview is dead weight; the searchable
|
||||
all-releases view should *be* the archive. Slim the nav, drop GENRES, fix the stuck-open popover.
|
||||
all-**releases** view (release-cardinal — decided H2) *is* the archive. Slim the nav, drop GENRES
|
||||
(nav-only), fix the stuck-open popover.
|
||||
|
||||
**Not in this wave:** the **Mix Visualizer redesign (8.K)**. Daniel has explicitly asked to be
|
||||
interviewed before it is designed. It is carried as `[design pending interview]` with a structured
|
||||
question set in `phase-9-mix-visualizer-redesign.md`. No implementation spec exists or should be
|
||||
authored until the interview runs.
|
||||
**Out of Phase-9-completion scope (but documented in full):** the **Mix Visualizer redesign (8.K)**.
|
||||
The interview has run; `phase-9-mix-visualizer-redesign.md` is now a complete, implementation-ready
|
||||
design spec. Phase 9 closes without it; it runs as a post-Phase-9 wave.
|
||||
|
||||
---
|
||||
|
||||
@@ -226,16 +235,18 @@ not a per-medium route fork.
|
||||
**Acceptance criteria.**
|
||||
- Add Track is present on every tab (`ALL`, Cut, Session, Mix).
|
||||
- Add Track on a medium tab opens the upload form with that medium pre-selected.
|
||||
- **The `ALL` tab's Add Track defaults to Cut** (Daniel, 2026-06-13) — the existing default and most
|
||||
common case.
|
||||
- **The medium selector remains user-changeable after landing on the upload form** (Daniel,
|
||||
2026-06-13). The pre-selected medium is a *starting point*, not a lock: pre-selecting Session from
|
||||
the Session tab opens the form in Session mode, but the admin can still switch the selector to Cut/Mix
|
||||
on the form without going back. The pre-selection seeds; it does not constrain.
|
||||
- The pre-selected medium drives the conditional form fields immediately (Session shows the hero field
|
||||
per 8.F; Cut shows `ReleaseType`; etc.).
|
||||
per 8.F; Cut shows `ReleaseType`; etc.), and switching the selector re-drives them live.
|
||||
|
||||
**Dependencies.** Depends on **8.A** (tabs exist to host the buttons). Pairs with **8.F** (a Session
|
||||
Add-Track that pre-selects Session should land the admin on a form that *has* the hero field).
|
||||
|
||||
**Open question (minor, recommend a default).** What medium does the `ALL` tab's Add Track default to?
|
||||
*Recommend Cut* (the existing default and the most common case); the admin can switch the selector. Not
|
||||
worth blocking.
|
||||
|
||||
---
|
||||
|
||||
### 8.F — Session hero image in the upload form (retire the two-step)
|
||||
@@ -262,25 +273,30 @@ or in the `MediumFields` dispatch — staff-engineer's call — but the *user* s
|
||||
|
||||
`SessionFields.razor`'s current body (a `MudAlert` only) is replaced by a real hero-image input.
|
||||
|
||||
**Hero image — optional, but warn if missing (Daniel, 2026-06-13).** The hero image is **not** a hard
|
||||
validation gate: a Session can be submitted without one and the upload succeeds. **But** the form
|
||||
**surfaces a warning when a Session is submitted (or about to be submitted) without a hero image** — a
|
||||
soft nudge, not a block. Rationale: a Session's hero is its primary visual identity on the public detail
|
||||
page (it is the precedence-first image — see `SessionDetail.razor`), so a missing hero is *usually* an
|
||||
oversight worth flagging, but Daniel wants the seed-then-correct path (set later via the browser) to
|
||||
remain valid. So: warn, don't gate.
|
||||
|
||||
**Acceptance criteria.**
|
||||
- The Session upload form presents a hero-image input (in addition to cover art).
|
||||
- Submitting a Session with a chosen hero image creates the release and sets `HeroImageEntryKey` in one
|
||||
flow — no separate manual step required.
|
||||
- The "set hero from the browser later" alert is removed.
|
||||
- **Submitting a Session with no hero image surfaces a warning** (e.g. an inline `MudAlert` of
|
||||
`Severity.Warning`, or a confirm-dialog "Submit without a hero image?") — the submit still proceeds;
|
||||
the warning informs, it does not block. No hard `Required` validation on the hero field.
|
||||
- The per-row hero upload in `CmsSessionBrowser` still works as a replace/correct path.
|
||||
- A Session uploaded with no hero image still succeeds (hero optional), and can have one set later via
|
||||
the browser (back-compat with the existing per-row path).
|
||||
- A Session uploaded with no hero image still succeeds and can have one set later via the browser
|
||||
(back-compat with the existing per-row path).
|
||||
|
||||
**Dependencies.** Independent of the tab restructure (8.A–8.E). Touches the upload form and the submit
|
||||
sequencing. Pairs naturally with **8.E** (Session Add-Track should land on this improved form). Can be
|
||||
built in parallel with the tab work.
|
||||
|
||||
**Open question (flag, recommend).** Is the hero image **required** for a Session, or optional? Daniel's
|
||||
note says "the form should allow uploading all metadata including the hero image" — *allow*, not
|
||||
*require*. **Recommend optional** (consistent with cover art being optional, and with the existing
|
||||
per-row set-later path remaining valid). Confirm with Daniel; if required, the form gains a validation
|
||||
gate.
|
||||
|
||||
---
|
||||
|
||||
### 8.G — "Album Name" → "Release Name" label
|
||||
@@ -303,6 +319,104 @@ should follow for consistency — e.g. placeholder/help text — but the named c
|
||||
|
||||
---
|
||||
|
||||
### 8.L — Consolidate release name + track name for single-track releases
|
||||
|
||||
**Goal.** For single-track media (**Session** and **Mix** — the §9.6/§9.7 one-track-per-medium
|
||||
releases), the UI presents and stores **a single name**. The admin enters/sees one **"Release Name"**;
|
||||
the track name is **derived from it automatically** — never entered or shown as a separate field. This
|
||||
is a **consolidation**, not an addition: today these forms surface *two* name inputs (Release Name +
|
||||
Track Name) for media that conceptually have only one name.
|
||||
|
||||
**Why.** A Session or Mix is a single work. There is exactly one thing to name. Surfacing a separate
|
||||
"Track Name" alongside "Release Name" for these media is a redundant input that invites divergence
|
||||
(the release titled "Lowcountry Live #3" whose lone track is named "untitled-master-final") and a
|
||||
confusing authoring experience. Cuts are different — a Cut release legitimately has a release name
|
||||
distinct from its per-track names ("Charleston EP" → tracks "Battery", "Rainbow Row") — and are
|
||||
**unaffected** by this track.
|
||||
|
||||
**Recommendation — keep them synced for single-track media (Daniel to confirm posture; this is the
|
||||
recommended default).** On both create and edit of a single-track release, the underlying track name is
|
||||
**set equal to the Release Name on save, and kept in sync** so they can never diverge. The admin never
|
||||
sees or touches the track name for Session/Mix. On edit, changing the Release Name updates the track
|
||||
name with it. This is the simplest model and the one that honors "there is only one name": the track
|
||||
name is a *derived field*, not an independent one. (The alternative — let them diverge once set — would
|
||||
reintroduce exactly the two-name confusion this track removes. Rejected.)
|
||||
|
||||
**Discovery audit — every UI surface that surfaces separate Release vs. Track name (read against live
|
||||
source, 2026-06-13).** This is the full blast radius. Implementation must collapse the name inputs on
|
||||
the single-track path for each:
|
||||
|
||||
*CMS — the surfaces that show BOTH names today (these are the ones to fix):*
|
||||
- **`BatchUpload.razor` (`/tracks/upload`) — the single-track branch.** When `_medium != Cut`, the form
|
||||
renders `AlbumHeaderFields` (which carries the Release/Album name — renamed "Release Name" in 8.G)
|
||||
**plus** a separate `<MudTextField Label="Track Name">` bound to `_tracks[0].TrackName` (lines ~62-65).
|
||||
This is the primary offender on the create path. For Session/Mix this Track Name input must be
|
||||
**removed**, and `_tracks[0].TrackName` set equal to the Release Name on submit.
|
||||
- **`BatchEdit.razor` (`/tracks/album/{AlbumName}/edit`) — the single-track path.** Renders
|
||||
`AlbumHeaderFields` (Release Name) **plus** `BatchTrackList` + `BatchTrackDetail`. For single-track
|
||||
media the list is already collapsed to one row (`OnMediumChanged` / load-path trim), but
|
||||
`BatchTrackDetail` still shows a separate `<MudTextField Label="Track Name">` (its lines ~8-15) for
|
||||
that one row. On the single-track path this Track Name editor must be **suppressed**, and the row's
|
||||
`TrackName` kept equal to `_albumName` on save.
|
||||
- **`BatchTrackDetail.razor`** — the component that renders the "Track Name" field (lines ~8-15). It is
|
||||
shared by the Cut path (where it stays) and the single-track path (where it must be hidden). Cleanest:
|
||||
the parent passes a flag (e.g. `ShowTrackName` / `IsSingleTrack`) so `BatchTrackDetail` suppresses the
|
||||
name field for single-track media while still showing the WAV/Original-File rows.
|
||||
- **`TrackNew.razor` (`/tracks/new`) — the legacy single-track add form.** Shows `Track Name` (line 31),
|
||||
`Album` (line 33), and a `MediumFields` selector. When the selected medium is single-track, the
|
||||
separate Track Name vs. Album split is the same redundancy. This legacy form is a secondary surface
|
||||
(the batch form is the primary upload path) — confirm whether it is still a live entry point before
|
||||
investing; if it is, apply the same collapse (one name when medium is Session/Mix). If it is dead,
|
||||
note it for retirement rather than re-plumbing.
|
||||
- **`TrackEdit.razor` (`/tracks/{Id:long}`) — the legacy single-track edit form.** Shows `Track Name`
|
||||
(line 46) and `Album` (line 58) as separate fields, with a `MediumFields` selector. Same disposition
|
||||
as `TrackNew`: collapse on the single-track path if live, flag for retirement if not.
|
||||
|
||||
*CMS — surfaces that already do the right thing (no change needed, listed so implementation knows they
|
||||
are clean):*
|
||||
- **`CmsMediumTable.razor`** (the Sessions/Mixes browser grid) shows only `ReleaseAccessor(context).Title`
|
||||
(the release name) as its title column — no separate track-name column. Clean.
|
||||
- **`CmsSessionBrowser` / `CmsMixBrowser`** consume `CmsMediumTable` and likewise key off the release
|
||||
title only. Clean.
|
||||
|
||||
*Public — surfaces that already do the right thing (no change needed):*
|
||||
- **`SessionDetail.razor`** uses only `release.Title` for the masthead and `ViewModel.Track` for
|
||||
playback — it never renders the track name separately. Clean.
|
||||
- **`MixDetail.razor`** likewise uses only `release.Title` + `ViewModel.Track`. Clean.
|
||||
- **`ReleaseGallery.razor`** (the Sessions/Mixes card grid) shows `release.Title` + `release.Artist`
|
||||
only. Clean.
|
||||
|
||||
**Net blast radius:** the consolidation is **entirely CMS-side**, and concentrated in the two batch
|
||||
forms (`BatchUpload`, `BatchEdit`) via the shared `BatchTrackDetail`, plus the two legacy single-track
|
||||
forms (`TrackNew`, `TrackEdit`) *if they are still live*. The public site already treats a single-track
|
||||
release as one-named — no public work. This is the discovery step Daniel asked for: implementation
|
||||
knows the full surface set before touching anything.
|
||||
|
||||
**Acceptance criteria.**
|
||||
- On the **create** path (batch upload, single-track medium): the form presents **one** name field
|
||||
(Release Name). No separate Track Name input. On save, the single track's `TrackName` is set equal to
|
||||
the Release Name.
|
||||
- On the **edit** path (batch edit, single-track medium): the form presents **one** name field (Release
|
||||
Name). The per-row Track Name editor is suppressed. On save, the track's `TrackName` is set equal to
|
||||
the (possibly edited) Release Name — they stay synced.
|
||||
- **Cuts (multi-track) are unaffected**: a Cut release keeps its Release Name distinct from per-track
|
||||
names, and `BatchTrackDetail` still shows the per-track Track Name field for Cut rows.
|
||||
- Switching the medium selector mid-form between Cut and a single-track medium re-drives which name
|
||||
fields are visible (single name for Session/Mix; release + per-track names for Cut) without losing
|
||||
entered data where it still applies.
|
||||
- The legacy `TrackNew` / `TrackEdit` forms either apply the same single-name collapse (if live) or are
|
||||
flagged for retirement (if dead) — staff-engineer confirms their live status during implementation.
|
||||
- No public-site change is required (verified: public detail/gallery views already key off the release
|
||||
title only).
|
||||
|
||||
**Dependencies.** Pairs with **8.G** ("Album Name" → "Release Name" — the single name field these forms
|
||||
present should already read "Release Name" before this collapse lands; sequence 8.G first or together).
|
||||
Touches the same upload/edit forms as **8.E**/**8.F** — coordinate so the Session form's hero input
|
||||
(8.F), medium pre-selection (8.E), and name collapse (8.L) land coherently rather than fighting over the
|
||||
same submit handler. Independent of the tab restructure (8.A–8.D) and the public cluster.
|
||||
|
||||
---
|
||||
|
||||
## 3. Public site — 8.H through 8.J
|
||||
|
||||
### 8.H — Archive page becomes the searchable all-releases browser
|
||||
@@ -311,56 +425,56 @@ should follow for consistency — e.g. placeholder/help text — but the named c
|
||||
releases**. The searchable all-releases browser *is* the archive.
|
||||
|
||||
**User-visible change.** Visiting `/archive` (or clicking ARCHIVE) lands on a searchable, filterable
|
||||
browser of all releases — not three static cards. The cards are gone; the archive is the browse
|
||||
browser of **all releases** — not three static cards. The cards are gone; the archive is the browse
|
||||
surface.
|
||||
|
||||
**Shape — and the framing tension that needs a decision.** Daniel's note says the Archive should be
|
||||
"what the TRACKS page links to now — the searchable view of all releases," and that "naming everything
|
||||
TRACKS is misleading." There is a real cardinality mismatch to resolve:
|
||||
**Decision (H2 — Daniel, 2026-06-13): the archive is release-cardinal.** Build a **new searchable
|
||||
all-*releases* browser at `/archive`** — search + medium/genre filter, release cards (cover, title,
|
||||
artist) that link to the right per-medium detail page. This is consistent with the `/cuts`
|
||||
release-cardinal model and the `api/release` read family, and it mirrors the CMS tab model (8.A): both
|
||||
the public archive and the CMS archive now share one "all releases, filter by medium, search within"
|
||||
mental model (*One source, multiple views*). The earlier H1 reading (relabel the track-cardinal
|
||||
`TracksView` and re-home it) is **dropped** — Daniel thinks in releases, and the archive should match.
|
||||
|
||||
- The current `/tracks` (`TracksView`) is **track-cardinal** — it lists individual *tracks* with search
|
||||
and album/genre filter pills. It is the searchable view that exists today.
|
||||
- The medium browsers (`/cuts`, `/sessions`, `/mixes`) are **release-cardinal**.
|
||||
- Daniel says "all releases" — which reads release-cardinal — but points at `TracksView`, which is
|
||||
track-cardinal.
|
||||
**The cascade from H2 (decided):**
|
||||
- **`/tracks` (`TracksView`, track-cardinal) is no longer the archive.** It is not what ARCHIVE points
|
||||
at. Its fate: keep the route reachable (no hard 404), but it is demoted from the nav — the archive is
|
||||
the release-cardinal browser, and the flat track gallery is not the primary browse surface anymore.
|
||||
Treat `/tracks` the same way 8.I treats `/genres`: **drop it from the nav, keep the route reachable**,
|
||||
pending a later decision on whether to retire it wholesale. (It is not a Wave 8 deliverable to remove
|
||||
it; it simply stops being the archive.)
|
||||
- **8.I follows from H2** — ARCHIVE links to the new release-cardinal browser (not `TracksView`), and
|
||||
the three medium links sit beside it.
|
||||
|
||||
Two readings, and Daniel should pick:
|
||||
**Shape (informing, not prescribing).** A new public page at `/archive` consuming the `api/release`
|
||||
paged-list family (which already supports a medium filter — `COMPLETED.md §9`). Reuse the
|
||||
release-cardinal card idiom (`ReleaseGallery` already renders release cards that link to
|
||||
`/{detailRoute}/{id}`); the archive adds a search field and a medium filter (ALL + per-medium) above the
|
||||
grid. Drive the medium filter off `Enum.GetValues<ReleaseMedium>()` + a label lookup (the same Phase 9
|
||||
extension discipline), so a fourth medium surfaces a filter chip for free. Card→detail routing is
|
||||
medium-aware (a Cut card → `/cuts`-flavored target, a Session card → `/sessions/{id}`, a Mix card →
|
||||
`/mixes/{id}`); reuse the existing per-medium detail routes.
|
||||
|
||||
- **(H1) Archive = the existing track gallery, renamed.** Move/retarget `TracksView`'s searchable
|
||||
gallery to `/archive`, drop the misleading "Tracks" naming, and treat the flat searchable list as the
|
||||
archive. Lowest effort — it is the view that exists, relabelled and re-homed. *But* it is
|
||||
track-cardinal, which sits oddly with "all releases" and with the release-cardinal medium views it
|
||||
sits beside.
|
||||
- **(H2) Archive = a new searchable all-*releases* browser.** Build a release-cardinal searchable
|
||||
browser (search + medium/genre filter) at `/archive`, consistent with the `/cuts` release-cardinal
|
||||
model and the `api/release` read family. More work (a new browse surface), but coherent: the archive
|
||||
is releases, the medium tabs filter the archive, search filters within. This matches the *CMS* tab
|
||||
model (8.A) — the public archive and the CMS archive would share the "all releases, filter by medium,
|
||||
search within" mental model.
|
||||
**Mobile ARCHIVE → the searchable browser (Daniel, 2026-06-13).** With `/archive` becoming the
|
||||
searchable browser, **mobile ARCHIVE goes straight to that browser** (the medium modes are reachable
|
||||
via the in-page medium filter). The medium links also live in the hamburger sub-list under ARCHIVE
|
||||
(8.I). **The three-card overview is fully retired** — there is no card-overview destination on any
|
||||
breakpoint.
|
||||
|
||||
**Recommendation: (H2) if the release is the unit Daniel thinks in; (H1) if speed matters most.** The
|
||||
CMS side (8.A) is moving to a release-cardinal, medium-filtered archive — symmetry argues for (H2) on
|
||||
the public side too (*One source, multiple views*: the same browse model, CMS and public). But (H1) is
|
||||
materially cheaper and may be all Daniel wants. **This is a product decision — flag for Daniel before
|
||||
building 8.H.** Do not pick by default; the cardinality choice cascades into 8.I (what ARCHIVE links to)
|
||||
and the fate of `/tracks`.
|
||||
**Acceptance criteria.**
|
||||
- `/archive` renders a **release-cardinal** searchable browse surface (search field + medium/genre
|
||||
filter), not the three-card overview.
|
||||
- The surface covers **all releases** (every medium), with a medium filter (ALL + per-medium) and search
|
||||
within.
|
||||
- Each release card links to the correct per-medium detail page.
|
||||
- The medium filter is enum-driven (a fourth medium surfaces a filter chip with one lookup entry, no
|
||||
markup fork).
|
||||
- The old three-card overview (`ArchiveView`'s current body) is **fully retired** — desktop and mobile.
|
||||
- `/tracks` (`TracksView`) is no longer the archive and is dropped from the nav (route remains
|
||||
reachable; see 8.I posture for `/genres`).
|
||||
|
||||
**Acceptance criteria (conditional on the framing decision).**
|
||||
- `/archive` renders a searchable browse surface (search + filter), not the three-card overview.
|
||||
- The surface covers all releases (H2) or all tracks (H1) per the decision.
|
||||
- The old three-card overview is retired (or repurposed — see 8.I, the mobile question).
|
||||
- The misleading "Tracks"-as-everything naming is resolved (the route/label reflects "archive").
|
||||
|
||||
**Dependencies.** **Gated on the framing decision above.** Gates **8.I** (8.I links ARCHIVE to whatever
|
||||
8.H produces). Independent of 8.J.
|
||||
|
||||
**Open question (carry-over from §5.1 of the medium-types spec).** The original ARCHIVE design used
|
||||
`/archive` as the *mobile* overview (three cards) since the desktop popover is hover-only. If `/archive`
|
||||
becomes the searchable browser, **what is the mobile ARCHIVE destination?** Options: ARCHIVE on mobile
|
||||
goes straight to the searchable browser (the three medium modes are reachable via in-page filter/tabs),
|
||||
or the mobile hamburger keeps the three medium links indented under ARCHIVE (already does — see 8.I).
|
||||
Recommend: mobile ARCHIVE → the searchable browser; the medium links live in the hamburger sub-list
|
||||
(8.I) so the three-card overview is fully retired. Confirm with Daniel.
|
||||
**Dependencies.** Gates **8.I** (8.I links ARCHIVE to this browser). Independent of 8.J. No longer gated
|
||||
on a framing decision — H2 is decided.
|
||||
|
||||
---
|
||||
|
||||
@@ -387,23 +501,23 @@ the desktop breakpoint (though 8.J should still be fixed for any breakpoint wher
|
||||
e.g. mobile or a narrow-desktop fallback). Coordinate 8.I and 8.J: 8.I may *reduce* where the popover
|
||||
exists, 8.J fixes the dismissal wherever it remains.
|
||||
|
||||
`/genres` route and `GenresView` — Daniel says eliminate GENRES from the *nav*. Recommend the same
|
||||
posture Phase 9 took with CMS genre browse: **drop the nav item, keep the route reachable** (no active
|
||||
development, no hard removal) unless Daniel says retire it wholesale. Flag.
|
||||
**GENRES — remove the nav link only, for now (Daniel, 2026-06-13).** Drop the GENRES menu item. **Keep
|
||||
the `/genres` route and `GenresView` reachable** — no active development, no hard removal. This is the
|
||||
same posture Phase 9 took with the CMS genre browse and the same posture H2 sets for `/tracks`: demote
|
||||
from the nav, leave the route intact, defer the wholesale-retire question. So the work here is purely
|
||||
*remove the menu item from `Pages.cs`* — `GenresView` itself is untouched.
|
||||
|
||||
**Acceptance criteria.**
|
||||
- Above the medium breakpoint, ARCHIVE and CUTS / SESSIONS / MIXES appear as appbar links.
|
||||
- ARCHIVE links to the all-releases browser (8.H's output).
|
||||
- ARCHIVE links to the all-releases browser (8.H's output — the release-cardinal `/archive`).
|
||||
- Each medium link navigates to its view page (`/cuts`, `/sessions`, `/mixes`).
|
||||
- GENRES no longer appears in the nav.
|
||||
- Below the breakpoint, the nav remains usable (medium links reachable via the hamburger).
|
||||
- **GENRES no longer appears in the nav; `/genres` + `GenresView` remain reachable by URL** (nav-only
|
||||
removal, not retirement).
|
||||
- Below the breakpoint, the nav remains usable: the medium links live in the hamburger **sub-list under
|
||||
ARCHIVE** (8.H confirms mobile ARCHIVE → the searchable browser, with the medium links indented).
|
||||
|
||||
**Dependencies.** Depends on **8.H** (ARCHIVE's target). Coordinates with **8.J** (popover fate).
|
||||
|
||||
**Open question (flag).** Eliminate GENRES from the **nav only** (keep `/genres` route reachable), or
|
||||
retire `GenresView` entirely? *Recommend nav-only removal* (consistent with the CMS genre-browse
|
||||
disposition; the route is built and harmless). Confirm with Daniel.
|
||||
|
||||
---
|
||||
|
||||
### 8.J — ARCHIVE popover click does not close (bug)
|
||||
@@ -437,22 +551,25 @@ exists). Can be specced and fixed independently; sequence after 8.I if 8.I resha
|
||||
|
||||
---
|
||||
|
||||
## 4. Mix Visualizer — 8.K `[design pending interview]`
|
||||
## 4. Mix Visualizer — 8.K `[post-Phase-9, design-complete]`
|
||||
|
||||
**Do not write an implementation spec for this track.** Daniel has explicitly asked to be interviewed
|
||||
before the Mix Visualizer is redesigned. His seed idea: the waveform **scrolls** bottom-to-top in high
|
||||
resolution, with a slider controlling scroll speed / zoom level (higher resolution moves faster) —
|
||||
**not** a static background image (which is what `MixWaveformVisualizer` renders today: a single static
|
||||
full-viewport mirrored silhouette).
|
||||
**Out of Phase-9-completion scope (Daniel, 2026-06-13).** "Visualizer is outside the scope of phase 9
|
||||
but we must document it now in complete detail." Phase 9 can close **without** 8.K. The interview has
|
||||
run, and `product-notes/phase-9-mix-visualizer-redesign.md` is now a **finished, implementation-ready
|
||||
design spec** — no longer a question set. A future wave can be dispatched straight from it.
|
||||
|
||||
The structured interview question set is in `product-notes/phase-9-mix-visualizer-redesign.md`. It is
|
||||
grounded in the current implementation (read 2026-06-13): an SVG silhouette built from a stored loudness
|
||||
profile, full-page background, with an inert click-to-seek seam already present. The questions probe the
|
||||
motion model, zoom/resolution coupling, aesthetics, interaction, and performance so the eventual design
|
||||
is built on Daniel's actual intent, not a guess.
|
||||
Headline of the captured design: the visualizer becomes a **windowed, playback-coupled, bottom-to-top
|
||||
scrolling waveform** — a musical-score-going-by treatment showing only the currently-playing region.
|
||||
Zoom couples to apparent scroll speed (Guitar-Hero model: zoomed in = shorter time-span fills the
|
||||
screen = faster apparent motion), with a hard anchor that **at maximum zoom exactly one quarter note is
|
||||
visible at 180 BPM (~333 ms of audio)**. It is a **lava-lamp, not test-equipment** aesthetic —
|
||||
theme-aware gradients, glassy, **strictly read-only** (no seeking), a background/theming element.
|
||||
Rendering shifts to standard Canvas/WebGL with **no tricks — industry-standard patterns, well
|
||||
commented**. Full motion/zoom/aesthetic/interaction/performance/data spec, plus the datum-resolution
|
||||
analysis and recommendation, in the design doc.
|
||||
|
||||
**This track stays `[design pending interview]` until the interview runs and a design is captured.** It
|
||||
must not be dispatched for implementation from this document.
|
||||
**This is the one Wave 8 track that does not gate Phase 9 completion.** It is design-complete and
|
||||
sequenced as a post-Phase-9 implementation wave.
|
||||
|
||||
---
|
||||
|
||||
@@ -463,37 +580,48 @@ must not be dispatched for implementation from this document.
|
||||
- **8.A** (tab strip) — consumes 8.B; the structural spine. Land after 8.B.
|
||||
- **8.C** (per-medium edit), **8.E** (medium-aware Add Track) — layer onto 8.A; parallel with each
|
||||
other once 8.A lands.
|
||||
- **8.F** (Session hero in form), **8.G** (label rename) — **independent** of the tab work; land in
|
||||
parallel any time. 8.F pairs with 8.E (Session Add-Track → hero-capable form).
|
||||
- **8.F** (Session hero in form), **8.G** (label rename), **8.L** (single-track name consolidation) —
|
||||
**independent** of the tab work; touch the upload/edit forms. Sequence **8.G → 8.L** (the consolidated
|
||||
field should read "Release Name" first), and **coordinate 8.E/8.F/8.L** — all three touch the Session
|
||||
upload form and its submit handler.
|
||||
|
||||
**Public cluster:**
|
||||
- **8.J** (popover dismissal bug) — **independent**; can land immediately (but coordinate with 8.I if
|
||||
8.I reshapes the popover).
|
||||
- **8.H** (archive = searchable browser) — **gated on Daniel's cardinality decision** (H1 vs H2).
|
||||
- **8.I** (nav slim + GENRES out) — depends on 8.H (ARCHIVE target); coordinates with 8.J.
|
||||
- **8.H** (archive = release-cardinal searchable browser) — **decided (H2)**; build the new browser.
|
||||
- **8.I** (nav slim + GENRES out + `/tracks` demoted) — depends on 8.H (ARCHIVE target); coordinates
|
||||
with 8.J.
|
||||
|
||||
**Mix Visualizer:**
|
||||
- **8.K** — **blocked on the interview.** Not implementable from this doc.
|
||||
- **8.K** — **out of Phase-9 scope; design-complete.** Sequenced as a post-Phase-9 implementation wave,
|
||||
dispatchable straight from `phase-9-mix-visualizer-redesign.md`. Does not gate Phase 9 completion.
|
||||
|
||||
**Recommended sequencing.** Land the independent/trivial items first (8.G, 8.D, 8.J, 8.F) — they unblock
|
||||
nothing and need nothing. Then the CMS spine (8.B → 8.A → 8.C/8.E). On the public side, get Daniel's H1/
|
||||
H2 decision, then 8.H → 8.I. Run the 8.K interview in parallel with all of it; it gates only itself.
|
||||
**Recommended sequencing.** Land the independent/trivial items first (8.G, 8.D, 8.J), then 8.L
|
||||
(consolidation, after 8.G). Then the CMS spine (8.B → 8.A → 8.C/8.E), folding 8.F into the Session-form
|
||||
work alongside 8.E/8.L. On the public side, 8.H (the new release-cardinal archive) → 8.I. **Phase 9
|
||||
closes when 8.A–8.J + 8.L land; 8.K is explicitly excluded** and runs as a separate post-Phase-9 wave.
|
||||
|
||||
---
|
||||
|
||||
## 6. Decisions needed from Daniel before / during build
|
||||
## 6. Decisions — all resolved (Daniel, 2026-06-13)
|
||||
|
||||
1. **(8.H) Archive cardinality — H1 vs H2.** Is the public archive the existing **track** gallery
|
||||
relabelled (H1, cheap), or a new **release**-cardinal searchable browser (H2, coherent with the CMS
|
||||
archive and the medium views)? *This is the load-bearing product decision of the public cluster.*
|
||||
Recommend H2 for model symmetry, H1 if speed dominates.
|
||||
2. **(8.H) Mobile ARCHIVE destination.** With `/archive` becoming the searchable browser, does mobile
|
||||
ARCHIVE go to the browser (recommended) or keep a card overview? Affects whether the three-card view
|
||||
is fully retired.
|
||||
3. **(8.I) GENRES — nav-only removal vs full retirement.** Recommend nav-only (keep `/genres`
|
||||
reachable). Confirm.
|
||||
4. **(8.F) Session hero image — optional vs required.** Daniel's wording ("allow") reads optional.
|
||||
Recommend optional. Confirm.
|
||||
5. **(8.E, minor) `ALL`-tab Add Track default medium.** Recommend Cut. Not blocking.
|
||||
The open questions that gated this wave are answered. Recorded here as the decision log; baked into the
|
||||
acceptance criteria above.
|
||||
|
||||
Items 1–4 are genuine product calls; 5 has a safe default and should not block.
|
||||
1. **(8.H) Archive cardinality → H2.** The public archive is a **new release-cardinal searchable
|
||||
browser** at `/archive`, not the relabelled track gallery. Cascade: `/tracks` (`TracksView`) is
|
||||
demoted from the nav (route kept reachable); 8.I links ARCHIVE to the new browser.
|
||||
2. **(8.H) Mobile ARCHIVE → the searchable browser.** The three-card overview is fully retired on every
|
||||
breakpoint; medium links live in the hamburger sub-list under ARCHIVE.
|
||||
3. **(8.I) GENRES → nav-only removal.** Drop the menu item; keep `/genres` + `GenresView` reachable. No
|
||||
retirement.
|
||||
4. **(8.F) Session hero → optional, but warn if missing.** No hard validation gate; the form surfaces a
|
||||
warning when a Session is submitted without a hero image.
|
||||
5. **(8.E) `ALL`-tab Add Track default medium → Cut.** The medium selector remains user-changeable after
|
||||
landing on the upload form.
|
||||
6. **(8.L, recommendation pending confirm) Single-track name sync.** Recommended posture: keep the
|
||||
derived track name **synced** to the Release Name for Session/Mix on both create and edit, so they
|
||||
never diverge. (Daniel set the consolidation requirement; the sync-vs-diverge interaction detail is
|
||||
the one open recommendation — call it out, default to synced.)
|
||||
7. **(8.K) Mix Visualizer → out of Phase-9 scope, design-complete.** Documented in full now; built
|
||||
later. Phase 9 closes without it.
|
||||
|
||||
Reference in New Issue
Block a user