Files
design-v3/iteration-3/00-changes.md
T
Joshua KingandClaude Opus 5 d9ed1898b9 Add the Extrudex Design System v3 bundle
Tokens (light + dark, neumorphism, 54/54 WCAG AA contrast pairs), the
self-hosted JetBrains Mono fonts, and interactive mockups of every screen
across three iterations. Iteration 3 is final: phone, tablet and desktop
tiers, device preview, and "empty spool weight" terminology. The build
scripts regenerate the screens byte-identically from source.

Implementation is tracked in Maestro feature UI Refresh - V3.0
(224b72a1-8d84-4970-97ea-5dafa4d8ea3b).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 11:31:50 -04:00

11 KiB
Raw Blame History

Iteration 3: the remaining screens, plus tablet and phone

2026-09-18. Built on iteration 2 (left unchanged in ../iteration-2/). Same v3 tokens, same shared panel/palette/toast system. Start at screens/index.html (flow map, 14 guided flows) or screens/devices.html (every screen in live phone, tablet-portrait and tablet-landscape frames).


1. Your answers, applied

Question Your answer What changed
One-click suggestion Fine if accurate; fixable by hand Kept one click. Every attributed print now has Change spool in its panel, and it states the real effect: "46 g goes back to Elegoo Black #42 and comes off the spool you pick; cost is re-rated." (That's what SetPrintSpool does on dev.) Rows attributed before deductions were tracked get the real refusal: reconcile to the same spool first (see print Test_cube).
Weigh-session order By weight, with location visible The session always runs lightest first, whatever the table sort. Each step opens with a "Find it: Shelf C" strip and "spool 2 of 4 · lightest first".
Landing page Dashboard Unchanged.
Filament badge Yes: it flags an assumed weight that could be off Filament [7] badge = empty spool weight unverified: 3 unknown + 4 estimated (Generic 180 g, Refill 35 g). Its tooltip splits the two. The saved view is renamed Empty spool weight unverified, and the Dashboard item reads "7 spools have an unverified empty spool weight: 3 can't be weighed yet, 4 could be off."
Palette commands Makes sense load ‹spool› into ‹holder› and attribute ‹print› to ‹spool›. They're typed in stages: the list narrows to spools or prints, then to holders or spools. Full holders show "full · 4/4" and refuse. Two new actions in the empty palette prefill them.

Check my reading of 4a. I took "identifies an assumed weight" to include estimated empty spool weights, not just unknown ones. If you meant unknown only, it's a one-line change and the badge drops to 3.


1b. Terminology: "empty spool weight", not "tare" (changed 2026-09-18)

"Tare" isn't how the 3D printing community talks, so every user-facing string now says empty spool weight. The short form empty spool is used only where space is tight: column headers, and the scale equation "262 g empty spool

  • 812 g filament = 1,074 g". Examples:
Was Now
Tare unverified (view) Empty spool weight unverified
Empty spool (tare) Empty spool / Empty spool weight
tare unknown empty spool weight unknown
Set a tare · Save tare Set empty spool weight · Save empty spool weight
Remaining = reading − 140 g tare Remaining = reading − 140 g empty spool
Brand tare Brand empty spool weight

Not changed: code and API names (tare_grams, tare_source, effective_tare_grams, tare_origin). Renaming those would be an API break for no user benefit. CTXD's GLOSSARY.MD still defines "Tare"; I haven't edited CTXD (read-only for this task). You may want to add "empty spool weight" there as the user-facing term.

Iterations 1 and 2 still say "tare"; they're kept as snapshots.


2. New screens

Screen Who What it's for Built from on dev
05 Lists operator+ The 5 name-part lists + spool types. A name bar shows which part you're editing ("Sunlu Rapid PETG CF Silk"). "Used by N spools" links to Filament filtered. Remove is disabled with the reason when in use. Spool types show empty spool weight + trust level; adding one enforces "weight and source together, never 0 g". Demos: rename conflict (409), add error. ManageLookups.tsx, lookup store rules
06 Labels operator+ Queue of spools without a label (preselected) → one PDF. Previews at the real 51 × 21 mm layout (19 mm QR · Brand / Color · taxonomy · #id). Tabs: all spools (reprint), holders (per-printer holder labels that start scan sessions). A format reference is included. labels.go, /api/spool-labels/unprinted, /api/filament-containers/{id}/label
07 Access admin Authentik owns people and roles; Extrudex shows its local view. Role cards (reader / operator / admin, from the route policy). People with sessions (idle and hard expiry) and Revoke… with an inline confirm. Machines & API tokens: new token shown once (exd_…), per-token revoke. AccessAdministration.tsx; machines/tokens have API but no screen on dev
08 System admin Low-filament report: schedule, threshold, weekly delivery history (retries, errors), Run this week's now. Audit log: who/what/when with links to the thing changed, filters, paging. This device: install, update-ready, offline readiness. webhook.go, audit.go, PWAControls.tsx; webhook and audit have API but no screen on dev
09 Scan: holder (/c/:id) phone-first Scan a holder label → a session for this tab. Each spool scanned loads (from storage), returns (already here) or moves here (from another holder). No mode picker. Full → refused, nothing changes. Result card + haptic, a session log, "Done scanning". Camera sheet (demo) + type-a-number fallback. Reader view shows contents only. ScanSession.tsx, ScannedSpoolRoute
10 Scan: spool (/s/:id) phone-first A spool label scanned with no holder session active: big remaining, Lives in, one-handed weigh-in (68 px input, before → after, the same two refusals), then open its holder or full details. Empty spool weight unknown → pick a spool type first. ScanWeighSpool.tsx
Printer panels (on Printers) admin Add / edit printer (brand filters models from printerCatalog.ts; access code write-only; Elegoo has none), Manage holders (add AMS/AMS Lite, the external holder can't be removed, loaded holders can't be removed, print holder label), Remove printer (type the exact name). PrinterForm.tsx, ManagePrinterContainers.tsx, ConfirmRemovePrinter.tsx
Devices — Every screen in 3 live frames, dark/light. —

The nav now reaches everything: Manage (Lists, Labels, Access, System) on the rail, and a More tab on phones.


3. Things I checked against the code (and corrected in the design)

Claim I almost made What dev actually does Design now says
"Run the report again resends it" A delivered week returns its existing result; only a retrying week is retried (runPeriod) "Already delivered Monday 08:00; nothing was sent again. Running it never sends a duplicate."
"Remove printer, and history is kept" Also refused while any holder still has spools, and an open print is settled as unknown Both shown in the remove panel; confirm disabled while loaded
Re-attributing a charged print is blocked Allowed: grams are returned to the old spool and taken from the new one, except rows from before tracking (ErrUnreconciledAttribution) "Change spool" with the exact effect, and the real refusal
Scanning a spool label always opens it Only with no holder session active; otherwise it's loaded/moved into the active holder Both routes designed; each page explains the other
Sample token ctxd_… Extrudex tokens are exd_… Fixed

Two findings for you (not design changes):

  1. List names are case-sensitive in the schema (UNIQUE, no COLLATE NOCASE), so "petg" can be added beside "PETG", which is the very problem the lists exist to prevent. The Lists screen shows a proposed near-duplicate warning, labeled as a proposal.
  2. Audit log, low-filament report and machine tokens have APIs but no screens on dev. They're designed here and tagged "API exists · no screen on dev yet".

4. Responsive specification

Phone < 700 px Tablet 700–1180 px Desktop > 1180 px
Navigation Bottom bar: Dashboard · Filament · Prints · Printers · More (sheet with Manage + theme), badges on icons Compact rail (88 px): icon + label, badges top-right, Manage group Full rail with labels, Manage group, theme switch
Search "Search…" pill, no shortcut hint Full placeholder; shortcut hint hidden on touch Full placeholder + ⌘K
Primary action Floating + (56 px) above the bar Header button Header button
Panel Full-screen sheet 480 px side sheet over the page 520 px side sheet
Tables Low-priority columns dropped (hide-m); Lists become stacked rows Tablet-only drops (hide-t): Value, Cost, Use; Weigh becomes icon-only All columns
Touch 44 px+ targets; menu items 12 px padding; pointer: coarse rules Same pointer: coarse rules Mouse sizes, keyboard hints
Scan pages Designed for this: 64 px scan button, 68 px scale input, haptic on result Centered 560 px column Centered 560 px column
Dashboard One column; attention buttons full-width One column below 980 px, two above Two columns
Printers One card per row 2 per row (portrait 1, landscape 2) 3 per row

5. New open questions

  1. Empty spool weight badge scope. Unknown + estimated (as built), or unknown only? See §1.
  2. Near-duplicate list names. Add a case-insensitive uniqueness check (a schema change plus migration), or only warn in the UI?
  3. Holder scan session end. dev keeps the active holder for the browser session. Is an explicit Done scanning (as designed) wanted, and should it also time out after a few minutes idle?
  4. Machine tokens, audit log, low-filament report. Worth building screens for all three now, or keep them API-only until something needs them?
  5. Label printing. Always PDF download, or is there a specific label printer you'd want a direct-print path for?

6. More implementation tasks (titles only, smallest first)

  1. Rename the "Tare unknown" view to "Empty spool weight unverified" and include estimated weights
  2. Add a Filament nav badge for unverified empty spool weights
  3. Always run weigh sessions lightest first
  4. Show the spool's location at the top of the weigh step
  5. Add "Change spool" to attributed prints, stating the returned grams
  6. Show the unreconciled-attribution refusal with its fix
  7. Add a case-insensitive near-duplicate warning to Lists
  8. Show "Used by N spools" with a link on every list value
  9. Add label previews at 51 × 21 mm proportions
  10. Add holder labels to the Labels screen
  11. Add the "load … into …" palette command
  12. Add the "attribute … to …" palette command
  13. Add a More tab and sheet to the phone navigation
  14. Add the compact tablet rail (700–1180 px)
  15. Add a Manage holders panel with the removal rules
  16. Add "Remove printer" with name confirmation and the loaded-holders refusal
  17. Add a "Done scanning" control to holder scan sessions
  18. Add the phone weigh-from-label layout
  19. Add an audit log screen over GET /api/admin/audit
  20. Add a low-filament report screen over the webhook endpoints
  21. Add a machine and API token screen with show-once tokens