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:
297
docs/waves/wave-7.md
Normal file
297
docs/waves/wave-7.md
Normal file
@@ -0,0 +1,297 @@
|
||||
# Wave 7 — The creator
|
||||
|
||||
**Items:** `B7`, `A1`, `CR-015`, `A2`, `A6`, `CR-014`, `CR-007`, `B6`, `S1` (creator), `F6`
|
||||
**Depends on:** wave 6 merged, and `T4.2` (URL state) merged
|
||||
**Why last among the build waves:** most of it depends on the iframe decision, and `CR-014`
|
||||
depends on `X1`.
|
||||
|
||||
`T7.1` is the largest engineering item in the plan. Decided and approved: the iframe gets
|
||||
dissolved. Do it first — everything after it is cheaper on the far side.
|
||||
|
||||
---
|
||||
|
||||
### T7.1 — B7: Dissolve the creator iframe
|
||||
|
||||
- **Items:** `B7`
|
||||
- **Depends on:** T6.5
|
||||
- **Blocks:** T7.2 through T7.9
|
||||
- **Surface:** `html/`
|
||||
- **Files:** parent page hosting the creator, the creator itself, cross-frame messaging
|
||||
|
||||
**Problem:** The tab row lives in the parent and the toolbar lives in the iframe child, so
|
||||
folding one into the other is impossible while the boundary exists. The boundary is also
|
||||
implicated in `F4` and possibly in `CR-006` toggle propagation (`X4`).
|
||||
|
||||
**Do:** Remove the iframe boundary so the creator renders in the parent document. Expect to
|
||||
untangle: cross-frame messaging, duplicated styling, focus and scroll management, and
|
||||
anything relying on separate document contexts.
|
||||
|
||||
Do this as its own PR with no feature work attached. It will be large and it needs to be
|
||||
reviewable as a structural change.
|
||||
|
||||
**Do not:** bundle any other item into this task, and do not leave a dormant iframe path
|
||||
behind a flag.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] no iframe remains in the creator; grep confirms
|
||||
- [ ] every creator feature works as it did before: verify against the wave 0 baseline screenshots and a functional pass
|
||||
- [ ] `F4` no longer reproduces
|
||||
- [ ] `CR-006` section toggles propagate into the creator with no special-casing
|
||||
- [ ] browser back and forward still behave with the `T4.2` URL state
|
||||
- [ ] no cross-frame messaging code remains
|
||||
|
||||
---
|
||||
|
||||
### T7.2 — F6 + A4 pattern: Section tabs replace the 4,700px form
|
||||
|
||||
- **Items:** `F6`
|
||||
- **Depends on:** T7.1, T5.5, T3.5
|
||||
- **Blocks:** T7.9
|
||||
- **Surface:** `html/`
|
||||
- **Files:** creator layout, jump links
|
||||
|
||||
**Problem:** The creator is one form roughly 4,700px tall with 11 cards rendered at once and
|
||||
jump links standing in for structure.
|
||||
|
||||
**Do:** Give the form real structure — section tabs or an equivalent that shows one coherent
|
||||
group at a time. Respect the `CR-006` toggles: a section toggled off has no tab. Retire the
|
||||
jump links. Section identity belongs in the URL (`T4.2`) so a section is linkable.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] no single view exceeds roughly two screen heights at 1440px
|
||||
- [ ] toggled-off sections have no tab
|
||||
- [ ] each section is addressable by URL and survives refresh
|
||||
- [ ] jump links are gone
|
||||
- [ ] tabs are keyboard operable and follow the tab pattern with `aria-selected` and arrow keys
|
||||
- [ ] unsaved work is preserved when moving between sections (`T4.3`)
|
||||
|
||||
---
|
||||
|
||||
### T7.3 — A1 + CR-015: Guarded transitions and the hold bug
|
||||
|
||||
- **Items:** `A1`, `CR-015`
|
||||
- **Depends on:** T7.1
|
||||
- **Blocks:** T7.4, T7.6
|
||||
- **Surface:** `server/` + `html/`
|
||||
- **Files:** status handling, constraint handling, `wp-creation-app.js:1962-1972`
|
||||
|
||||
**This is one task, not two (`X2`).** The hold-not-clearing bug and the transition model are
|
||||
the same code. `CR-015` is the highest-severity item in the plan and it was reproduced live
|
||||
in front of the Micron team.
|
||||
|
||||
**Problem:** Clearing all constraints does not clear the hold. Hold state is not purely
|
||||
derived from open constraints, which is why it goes stale.
|
||||
|
||||
**Do:** Model transitions explicitly. For each state, define the primary next action **plus
|
||||
an audited override**. "One legal next action" is too narrow — `wp-creation-app.js:1962-1972`
|
||||
contains a deliberate logged-override path for predecessors, and Issue (Hold) is a branch
|
||||
from several states, not a single linear step.
|
||||
|
||||
Derive hold state from open constraints rather than storing it independently, or if it must
|
||||
be stored, recalculate it on every constraint change. Write every hold and release to the
|
||||
work package history with timestamp, user and reason.
|
||||
|
||||
**Do not:** remove the logged-override path. It is an audited business rule. And do not fix
|
||||
the symptom by recalculating on page load only.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] clearing the last open constraint clears the hold and returns the work package to its prior status, with no refresh
|
||||
- [ ] logging a new constraint on an in-progress work package places it back on hold
|
||||
- [ ] clearing that constraint releases it again
|
||||
- [ ] the override path still works and still logs
|
||||
- [ ] Issue (Hold) is reachable from every state it should branch from
|
||||
- [ ] every hold and release is in the history with timestamp, user and reason
|
||||
- [ ] a regression test covers the clear-last-constraint path specifically
|
||||
- [ ] the exact root cause is stated in the PR
|
||||
|
||||
**Why the history matters:** the delay-documentation use case is the business justification
|
||||
for the whole constraint workflow. If a constraint log can be shown to have been wrong, it
|
||||
stops supporting a notice of delay or a change order claim.
|
||||
|
||||
---
|
||||
|
||||
### T7.4 — A2: De-duplicate the constraint warning
|
||||
|
||||
- **Items:** `A2`
|
||||
- **Depends on:** T7.3
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `html/`
|
||||
- **Files:** creator constraint warnings
|
||||
|
||||
**Problem:** The same warning appears three times.
|
||||
|
||||
**Do:** Keep one. The top banner is the only one visible without scrolling, so it stays. The
|
||||
tab count badge then has to carry the weight the removed duplicates were carrying — make the
|
||||
count prominent enough to notice from any section.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] the warning appears once
|
||||
- [ ] the tab badge shows the open constraint count and is legible at 390px
|
||||
- [ ] with the constraints section scrolled out of view, a user can still tell constraints are open
|
||||
- [ ] the banner announces via `aria-live` when the count changes
|
||||
|
||||
---
|
||||
|
||||
### T7.5 — A6: Sidebar triage data and inline hold reason
|
||||
|
||||
- **Items:** `A6`
|
||||
- **Depends on:** T7.3
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `html/`
|
||||
- **Files:** creator sidebar
|
||||
|
||||
**Do:** Surface triage data in the sidebar, including the hold reason inline. The hold reason
|
||||
is already captured by the hold modal, so this is display work.
|
||||
|
||||
**Use case to test against:** someone in a stand-up is asked why a package has not moved.
|
||||
They open it on a phone and need the answer without scrolling or clicking.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] the hold reason is visible in the sidebar without opening the modal
|
||||
- [ ] status, priority, due date, P6 activity and open constraint count are all visible together
|
||||
- [ ] usable at 390px
|
||||
- [ ] a package with no hold shows a sensible state rather than an empty slot
|
||||
|
||||
---
|
||||
|
||||
### T7.6 — CR-014: Ready for QA gate
|
||||
|
||||
- **Items:** `CR-014`
|
||||
- **Depends on:** T7.3, T4.2 (blocking dependency `X1`)
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `server/` + `html/`
|
||||
- **Files:** status model, notification service, QA section
|
||||
|
||||
**Intent:** Looping QA in has historically been the failure point. Marlena raised this
|
||||
directly: QA needs to see inbound work and organize their schedule ahead of time rather than
|
||||
being told after the fact.
|
||||
|
||||
**Do:** Add `Ready for QA` between In Progress and Complete/Closed, inside the `T7.3`
|
||||
transition model (`X3`). Entering that state emails the assigned QA representative and the
|
||||
QA/QC members named on the work package.
|
||||
|
||||
The email includes the work package number and title, location, a scope summary, and **a
|
||||
direct link that opens that work package** — this is why `T4.2` is a hard prerequisite. A
|
||||
dashboard view lists everything sitting in Ready for QA. The QA representative can accept or
|
||||
reject; rejection returns the package to In Progress with a required comment.
|
||||
|
||||
**Do not:** build the email with a link to the app root. That is the failure `X1` exists to
|
||||
prevent.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] the new state exists in the transition model, not beside it
|
||||
- [ ] entering it sends email to the QA rep and named QA/QC members
|
||||
- [ ] the link in the email opens that specific work package, including for a signed-out recipient via login
|
||||
- [ ] a dashboard view or filter lists all packages in Ready for QA
|
||||
- [ ] rejection returns to In Progress and requires a comment
|
||||
- [ ] the transition is written to history
|
||||
- [ ] email failure is logged and surfaced, not silent
|
||||
|
||||
**Note:** QA currently runs off a comprehensive Excel questionnaire being migrated into
|
||||
CxAlloy. Integration with CxAlloy is explicitly out of scope. This gate is notification only.
|
||||
|
||||
---
|
||||
|
||||
### T7.7 — CR-007: Upload drawings for offline access
|
||||
|
||||
- **Items:** `CR-007`
|
||||
- **Depends on:** T7.2, T4.3 (blocking dependency `X8`)
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `server/` + `html/`
|
||||
- **Files:** Drawings and Attachments section, file storage, export
|
||||
|
||||
**Intent:** Today the section holds links, typically to a Bluebeam session. The field wants
|
||||
the specific PDF attached instead: a general foreman opens the package and sees exactly the
|
||||
sheet and the highlighted section relevant to their scope, with no navigation and no
|
||||
connectivity dependency. Links stay supported for those who want them.
|
||||
|
||||
**Do:** File upload alongside the existing link support. Store files with the work package.
|
||||
Include them when the package is exported or downloaded. Make them available offline on a
|
||||
tablet. Each attachment gets a short description field so the creator can note the focus
|
||||
area, for example "Tray section, Level 3 east only".
|
||||
|
||||
Show file size limits and supported types in the UI before upload, not after failure.
|
||||
|
||||
**Do not:** build this before `T4.3`. Uploading into a form with no autosave risks losing
|
||||
both the upload and the surrounding work.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] PDF upload works and the file is retrievable
|
||||
- [ ] links still work alongside uploads
|
||||
- [ ] attachments are included in export or download
|
||||
- [ ] an uploaded drawing opens on a tablet with the network disabled
|
||||
- [ ] the description field persists and prints on the export
|
||||
- [ ] limits and supported types are stated before upload
|
||||
- [ ] upload failure is clear and recoverable, with no loss of surrounding form work
|
||||
- [ ] the whole flow works at 390px
|
||||
|
||||
**Accepted tradeoff:** this shifts effort onto the package creator to isolate the right
|
||||
sheet. That was raised in the meeting and accepted.
|
||||
|
||||
---
|
||||
|
||||
### T7.8 — B6: Sticky action bar
|
||||
|
||||
- **Items:** `B6`
|
||||
- **Depends on:** T7.2
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `html/`
|
||||
- **Files:** creator and wizard action bars
|
||||
|
||||
**Problem:** The proposal placed actions beside the fields, but on the Constraints and
|
||||
Sequence steps that means scrolling to save.
|
||||
|
||||
**Do:** A sticky action bar instead. The creator already solves this; reuse that pattern in
|
||||
the wizard rather than inventing a second one.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] save and primary actions are reachable without scrolling on every step and section
|
||||
- [ ] verified specifically on Constraints and Sequence
|
||||
- [ ] the bar does not obscure fields at 390px
|
||||
- [ ] it shows the save state from `T4.4`
|
||||
|
||||
---
|
||||
|
||||
### T7.9 — S1 (creator): Inline validation
|
||||
|
||||
- **Items:** `S1` creator half
|
||||
- **Depends on:** T7.2
|
||||
- **Blocks:** nothing
|
||||
- **Surface:** `html/`
|
||||
- **Files:** creator validation, `wp-creation-app.js:1144`
|
||||
|
||||
**Problem:** 43 native dialogs in the creator alone. `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.
|
||||
|
||||
**Do:** Inline validation matching the wizard pattern from `T5.8`. Errors at the field, focus
|
||||
and scroll to the first invalid one, and with section tabs now in place, the tab containing
|
||||
errors is marked. Remove the creator's native dialogs.
|
||||
|
||||
**Done when:**
|
||||
|
||||
- [ ] no `alert()`, `confirm()` or `prompt()` remains in the creator; count is 0
|
||||
- [ ] every required field validates inline
|
||||
- [ ] submitting focuses and scrolls to the first error, switching sections if needed
|
||||
- [ ] sections containing errors are marked in the tab row
|
||||
- [ ] errors announce via `aria-live`
|
||||
- [ ] the app-wide native dialog count is recorded against the wave 0 baseline of 79
|
||||
|
||||
---
|
||||
|
||||
## Wave 7 exit criteria
|
||||
|
||||
- [ ] no iframe; `F4` resolved structurally
|
||||
- [ ] `CR-015` fixed with a regression test and a stated root cause
|
||||
- [ ] hold state is derived, and history records every transition
|
||||
- [ ] the QA gate emails a working deep link
|
||||
- [ ] drawings upload and open offline on a tablet
|
||||
- [ ] creator native dialog count is 0
|
||||
Reference in New Issue
Block a user