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>
9.2 KiB
Wave 5 — Launcher and SOP wizard
Items: A4, B3, S9, S1 (wizard), CR-005, CR-006, CR-002, CR-016
Depends on: wave 4 merged
Why here: CR-006 is the enabler for every removal request in the plan. Building it
before CR-002 and CR-016 means nothing gets deleted that another project may need.
First field-visible wave. Everything before this was prerequisites.
T5.1 — A4 + S9: Vertical stepper with real buttons
- Items:
A4,S9 - Depends on: T3.4, T3.5, T2.2
- Blocks: T5.4, T5.5
- Surface:
html/ - Files: SOP wizard step rail
Problem: The step rail is 10 <div> elements with onclick, so it is unreachable by
keyboard. There is also an orphaned "1 / 10" counter doing the job a stepper should do.
Do: Rebuild the rail as a vertical stepper showing all 10 steps, which is complete, which
is current, and which are not yet reachable. Every step is a real <button>. Retire the
"1 / 10" counter.
Per C1, this is the moment to make it accessible — it is being rebuilt anyway.
Do not: ship a single <div onclick> in the replacement. The app-wide count from wave 0
must go down by 10.
Done when:
- all 10 steps are
<button>elements - the rail is fully operable by keyboard: tab, arrow keys, enter and space
- current step is exposed with
aria-current - completed, current and unavailable states are distinguishable without relying on color alone
- the "1 / 10" counter is gone
- app-wide
<div onclick>count dropped by 10 versus the wave 0 baseline
T5.2 — B3: Launcher empty state, then remove the picker card
- Items:
B3 - Depends on: T4.1
- Blocks: T5.3
- Surface:
html/ - Files: launcher, project picker card
Problem: The proposal removes the project-picker card, but the first-run empty state lives inside it. A header dropdown is the wrong home for "create your first project".
Do: Build an explicit first-run empty state on the launcher: no projects yet, here is how to create one, here is the sample project. Only once that exists, remove the picker card. Order matters — removing the card first strands new users.
Done when:
- a brand-new account with zero projects sees a clear path to create one
- the sample project remains discoverable from the empty state
- the picker card is removed only after the empty state ships
- switching projects still works from the header for users who have projects
T5.3 — B4 surface: pipeline strip
- Items:
B4UI half - Depends on: T4.1, T5.2
- Blocks: nothing
- Surface:
html/ - Files: launcher
Do: Build the four-cell pipeline strip against the server aggregates from T4.1. Each
cell links through to the filtered list, using the URL state from T4.2.
Do not: ship it against localStorage. That is the specific thing B4 warns about.
Done when:
- every number comes from a server endpoint
- each cell links to a filtered view via a shareable URL
- a project with zero work packages renders a sensible empty state, not four zeros that look broken
- the strip announces updates via
aria-liveif it refreshes in place
T5.4 — CR-005: Upload building / floor / sector lists at SOP setup
- Items:
CR-005 - Depends on: T5.1
- Blocks: T6.3
- Surface:
server/+html/ - Files: SOP wizard, server API, schema
Intent: The location taxonomy differs per project. On Micron, floors within B100 behave like separate buildings, so floor and sector are the unit of both execution and cost tracking. Configure it once per SOP rather than hard-coding it.
Do: A wizard step accepting a bulk upload (CSV or paste) of Building / Floor / Sector
values, with the hierarchy preserved. Editable after import: add, rename, deactivate. Store
as structured codes, not display strings — CR-018 needs to group by them.
Deactivating a value hides it from new work packages without breaking existing ones that reference it.
Do not: hardcode floor or building names. The B100 list has not been supplied yet (see
IMPLEMENTATION.md section 8). Seed with obviously-fake sample values.
Done when:
- CSV upload and paste both work and report rejected rows with reasons
- duplicates are detected and reported rather than silently merged
- values are editable after import
- deactivating a value hides it from new work packages; an existing work package referencing it still renders
- values are stored as codes suitable for grouping
- no guessed real-world floor names exist anywhere in the code
T5.5 — CR-006: Section toggles
- Items:
CR-006 - Depends on: T5.1
- Blocks: T5.6, T5.7, T7.2
- Surface:
server/+html/ - Files: SOP wizard, work package renderer, PDF export, creator
Intent: This is the structural fix behind most removal requests in the plan. Rather than deleting fields globally, each project turns on only the sections it uses. It is what lets Micron drop Kitting and Assets while another project keeps them.
Do: In the SOP creation tool, list every work package section with an on/off toggle: General Information, Location, Scope of Work, Assets, Materials, Kitting, Drawings and Attachments, Constraints, QA/QC, Closeout. Default all on for a new SOP.
A section toggled off does not render in the creation form, the detail view, or the PDF export. Data already captured is retained, and toggling back on restores it intact.
Do not: delete data on toggle-off. Ever. And note X4: the creator is an iframe child
until T7.1, so toggle propagation into the creator may need revisiting in wave 7 — test it
and say what you found.
Done when:
- all 10 sections are toggleable
- a section toggled off is absent from the form, the detail view and the PDF export
- toggling off then on restores prior data with no loss
- new SOPs default to all sections on
- toggle state propagates into the creator, or the PR documents exactly where it does not and why
T5.6 — CR-002: Remove Acumatica Cost Code and Task
- Items:
CR-002 - Depends on: T5.5
- Blocks: nothing
- Surface:
html/+server/ - Files: work package form, detail view, PDF export
Intent: The team concluded these are noise on a field work package. Cost codes are
effectively constant and the Acumatica task mapping is a PM concern. The cost visibility they
actually want is by building and floor, which is CR-004 and CR-018.
Do: Hide both fields from the form, the detail view and the PDF export, using the section
or field toggle mechanism from T5.5. Retain the data and the model.
Do not: drop the columns or delete the data. Another project may need these fields, and that is what the toggles are for.
Done when:
- neither field appears in the form, detail view or PDF export for the Micron EUV SOP
- existing records still hold their values; confirm by querying
- the fields can be re-enabled for another SOP without a code change
- no schema migration drops data
T5.7 — CR-016: Assets section off for Micron EUV
- Items:
CR-016 - Depends on: T5.5
- Blocks: nothing
- Surface: configuration
- Files: SOP configuration for Micron EUV
Intent: Asset content duplicates the database Clinton's team maintains. Integration is deferred, so the section comes out in the interim.
Do: Toggle Assets off for the Micron EUV SOP. Leave the section and its data model in the application so the eventual database integration has somewhere to land.
Done when:
- Assets does not render for Micron EUV in the form, detail view or export
- the section and model remain in the codebase
- another SOP can enable Assets and it works
T5.8 — S1 (wizard): Inline validation
- Items:
S1wizard half - Depends on: T5.1
- Blocks: nothing
- Surface:
html/ - Files: SOP wizard validation,
wp-creation-app.js:1144for the pattern to replace
Problem: Validation is alert()-only and validateStep guards only steps 1, 5 and 6,
while the markup marks required fields throughout. The message "Subject and WP Type are
required" names no field, highlights nothing and scrolls nowhere.
Do: Inline validation on every step that has required fields. Errors appear at the field,
the first invalid field receives focus, and the message says what is wrong. Announce via the
aria-live region from T4.5. Remove the wizard's alert() calls.
Do not: add a native alert(), confirm() or prompt() anywhere. The app-wide count
from wave 0 must go down.
Done when:
- every step with required fields validates them
- each error renders at its field and is associated via
aria-describedby - submitting an invalid step focuses and scrolls to the first error
- errors announce to screen readers
- the wizard's native dialog count is 0; record the new app-wide count
Wave 5 exit criteria
- the stepper is keyboard operable and
<div onclick>count dropped by at least 10 - section toggles work end to end, including the export
- Acumatica fields and Assets are hidden by configuration, with no data deleted
- the wizard has no
alert()calls left - first-run users can create a project