Import the R2 implementation spec into the repo
The plan was delivered as wp-suite-implementation-spec.zip and lived only in Downloads, so every "read CLAUDE.md first" instruction in it pointed at a file the repo did not have. Bring it in unchanged: CLAUDE.md, IMPLEMENTATION.md, and docs/waves/wave-0 through wave-9 plus backlog.md. UX-REVIEW-2026-08-14.md is committed alongside it. It is the review that produced F1-F6, S1-S13 and the A/B/C assessments, and item IDs throughout the wave files cite it, so it belongs under version control rather than sitting untracked in the working tree. No application code changes here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
120
UX-REVIEW-2026-08-14.md
Normal file
120
UX-REVIEW-2026-08-14.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# UX Review — Work Package Suite
|
||||
|
||||
**Date:** 2026-08-14 · **Branch:** `users/directory-super-user` · **Scope:** `html/` — 6 pages, 4 stylesheets, ~11.9k lines
|
||||
|
||||
Full write-up with screenshots: <https://claude.ai/code/artifact/09d89aa1-54b9-41db-9e09-e1fc8fb55852>
|
||||
|
||||
**Method.** Two passes. A full read of the frontend, then the app run locally
|
||||
(`uvicorn server.app:app`, throwaway SQLite DB) and driven in Chrome through the real
|
||||
first-run flow: sign in → create project → SOP wizard → creator → directory → field view
|
||||
at 390px. Section 1 below is browser-verified; section 2 is read from source.
|
||||
|
||||
> Incidental find: `server/seed_demo.py` no longer authenticates, so it can't seed a
|
||||
> running instance — every `/api/` route requires a session and the script sends none.
|
||||
> It predates the commit that taught the smoke test to sign in.
|
||||
|
||||
---
|
||||
|
||||
## 1. Rendering defects (browser-verified, reproducible today)
|
||||
|
||||
No design decisions needed for any of these.
|
||||
|
||||
| # | Defect | Severity |
|
||||
|---|---|---|
|
||||
| F1 | **Header project switcher is stale on every page.** Hero, picker and create-user card show the active project; the app bar still reads "Select a project". Two sources of truth, global one loses. | High |
|
||||
| F2 | **App bar breaks at 390px — on Field View.** Nav wraps to 3 rows and clips: "Sign out" cut in half, search truncated. This is the gloved-hands surface. | High |
|
||||
| F3 | **Logo/project-name collision in the SOP header.** `.header-left` and the injected chrome fight for the same run of the bar. | Medium |
|
||||
| F4 | **Comments drawer renders off-screen over the header** in the standalone creator. | Medium |
|
||||
| F5 | **SOP wizard fields read as read-only** — `#f4f4f4` fill, `#e0e0e0` border. Cause: the wizard redeclares its own tokens and never sees `--cds-field: #ffffff`. | Medium |
|
||||
| F6 | **The creator is one ~4,700px form** — 11 cards rendered at once, jump links standing in for structure. | Medium |
|
||||
|
||||
F1 and F2 are prerequisites for the proposed chrome work.
|
||||
|
||||
---
|
||||
|
||||
## 2. Structural findings (from source)
|
||||
|
||||
### Costs users work
|
||||
- **Validation is `alert()`-only, covering 3 of 10 wizard steps.** 79 native dialogs app-wide,
|
||||
43 in the creator. `wp-creation-app.js:1144` says "Subject and WP Type are required" without
|
||||
naming, highlighting or scrolling to the field — on a form ten cards deep.
|
||||
`validateStep` guards only steps 1, 5, 6 while the markup marks required fields throughout.
|
||||
- **No autosave, no unsaved-work guard.** The only `beforeunload` listener is analytics dwell
|
||||
tracking (`work-package-suite-app.js:326`).
|
||||
- **Nothing is linkable.** No `pushState` anywhere. Tab switches, dashboard views and package
|
||||
selections change no URL — can't send someone a link to WP07; refresh loses your place.
|
||||
- **No global nav on the two pages people live in.** Drawer + app bar ship on `admin`, `field`,
|
||||
`users`. The SOP wizard has its own header and no drawer; the creator has neither, plus a
|
||||
different brand treatment (mono wordmark vs. logo chip).
|
||||
|
||||
### Costs consistency
|
||||
- **Four parallel token systems.** `#0f62fe` is declared 4× (`--cds-interactive-01`, `--primary`,
|
||||
`--accent` twice). Already caused a bug — see the comment at
|
||||
`work-package-suite-styles.css:336` about `.field-hint` rendering unstyled.
|
||||
- **Icon set is mixed emoji + dingbats** (⤓ ⤒ 👁 ★ 📊 ⧉ 🕘 💬 ▤ ⚙ 🔒 ⚡ ⎙ ◔ ▦). `▤` is used for
|
||||
two different things on the same page.
|
||||
- **Four sample-data affordances under three names.** One sits a click from live project data
|
||||
with no confirm and no undo.
|
||||
|
||||
### Costs accessibility (and the field case)
|
||||
- **Hover-only tooltips carry load-bearing instructions.** 15 `.help-tip` badges, `<span>`s with
|
||||
no `tabindex` — so the `:focus` half of their CSS rule is dead code and there's no touch path.
|
||||
- **SOP step rail not keyboard-reachable.** All 10 steps are `<div onclick>`; 12 `<div>` + 2
|
||||
`<span>` click handlers app-wide.
|
||||
- **Zero `aria-live` regions.** Both toast systems and every admin banner announce nothing.
|
||||
`login.html` gets this right with `role="alert"`/`role="status"`; the pattern never spread.
|
||||
- **Helper text at ~2.9:1** (`--text-dim: #8d8d8d` at 12px). `console.css:85-87` already
|
||||
diagnosed and fixed this; the other two sheets didn't follow.
|
||||
- **Wizard removes the focus ring** — `outline: none` plus a pale 3px glow
|
||||
(`work-package-suite-styles.css:322-328`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Assessment of the proposed change list
|
||||
|
||||
Strong work — nearly every item maps to something verifiable, and two rank above anything in
|
||||
this review's own findings. 9 endorsed, 7 need adjustment, 6 gaps.
|
||||
|
||||
### Endorse as proposed
|
||||
| ID | Item | Note |
|
||||
|---|---|---|
|
||||
| A1 | **Guarded status transitions** | Best item on the list. But: Issue (Hold) is a *branch* from several states, and there's a deliberate **logged-override** path for predecessors (`wp-creation-app.js:1962-1972`). "One legal next action" is too narrow — model as primary-next **+ audited override**. |
|
||||
| A2 | De-duplicate constraint warning | Triplication confirmed. Caveat: the top banner is the only one visible without scrolling, so the tab count badge must carry that weight. |
|
||||
| A3 | Fields that look editable | Confirmed (F5). Pair with token consolidation or it drifts back. |
|
||||
| A4 | Vertical stepper + progress | Also retires the orphaned "1 / 10" counter. Make the steps real `<button>`s while rebuilding. |
|
||||
| A5 | One button system, no green/blue mix | Real: green `Save & View` + green `SOP Complete` vs blue elsewhere. **Scope "sentence case" to buttons/field labels** — the uppercase card-header idiom in `console.css` is deliberate and works. |
|
||||
| A6 | Sidebar triage data + inline hold reason | Cheap — hold reason is already captured by the hold modal. |
|
||||
| A7 | Card status lines · footer clarity · Language & time | Localization is a real shipped feature (`admin.js:484-517`), so keeping it is correct. |
|
||||
|
||||
### Right diagnosis, adjust the prescription
|
||||
| ID | Item | Adjustment |
|
||||
|---|---|---|
|
||||
| B1 | Collapse the 8-item nav | **Don't build a new avatar menu — ship the drawer you already have.** It's the best chrome in the app and already holds the whole nav; it's just on 3 pages of 6 while a flat strip duplicates it. Put it everywhere, delete the strip. Fixes F2. |
|
||||
| B2 | Un-truncate the switcher | Fix **correctness (F1) first**. "Micron EUV Cleanroom Enable · 2667008" won't fit 280px, and existing rules narrow it to 150px under 900px — needs a breakpoint plan. |
|
||||
| B3 | Remove the project-picker card | The first-run empty state lives *inside* that card. A header dropdown is the wrong home for "create your first project" — the launcher needs an explicit empty state. |
|
||||
| B4 | 4-cell pipeline strip | Hard data dependency: launcher SOP status reads `localStorage`, and the creator's dashboard admits it "reads local data now; wires to SQL in Phase 2". Per-browser numbers that look authoritative are worse than none. **Server aggregates first.** |
|
||||
| B5 | Autosave status text | Must ship with **actual autosave + dirty guard**. A "✓ All changes saved" toast already appears (that's the sync outbox, not your draft), so the app arguably implies this today. |
|
||||
| B6 | Wizard actions beside the fields | On Constraints/Sequence steps that means scrolling to save. **Prefer sticky** — the creator's sticky save bar already solves it. |
|
||||
| B7 | Toolbar into the tab row | Unstated prerequisite: tab row is in the parent, toolbar in the iframe child. This **requires dissolving the iframe** — the largest engineering item on the list. Name and schedule it. |
|
||||
|
||||
### Not addressed
|
||||
| ID | Gap |
|
||||
|---|---|
|
||||
| C1 | **Accessibility** — and the redesign touches every broken part. The step rail being rebuilt is 10 `<div onclick>`s; the status pills being replaced are the moment for a real radio group; the tooltips are unreachable on the tablet Field View targets. Skipping these means paying for the same components twice. |
|
||||
| C2 | **Mobile** — no item on the list, and it's where the worst rendering is (F2). |
|
||||
| C3 | **Token consolidation** — without it, "one button system" gets implemented four times and drifts, exactly as `.field-hint` did. |
|
||||
| C4 | **URL state · icon system · unsaved-changes guard · sample-data sprawl** — none addressed. |
|
||||
|
||||
---
|
||||
|
||||
## 4. Recommended sequence
|
||||
|
||||
Ordered by dependency, not preference.
|
||||
|
||||
1. **The six rendering defects.** No design decisions; F1/F2 unblock the chrome work.
|
||||
2. **Drawer everywhere, flat strip deleted.** Reuses the best existing component, fixes phone-width collapse, settles global nav before anything is redrawn.
|
||||
3. **Token consolidation.** One source of truth, page sheets aliasing to it. Every later visual item lands once instead of four times.
|
||||
4. **Launcher + SOP wizard.** Pipeline strip (after server aggregates), empty-state ownership, vertical stepper, editable fields, autosave + guard. Make the 10 steps buttons while rebuilding.
|
||||
5. **The creator.** Guarded transitions, de-duplicated warnings, section tabs, triage data. **Decide the iframe question up front** — most of this depends on it.
|
||||
|
||||
**Dependencies:** B1 resolves F2 · B2 depends on F1 · A3 depends on C3 · B7 gates most of step 5.
|
||||
Reference in New Issue
Block a user