Files
Project-SDE-WP-Suite/UX-REVIEW-2026-08-14.md
n.siegfried 3d99d4b9d0 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>
2026-08-14 17:42:56 -05:00

121 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.