v4.4.0 build order: UX Overhaul in six phases, with two review checkpoints #535

Open
opened 2026-09-06 19:30:20 +00:00 by claude-bot · 5 comments
Contributor

Tracking issue for the v4.4.0 milestone (12 issues: the seven-step design process #361–#367, plus #182, #422, #424, #437, #464 folded in). The order, the reasoning, and where the milestone stops for a human decision. The v4.3.0 tracking issue (#514) is the model.

Principles

  1. Design is decided by looking, not by argument. The milestone's own process is brief → divergent wireframes → convergent mockups → build. Two of those steps end with a choice only the owner can make, so the plan has two explicit checkpoints and nothing visual is built before the second.
  2. Mechanism before appearance. Two issues change how the frontend is wired rather than how it looks (#464 data router, #182 React Compiler rules). They go first, in parallel with the brief, so the rebuild inherits them instead of redoing them.
  3. Backend work that the design needs but does not depend on goes early. #424 needs beats persisted (a migration and a router) before any screen can show them; #437 needs an admin campaigns endpoint. Both can be built and tested against the API while the design is still being chosen; only their screens wait.
  4. The product stays usable throughout. #366 is built surface by surface on the component library, each lane a PR that leaves main deployable. Accessibility (#367) is a rule applied in every lane plus a final pass, not a retrofit.
  5. Same orchestration as v4.3.0. One delegate per file cluster, one PR per lane with Closes …, auto-merge on green CI, completion notes on every issue, dev deploy after each phase for a look, prod once at the end.

Phase 0 — Mechanism (parallel, starts now)

issue what lane
#464 createBrowserRouter + RouterProvider; useBlocker in the unsaved-changes hook for the summary and transcript editors App.jsx, hooks, SessionDetail
#182 fix the set-state-in-effect sites, then adopt the plugin's recommended preset the seven pages the probe names

Different files; both are prerequisites for everything that follows.

Phase 1 — The brief (#361) → checkpoint A

A fresh surface inventory (the audit's route table predates v4.3.0's nav bar and is in a gitignored folder that no longer exists on any machine), the six journeys as the acceptance bar, the vocabulary mapping (mostly settled by #379; the leftovers are named), the constraints, and the list of what must survive. Presented together with phase 2 so there is one review rather than two.

Phase 2 — Wireframes (#362) → checkpoint A

Seven low-fidelity concepts, each taking a distinct position on the five questions the audit posed (where attention lives, what the spine is, whether the session or the campaign is the primary object, how GM and player views relate, what the at-the-table surface is). Each concept shows the six structural surfaces at desktop and phone width and is walked through the six journeys; the secondary surfaces are placed in a table per concept. Delivered as a single comparison page. The owner picks two or three concepts, or elements of several, to carry forward.

Phase 3 — Mockups (#363) → checkpoint B

Three to five high-fidelity directions built from the choice at checkpoint A, populated with realistic sample data (a campaign mid-arc, sessions in every state, a real-length transcript and summary, a populated wiki, a queue of suggestions, a recording in progress), at desktop, tablet and phone widths, GM and player, including loading, error, empty and in-progress states. The owner picks one direction, or a recombination, and that decision is written into the brief.

Phase 4 ∥ — Backend groundwork (parallel with phases 1–3)

  • #424 backend half: persist beats per summarisation run (migration + model + GET router, validation results and cited transcript timestamps included), tests, no change to what a GM sees yet. The decision on per-run versus last-write-wins is made here: per run, because #423 showed two runs over the same audio genuinely differ and the comparison is the point.
  • #437 backend half: an admin-only campaigns list endpoint with GMs, member count, session count, guild linkage, retention overrides, created date. Metadata only. The content-access decision is taken now so the screen does not decide it by accident: admins see that a campaign exists and who runs it; they do not open it. Drill-through, if ever wanted, is a separate issue with an audit entry.

Phase 5 — The build

  • 5a #364 the design system: tokens (type, spacing, colour with the existing dark mode, elevation), the primitives (button hierarchy, form controls, badges and counts, cards, dialogs and confirmations, empty/loading/error states, the async-progress pattern), the interaction rules written down, and a stated touch-target minimum. Ships as a library plus a documentation page; no screen changes yet.
  • 5b #366 the rebuild, one lane per surface cluster in this order: dashboard and navigation → session (folding in #422's per-session character pin and #424's verified-events view) → prep → at-the-table and mobile (#365, on the Session Shelf, the wiki article and campaign detail ordering) → wiki and review → the remainder (profile, highlights, analytics, admin with #437's screen, join, help, login). Each lane replaces window.confirm, page-level errors and ad-hoc styles with the library as it goes.
  • 5c #367 accessibility: the standard (WCAG 2.2 AA) is applied in every 5b lane; automated checks go into CI with the first lane; a final keyboard-only walk of the six journeys closes it. The manual screen-reader pass is the owner's, on a real device.

Phase 6 — Release

v4.4.0 at the end, deployed dev then prod. Phase 0 rides with it rather than earning a patch release of its own; if the design phases run long, phase 0 plus phase 4 can ship as v4.3.1 to keep the deploy cadence.

Out of scope, noted

No backend re-architecture, no new features beyond the four folded issues, no change to the Discord embeds or notification content (v5.4.0), no localisation. Table and safety tools are v4.5.0; they will be built on this design system.

Tracking issue for the v4.4.0 milestone (12 issues: the seven-step design process #361–#367, plus #182, #422, #424, #437, #464 folded in). The order, the reasoning, and where the milestone stops for a human decision. The v4.3.0 tracking issue (#514) is the model. ## Principles 1. **Design is decided by looking, not by argument.** The milestone's own process is brief → divergent wireframes → convergent mockups → build. Two of those steps end with a choice only the owner can make, so the plan has two explicit checkpoints and nothing visual is built before the second. 2. **Mechanism before appearance.** Two issues change how the frontend is wired rather than how it looks (#464 data router, #182 React Compiler rules). They go first, in parallel with the brief, so the rebuild inherits them instead of redoing them. 3. **Backend work that the design needs but does not depend on goes early.** #424 needs beats persisted (a migration and a router) before any screen can show them; #437 needs an admin campaigns endpoint. Both can be built and tested against the API while the design is still being chosen; only their screens wait. 4. **The product stays usable throughout.** #366 is built surface by surface on the component library, each lane a PR that leaves main deployable. Accessibility (#367) is a rule applied in every lane plus a final pass, not a retrofit. 5. **Same orchestration as v4.3.0.** One delegate per file cluster, one PR per lane with `Closes …`, auto-merge on green CI, completion notes on every issue, dev deploy after each phase for a look, prod once at the end. ## Phase 0 — Mechanism (parallel, starts now) | issue | what | lane | |---|---|---| | #464 | `createBrowserRouter` + `RouterProvider`; `useBlocker` in the unsaved-changes hook for the summary and transcript editors | App.jsx, hooks, SessionDetail | | #182 | fix the `set-state-in-effect` sites, then adopt the plugin's `recommended` preset | the seven pages the probe names | Different files; both are prerequisites for everything that follows. ## Phase 1 — The brief (#361) → **checkpoint A** A fresh surface inventory (the audit's route table predates v4.3.0's nav bar and is in a gitignored folder that no longer exists on any machine), the six journeys as the acceptance bar, the vocabulary mapping (mostly settled by #379; the leftovers are named), the constraints, and the list of what must survive. Presented together with phase 2 so there is one review rather than two. ## Phase 2 — Wireframes (#362) → **checkpoint A** Seven low-fidelity concepts, each taking a distinct position on the five questions the audit posed (where attention lives, what the spine is, whether the session or the campaign is the primary object, how GM and player views relate, what the at-the-table surface is). Each concept shows the six structural surfaces at desktop and phone width and is walked through the six journeys; the secondary surfaces are placed in a table per concept. Delivered as a single comparison page. **The owner picks two or three concepts, or elements of several, to carry forward.** ## Phase 3 — Mockups (#363) → **checkpoint B** Three to five high-fidelity directions built from the choice at checkpoint A, populated with realistic sample data (a campaign mid-arc, sessions in every state, a real-length transcript and summary, a populated wiki, a queue of suggestions, a recording in progress), at desktop, tablet and phone widths, GM and player, including loading, error, empty and in-progress states. **The owner picks one direction, or a recombination, and that decision is written into the brief.** ## Phase 4 ∥ — Backend groundwork (parallel with phases 1–3) - #424 backend half: persist beats per summarisation run (migration + model + `GET` router, validation results and cited transcript timestamps included), tests, no change to what a GM sees yet. The decision on per-run versus last-write-wins is made here: **per run**, because #423 showed two runs over the same audio genuinely differ and the comparison is the point. - #437 backend half: an admin-only campaigns list endpoint with GMs, member count, session count, guild linkage, retention overrides, created date. Metadata only. The content-access decision is taken now so the screen does not decide it by accident: **admins see that a campaign exists and who runs it; they do not open it.** Drill-through, if ever wanted, is a separate issue with an audit entry. ## Phase 5 — The build - **5a** #364 the design system: tokens (type, spacing, colour with the existing dark mode, elevation), the primitives (button hierarchy, form controls, badges and counts, cards, dialogs and confirmations, empty/loading/error states, the async-progress pattern), the interaction rules written down, and a stated touch-target minimum. Ships as a library plus a documentation page; no screen changes yet. - **5b** #366 the rebuild, one lane per surface cluster in this order: dashboard and navigation → session (folding in #422's per-session character pin and #424's verified-events view) → prep → at-the-table and mobile (#365, on the Session Shelf, the wiki article and campaign detail ordering) → wiki and review → the remainder (profile, highlights, analytics, admin with #437's screen, join, help, login). Each lane replaces `window.confirm`, page-level errors and ad-hoc styles with the library as it goes. - **5c** #367 accessibility: the standard (WCAG 2.2 AA) is applied in every 5b lane; automated checks go into CI with the first lane; a final keyboard-only walk of the six journeys closes it. The manual screen-reader pass is the owner's, on a real device. ## Phase 6 — Release v4.4.0 at the end, deployed dev then prod. Phase 0 rides with it rather than earning a patch release of its own; if the design phases run long, phase 0 plus phase 4 can ship as v4.3.1 to keep the deploy cadence. ## Out of scope, noted No backend re-architecture, no new features beyond the four folded issues, no change to the Discord embeds or notification content (v5.4.0), no localisation. Table and safety tools are v4.5.0; they will be built on this design system.
Author
Contributor

Phase 4 correction. #424's backend half does not need building: it shipped in v4.0.0 (2791c24, aa4bff9) as summarisation_runs + session_beats with GET /api/sessions/{id}/summarisation-runs[/latest], GM-only. The plan above was written from the issue body, which predates that. The per-run decision recorded here was already the shipped behaviour. #424 is now frontend-only and stays in the session lane of phase 5b, building against the latest-run endpoint. #437's backend half is unaffected and in progress.

**Phase 4 correction.** #424's backend half does not need building: it shipped in v4.0.0 (`2791c24`, `aa4bff9`) as `summarisation_runs` + `session_beats` with `GET /api/sessions/{id}/summarisation-runs[/latest]`, GM-only. The plan above was written from the issue body, which predates that. The per-run decision recorded here was already the shipped behaviour. #424 is now frontend-only and stays in the session lane of phase 5b, building against the latest-run endpoint. #437's backend half is unaffected and in progress.
Author
Contributor

Phase 0 and the phase 4 backend half are on main (b57fd09).

PR issue merged
#537 data router + in-app unsaved-edit prompt #464, closed cce8601
#538 GET /api/admin/campaigns, metadata only #437, backend half; issue stays open for the screen 9373464
#540 React Compiler lint rules, 40 sites fixed #182, closed b57fd09

Two things the lanes could not have seen alone: #464's new hook seeded its blocker key from an effect, which #182's newly enabled rule forbids, so #540 carries a one-commit reconciliation (useId instead); and the merge run for #538 hit the v4.3.0 "poll gives up" flake, which turned out to be an ordering race rather than a timing margin, fixed in a follow-up PR against the test only.

Follow-ups filed from the lanes: #536 (Shelf tonight-notes debounce not flushed), #539 (body autosave "Saved" wiped). #424's backend was already on main from v4.0.0, so phase 4 had one lane, not two.

Checkpoint A (brief + concepts) is published and waiting on the owner. Deploying phase 0 to dev next for a look at the router change in a real browser.

**Phase 0 and the phase 4 backend half are on main** (`b57fd09`). | PR | issue | merged | |---|---|---| | #537 data router + in-app unsaved-edit prompt | #464, closed | `cce8601` | | #538 `GET /api/admin/campaigns`, metadata only | #437, backend half; issue stays open for the screen | `9373464` | | #540 React Compiler lint rules, 40 sites fixed | #182, closed | `b57fd09` | Two things the lanes could not have seen alone: #464's new hook seeded its blocker key from an effect, which #182's newly enabled rule forbids, so #540 carries a one-commit reconciliation (`useId` instead); and the merge run for #538 hit the v4.3.0 "poll gives up" flake, which turned out to be an ordering race rather than a timing margin, fixed in a follow-up PR against the test only. Follow-ups filed from the lanes: #536 (Shelf tonight-notes debounce not flushed), #539 (body autosave "Saved" wiped). #424's backend was already on main from v4.0.0, so phase 4 had one lane, not two. Checkpoint A (brief + concepts) is published and waiting on the owner. Deploying phase 0 to dev next for a look at the router change in a real browser.
Author
Contributor

Checkpoint A widened. The owner wants the players (the beta testers) to weigh in on the player side, and the redesign checked against in-person tables now even though those features are a later milestone.

  • Two audience pages published alongside the design page: players (four phone-first screens per concept, the in-person shared screen drawn for each) and GMs (the six GM screens per concept plus an in-person note). Each carries a short form that saves answers to the page's own store; a readout is a table on request.
  • The brief gains the in-person constraint; every concept gains a sixth position, "where the shared screen lives"; the comparison and the recommendation account for it. Details and the later-milestone feature list are in #542.
  • Checkpoint A now closes when the owner has the players' answers and picks the concepts to carry into #363. The mockups will include the shared-screen face and a recording-source selector for the chosen direction (#542's acceptance).
**Checkpoint A widened.** The owner wants the players (the beta testers) to weigh in on the player side, and the redesign checked against in-person tables now even though those features are a later milestone. - Two audience pages published alongside the design page: players (four phone-first screens per concept, the in-person shared screen drawn for each) and GMs (the six GM screens per concept plus an in-person note). Each carries a short form that saves answers to the page's own store; a readout is a table on request. - The brief gains the in-person constraint; every concept gains a sixth position, "where the shared screen lives"; the comparison and the recommendation account for it. Details and the later-milestone feature list are in #542. - Checkpoint A now closes when the owner has the players' answers and picks the concepts to carry into #363. The mockups will include the shared-screen face and a recording-source selector for the chosen direction (#542's acceptance).
Author
Contributor

Checkpoint A is now collectable from people without accounts: the players' and GMs' pages run as a self-hosted site at https://questboard-dev.rhoving.com/feedback/ (PRs #546, #550; iac-repo #405 for the route). Players see the phone drawings only; GMs also see each concept's shared screen for an in-person table and give that feedback. Checkpoint A closes when the owner has the responses and picks the concepts for #363.

Checkpoint A is now collectable from people without accounts: the players' and GMs' pages run as a self-hosted site at https://questboard-dev.rhoving.com/feedback/ (PRs #546, #550; iac-repo #405 for the route). Players see the phone drawings only; GMs also see each concept's shared screen for an in-person table and give that feedback. Checkpoint A closes when the owner has the responses and picks the concepts for #363.
Author
Contributor

Incident note, 2026-09-07: the feedback site's pages redirected to the dashboard for anyone whose browser had used the dev Quest Board. Cause: the app's service worker answers every navigation on the hostname with the app shell unless the path is denylisted, and /feedback was not. Fixed in PR #551 (/feedback on the navigation-fallback denylist and network-only), merged and deployed to dev at 599829e; the served worker now carries the exclusion. Browsers holding the old worker are right after one reload. Also live at the edge: the /feedback redirect keeps its query string (iac-repo #406), and the site's pages answer HEAD. Recorded as a rule in the config comment: any non-app path served on a Quest Board hostname needs the same treatment.

Incident note, 2026-09-07: the feedback site's pages redirected to the dashboard for anyone whose browser had used the dev Quest Board. Cause: the app's service worker answers every navigation on the hostname with the app shell unless the path is denylisted, and `/feedback` was not. Fixed in PR #551 (`/feedback` on the navigation-fallback denylist and network-only), merged and deployed to dev at `599829e`; the served worker now carries the exclusion. Browsers holding the old worker are right after one reload. Also live at the edge: the `/feedback` redirect keeps its query string (iac-repo #406), and the site's pages answer HEAD. Recorded as a rule in the config comment: any non-app path served on a Quest Board hostname needs the same treatment.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#535
No description provided.