101 Commits

Author SHA1 Message Date
270806539c Add ui-structure.md — full UI inventory and widget taxonomy
Covers all 7 nav sections with layout descriptions, all 11 dialog types,
recurring widget patterns (split pane, tabbed view, table, gallery, card,
field editor, modal dialog, non-modal overlay, full-page sub-view, canvas,
lightbox) with every instance listed, complete template inventory (41 entries),
and a primitive taxonomy for a future higher-level UI representation.
Linked from CLAUDE.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 14:18:09 +00:00
5fe7273e35 Update future-plans: dual event bus, UI sub-project boundary, fix duplicate
- Replace simple SSE note with full dual-bus architecture:
  server EventEmitter + client pub/sub, SSE as bridge, effects/ pattern,
  mutation wrapper to avoid wildcard, collection-level event granularity
- Add 'UI as self-contained sub-project' section: composition root pattern,
  main.mjs vs mock-main.mjs entry points, mock-api contract, views-never-
  call-each-other discipline
- Expand app.mjs monolith note to mention mount() export pattern
- Remove duplicate CodeMirror paragraph (copy-paste artifact)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 14:12:28 +00:00
72897c5b2d Add CLAUDE.md — agent orientation file
Covers: file map, KV prefix table, all data model shapes, full API
route index, frontend section layout, image file lifecycle, code style
preferences, git conventions, and a pointer to future-plans.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 13:18:12 +00:00
e2d0079ba0 Make bin editor open to image view; corners editing on demand
- Default view: processed image (full size in dialog), or placeholder if
  not yet processed. Name and type selector always visible at top.
- "Adjust corners…" button reveals the canvas editor (lazy-loaded on
  first click, so there's no canvas allocation cost on open).
- "← Back to image" returns to the image view.
- Corners are only re-processed on Save if the canvas was opened.
- Tabs reduced to Fields | Contents (Corners is no longer a tab).
- Added preview image CSS; btn-link style for the back button.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 13:06:30 +00:00
46ce10289e Wire up fields and contents UI for bins and bin types
- build_field_editor() helper: reusable field row editor shared by
  bin editor, bin type dialog (open_component_dialog still uses its own)
- open_bin_editor: tabs (Corners|Fields|Contents), field editor on
  Fields tab, content list on Contents tab, save always persists fields
- open_bin_type_dialog: field editor appended below existing form fields
- render_bin_contents / open_bin_content_dialog: content item CRUD
  (component ref or free-text name, quantity, notes); add/edit/delete
  update all_bins immediately without closing the editor
- bc-cancel / bc-save handlers registered in init()
- bin-content-row CSS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:37:32 +00:00
33c8ff274e Add tabs, fields section, and contents section to bin editor dialog
- t-dialog-bin-editor: tabs (Corners|Fields|Contents), field rows, contents list
- t-bin-content-row: row template for bin content items
- t-dialog-bin-content: dialog for adding/editing component or free-text items
- t-dialog-bin-type: append field rows section below existing form fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:34:26 +00:00
2b7d50a53d Add fields and contents to bins; fields to bin types
- bins: fields:{} and contents:[] on all new records
- bin types: fields:{} on all new records
- PUT /api/bins/:id accepts fields
- PUT /api/bin-types/:id accepts fields
- POST/PUT/DELETE /api/bins/:id/contents for content items
  (type: 'component'|'item', component_id or name, quantity, notes)
- api.mjs: add_bin_content, update_bin_content, delete_bin_content

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:33:53 +00:00
0319ff7099 Move canvas pan to middle mouse button; left button handles only
Left click now exclusively drags corner/edge handles.
Middle click pans the view. preventDefault on mousedown
suppresses the browser's autoscroll activation on middle click.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:27:12 +00:00
5e2a348b9d Expand duplicate plan to cover all entity types; clarify bins need fields too
- Generalized 'Duplicate bin type' to 'Duplicate any entity' covering
  components, bins, bin types, grids, templates, inventory, source images
- Clarified that bins (not just bin types) should carry generic fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:25:22 +00:00
b0eaf4dc10 Constrain edge midpoint drag to edge normal direction
Instead of applying raw 2D delta, project cursor movement onto the
outward normal of each edge so the edge can only be pushed/pulled
perpendicular to itself. Prevents shearing when dragging a side handle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:23:53 +00:00
046fe99c72 Fix canvas coordinate mismatch and handle jump-on-grab in Grid_Setup
- Canvas width now read via getBoundingClientRect after setting style.width=100%,
  avoiding the parentElement.clientWidth padding issue that made css_w exceed
  the actual rendered width and broke hit-testing
- All handle drags (corners + midpoints) now use relative delta via drag_prev_img
  instead of absolute cursor position, preventing handle teleport on grab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:20:09 +00:00
ede87bb90f Notes: generic fields on bins/bin types, field groups as domain filter, duplicate bin type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:15:38 +00:00
7670db2c6e Note: SSE-based live updates when data changes from any client
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:12:51 +00:00
1aa7350c4d Add maintenance: purge orphaned source image KV entries
When a source image file is deleted without going through the API
(e.g. the old bin delete bug), the KV entry remains and shows a
broken image. The new maintenance action scans all source image
entries, removes any whose file is missing on disk, and reports
how many were cleaned up.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:08:38 +00:00
b200a7ec8d Fix bin delete removing source image
Source images are shared entities managed through the Images gallery.
Deleting a bin should only remove the processed output (image_filename),
not the source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:07:29 +00:00
7e70864907 Note: replace flat prefixed KV keys with hierarchical collection structure
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:06:33 +00:00
090f6f3154 Add bin types: reusable named dimension presets for bins
Bin types store a name, physical W×H in mm, and optional description.
When editing a bin, a type can be selected from a dropdown; this
pre-fills and locks the dimension inputs. Custom dimensions remain
available when no type is selected.

- lib/storage.mjs: bin type CRUD with bt: prefix
- server.mjs: /api/bin-types CRUD routes; type_id accepted on bin
  create/update routes; DELETE protected if any bin references the type;
  type dims copied onto bin when type_id is set
- public/lib/api.mjs: bin type wrappers; rename_bin → update_bin (accepts
  any fields)
- public/templates.html: Types tab in bins section; t-bin-type-row;
  t-dialog-bin-type; type selector in bin editor dialog
- public/app.mjs: all_bin_types state loaded at startup; render_bin_types_list();
  open_bin_type_dialog(); type selector in open_bin_editor(); /bins/types routing
- public/style.css: bin types list styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 03:04:04 +00:00
320c6f1bd9 Add physical dimensions to bin editor for correct aspect ratio
When de-perspectiving a bin photo taken at an angle, inferring the
output size from the quadrilateral shape squishes the result. Entering
real-world W×H (mm) lets the server use the correct aspect ratio,
scaled to the same resolution as the inferred size.

- Bin editor dialog: W×H number inputs, pre-filled from saved phys_w/phys_h
- PUT /api/bins/:id/corners: accepts optional phys_w/phys_h; when provided,
  derives bin_w/bin_h from the physical aspect ratio at equivalent area
- phys_w/phys_h stored on the bin record for re-use on next edit
- future-plans.md: bin types note (reusable dimensions per model)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 05:13:57 +00:00
1ea14f8953 Fix bin editor handle hit-test mismatch
showModal() must be called before load_image() so the canvas has its
correct layout dimensions when parentElement.clientWidth is read.
Calling it after caused css_w to be computed against an unlaid-out
dialog, making drawn handle positions not match hit-test positions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 05:12:16 +00:00
c41fb42e16 Note: split CSS into per-section files with build-step consolidation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 05:06:00 +00:00
871ad7124a Add Images admin section for managing source image uses
New top-level nav section showing all source images in a list view
with checkboxes to edit the uses array (grid, bin) per image. Allows
correcting wrongly-tagged images without code changes.

Server PUT /api/source-images/:id was already in place; re-added the
frontend API wrapper that was prematurely removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 05:04:57 +00:00
53bd086661 Make source-use badges read-only display labels
Removing toggle interactivity from use badges — they were confusing
and the wrong place to manage uses. The uses array is now managed
automatically by upload context. Badges are plain spans.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 04:41:44 +00:00
38c2d89c9b Add tabbed sub-views to bins section, create-bin-from-source flow
Bins section now mirrors the grids section with two tabs:
- Bins: gallery of processed bin records
- Sources: source images tagged with uses=['bin'], with upload and
  '+ Bin' button to create a bin record from an existing source image

Server: POST /api/bins/from-source accepts source_id, creates bin
record and adds 'bin' to the source image's uses array.

URL state: /bins → bins tab, /bins/sources → sources tab.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 04:41:08 +00:00
e183988acb Hide inactive source-use badges
Inactive badges (uses not present on a source image) are now hidden
rather than shown at low opacity, which was visually noisy and
confusing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 04:30:37 +00:00
28b4590903 Add bins feature: upload, de-perspective, gallery
- lib/storage.mjs: bin CRUD with bin: prefix
- lib/grid-image.mjs: compute_bin_size() capped at 1024px
- server.mjs: POST/GET/PUT/DELETE /api/bins routes; PUT /api/bins/:id/corners
  re-processes image via process_grid_image with rows=1 cols=1
- public/lib/api.mjs: bin API wrappers including upload_bin()
- public/index.html: Bins nav button
- public/templates.html: t-section-bins, t-bin-card, t-dialog-bin-editor
- public/app.mjs: render_bins(), open_bin_editor() using Grid_Setup,
  save/cancel wiring in init()
- public/style.css: bin gallery and card styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 04:28:03 +00:00
f370b6d48d Fix kv-store load to use try/catch instead of existsSync
Replace check-then-read with read-and-catch-ENOENT. The existsSync
pattern is redundant and slightly misleading; other errors still
propagate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 04:27:55 +00:00
67369b56be Add edge midpoint drag handles to Grid_Setup
Drag indices 4-7 correspond to top/right/bottom/left edge midpoints.
Dragging a midpoint applies the delta to both adjacent corners, making
it easier to align bins with rounded corners where corner handles may
be obscured.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 04:27:35 +00:00
80a2fabf7d future-plans: type field approach for item types, bulk migration strategy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 03:38:02 +00:00
e83d3978b0 future-plans: bins as items, inventory type-specific views
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 03:36:51 +00:00
34dc1d441c future-plans: search should also match on field names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 00:42:03 +00:00
6874b9482a future-plans: multi-user, team permissions, shared auth library
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 21:10:16 +00:00
55f8766176 future-plans: image gallery with drag-drop, paste, URL, and shared images
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 20:47:11 +00:00
2405be6a66 future-plans: semantically-aware formatting for acronyms and proper names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 00:00:03 +00:00
5ac980c9fa future-plans: unified formatter→renderer pipeline and terminology revision
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:53:53 +00:00
a6bd340d81 future-plans: rich return values from templates (slots, not just strings)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:51:56 +00:00
eeb77babbb future-plans: use CodeMirror 6 for JavaScript input fields
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:25:55 +00:00
5681d5f024 future-plans: migrate to integer IDs via explicit safe migration tool
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:06:24 +00:00
210fb1e037 future-plans: component IDs in dropdowns, user-assignable short IDs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:04:57 +00:00
110e17e972 future-plans: sort component list by display name
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:03:53 +00:00
84dc06f365 future-plans: custom field input modes (e.g. SMD codes vs direct entry)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:55:34 +00:00
7265b5bb2c future-plans: recent locations, field keyboard shortcut, explicit save button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:50:44 +00:00
27bf6043d3 future-plans: clarify logical cell grouping is for batch overflow, not large components
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 00:24:59 +00:00
1bebf7a12b future-plans: irregular grid layouts, merged cells, stacked sub-grids
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 00:22:47 +00:00
85170d4b50 future-plans: read-only public mode via runtime flag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 23:19:00 +00:00
94b20dda6b future-plans: grid view layers with separate source images
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 15:38:41 +00:00
88cc71b7d3 future-plans: custom saved search views with JS expressions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 15:35:04 +00:00
06b2691d87 future-plans: multi-cell grid storage selection
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 15:33:35 +00:00
956f168578 future-plans: auto-select uploaded file in file picker
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 15:31:02 +00:00
07dbb6261e future-plans: store measurement as {value, prefix, unit}, canonical only for queries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 15:05:10 +00:00
a17bafb6d3 future-plans: clarify SI prefix vs unit distinction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 15:03:33 +00:00