docs: resolve four Phase 17 open questions (OQ1/OQ4/OQ8/OQ10), defer ReleaseGallery card affordance
This commit is contained in:
@@ -249,7 +249,7 @@ The phase deferred behind the home-hero **Plays** stat card (`NowPlayingStats.ra
|
||||
|
||||
**Sequenced BOTTOM-UP (Daniel directive 2026-06-19): foundation first, the live card LAST.** Reverses the earlier "visible win early" framing — Daniel does not care about the live card until the whole substrate and all metrics are finished. Strict chain: `16.1 → 16.2 → 16.3 → (16.4 optional) → 16.5`. 16.1 is the only cold-start wave; 16.5 (the card) is the capstone built last.
|
||||
|
||||
- **16.1 — Foundation: capture seam + transport + event log (nothing reads it yet).** Player-service play tracker (high-water mark + engagement floor), share tracker in `SharePopover` (debounced), `sendBeacon` interop + unload handler, `POST api/event/{play,share}` (proxied, rate-limited), append-only `play_event`/`share_event` log + incremental `play_counter` rollup, server-side release resolution + derived release totals. **No `anonId` yet; no card consumption.** Cold-start wave.
|
||||
- **16.1 — Foundation: capture seam + transport + event log (nothing reads it yet).** Player-service play tracker (high-water mark + engagement floor), share tracker in `SharePopover` (debounced), `sendBeacon` interop + unload handler, `POST api/event/{play,share}` (proxied, rate-limited), append-only `play_event`/`share_event` log + incremental `play_counter` rollup, server-side release resolution + derived release totals. **No `anonId` yet; no card consumption.** Cold-start wave. **Landed:** 2026-06-19 on dev. Migration `20260619155610_AddPlayShareTelemetry` authored but not applied (Daniel-gated).
|
||||
- **16.2 — Completion-bucket classification + shares.** Three-bucket classification (D1) correct and exhaustive end to end (tracker → payload → log → per-bucket counter columns); share-channel split (link/embed). **Depends on 16.1.**
|
||||
- **16.3 — Unique-listener `anonId` layer (lowest-priority metric, D5).** Option A: mint/read client first-party `localStorage` id, thread `anonId` onto payloads (nullable in the log), count distinct server-side (all-time, D3). **The last metric layer** — folded into "everything finished," explicitly last-built of the substrate. **Depends on 16.1; builds on 16.2.**
|
||||
- **16.4 — Per-target / CMS stats surfaces.** `[speculative]` — `GET api/stats/{track,release}/{key}` + CMS analytics views (bucket/channel splits, leaderboards). Not committed; the event log already supports it. Off the critical path to the card; build before the capstone only if a surface wants it. **Depends on 16.1–16.3.**
|
||||
@@ -281,11 +281,15 @@ pre-queue self):
|
||||
**read-only** for shared release queues (no reorder, no remove); the embed iframe is resized to fit
|
||||
the panel.
|
||||
4. **Add to Queue** affordance — an icon button + tooltip beside every detail-page play button for a
|
||||
release (→ `EnqueueRange`) or track (→ `Enqueue`), lighting up the dormant `Enqueue` path.
|
||||
release (→ `EnqueueRange`) or track (→ `Enqueue`), lighting up the dormant `Enqueue` path. Scoped
|
||||
to the detail-page play sites (Cut header, Cut track rows, Session/Mix hero); **`ReleaseGallery`
|
||||
browse-grid cards are excluded** (no play button today — deferred per OQ10, captured in `TODO.md`).
|
||||
|
||||
**Architectural spine.** Engine grows **two additive members only** — `Move(from, to)` and
|
||||
**Architectural spine.** Engine grows **two additive members** — `Move(from, to)` and
|
||||
`RemoveAt(index)` — interop-free state mutations that re-emit `QueueChanged` and **never re-stream or
|
||||
interrupt the playing track** (the engine's stated open/closed posture; existing members untouched).
|
||||
interrupt the playing track** (the engine's stated open/closed posture; existing members untouched),
|
||||
**plus a small additive `Enqueue`-into-dormant affordance** (OQ8: append leaves a coherent
|
||||
`CurrentIndex` so the next play/skip is correct, without auto-playing).
|
||||
Both view modes render **one shared `QueueList` presentational component** off the same cascaded
|
||||
`IQueueService.Items`, differing only in presentation + an `Editable` flag (project memory: *one
|
||||
source, multiple views*). Reorder/remove run safely during prerender (no JS) — only playback
|
||||
@@ -293,22 +297,30 @@ transitions touch interop.
|
||||
|
||||
**Sequenced as three waves.** `17.1 → {17.2, 17.3}`. **17.1 (engine `Move`/`RemoveAt` + the shared
|
||||
`QueueList` view) is the cold-start prerequisite**, settled and independent of the UI decisions —
|
||||
it can begin immediately. 17.2 (docked overlay, editable) and 17.3 (Fixed embed panel + snippet
|
||||
resize + Add-to-Queue) hang off it and are largely parallel. Add-to-Queue may split to a standalone
|
||||
17.4 (it needs only the existing `Enqueue`/`EnqueueRange`, not 17.1's new members).
|
||||
it can begin immediately. 17.2 (docked overlay, editable, `MudDropContainer` reorder) and 17.3 (Fixed
|
||||
embed panel + snippet resize + Add-to-Queue — **the OQ1 Option-A-vs-B feasibility call is made here**)
|
||||
hang off it and are largely parallel. Add-to-Queue may split to a standalone 17.4 (it needs only the
|
||||
existing `Enqueue`/`EnqueueRange`, not 17.1's new members).
|
||||
|
||||
Full design — goal, constraints, use cases, acceptance criteria, test cases, wave decomposition, and
|
||||
the open-question set: `product-notes/phase-17-player-queue-view.md`.
|
||||
|
||||
**Open questions (Daniel's call — spec §10).** OQ1 (Queue button behavior in embed mode given the
|
||||
panel is always shown — recommend repurpose as collapse/expand toggle); OQ2 (click-a-row to jump —
|
||||
recommend yes, both modes); OQ3 (terminal/empty states after removal); OQ4 (drag mechanism + touch
|
||||
viability — `MudDropContainer` vs. pointer-interop vs. up/down-arrow fallback; mobile is a primary
|
||||
surface); OQ5 (Clear-queue in the UI and whether it stops playback); OQ6 (embed panel height —
|
||||
fixed+scroll vs. grow-to-cap); OQ7 (Material vs. bespoke `DDIcons` glyph); OQ8 (Add-to-Queue into a
|
||||
dormant/empty queue — recommend pure append, keep "add" ≠ "play"); OQ9 (exclude `StreamNowButton` —
|
||||
no fixed track); OQ10 (`ReleaseGallery` cards — recommend defer; cards have no play button today);
|
||||
OQ11 (removing the current track — recommend keep playing to natural end). **None block 17.1.**
|
||||
**Open questions — 4 resolved (Daniel, 2026-06-19), 7 pending (spec §10).**
|
||||
|
||||
- **Resolved (Daniel, 2026-06-19):** **OQ1** → **Option A, conditional** — collapse/expand toggle *if*
|
||||
the embed snippet can dynamically resize the iframe (`postMessage` → host resize handshake), **else
|
||||
fall back to Option B** (omit the button); A preferred, B fallback, deciding factor = iframe-resize
|
||||
feasibility, **determined during 17.3**. **OQ4** → **`MudDropContainer` for now** (C6 softened —
|
||||
touch-viability is a known risk with a planned pivot path, not a pre-ship blocker). **OQ8** →
|
||||
**pure append** (add ≠ play; first add into a dormant queue leaves a coherent `CurrentIndex` via the
|
||||
17.1 engine affordance, no auto-play). **OQ10** → **deferred** (cards get no Add-to-Queue in Phase
|
||||
17; deferred card work captured in `TODO.md`).
|
||||
- **Still pending (recommendations stand, not confirmed):** OQ2 (click-a-row to jump — recommend yes,
|
||||
both modes); OQ3 (terminal/empty states after removal); OQ5 (Clear-queue in the UI and whether it
|
||||
stops playback); OQ6 (embed panel height — fixed+scroll vs. grow-to-cap; couples to OQ1's resize
|
||||
decision); OQ7 (Material vs. bespoke `DDIcons` glyph); OQ9 (exclude `StreamNowButton` — no fixed
|
||||
track); OQ11 (removing the current track — recommend keep playing to natural end).
|
||||
- **None block 17.1.**
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user