Commit Graph

142 Commits

Author SHA1 Message Date
grokbot_ty 3936c575b2 feat(photos): apply frozen mask to batch siblings after Calculate (#62)
After calibration Calculate, reuse approved sheet/sensitivity on non-calibration
photos via the mask worker + inventory compose. Persist per-photo ok/error on
measure.batchApply and the device draft for #64; leave Mask UI unopened and keep
scale/widths/sqft/bdft on the calibration results only.
2026-09-15 21:24:10 +00:00
grokbot_ty 9404d0130c test(photos): batch apply approved mask after Calculate (#62)
Prove frozen calibration mask reuse, per-photo errors, inventory PNG results, calibration-only measures, draft persistence, and no Mask re-prompting for batch siblings.
2026-09-15 21:20:35 +00:00
grokbot_ty 8ff008f85c feat(photos): keep M1 mask/axis/measure on calibration pick (#61)
Document single-source M1 path after pickCalibration: Mask/Axis/Measure/
Calculate use the chosen Source only; batch siblings stay draft-untouched
until #62 apply. Tag encode-fallback inventory Blob as image/png (CAPTURE.md).
2026-09-15 21:14:16 +00:00
grokbot_ty d2ffa4cad2 test(photos): M1 mask/axis/measure on calibration pick (#61)
Proving tests: after pick of index N≠0, Mask→Axis→Measure operate on that
blob only; Calculate yields inventory PNG + M1 numbers; other batch photos
stay in draft.batch untouched; resume through measure restores calibration
source. FakeWorker drives the path in Node. No production change yet (TDD).
2026-09-15 21:14:00 +00:00
grokbot_ty d18b96c10b feat(photos): pick calibration photo before Mask (#60)
Add pickCalibration state/UI over batch thumbs. Continue from batch opens
pick (including single-photo confirm). User pick enters M1 Mask on that
Source only; draft stores calibrationIndex. Removes first-photo proxy.
2026-09-15 21:11:07 +00:00
grokbot_ty 4fa8126471 test(photos): pick calibration before Mask (#60)
Failing session/UI tests for M2-3: Continue → pickCalibration (not
first-photo Mask proxy), user pick enters Mask on that Source, draft
remembers calibrationIndex, Resume restores. No production change yet (TDD).
2026-09-15 21:10:14 +00:00
grokbot_ty ff4bb0f31e feat(photos): multi-photo batch + device draft (#59)
Replace single Add photo with Batch: accumulate 1–N photos, Continue
when ≥1 (M1 bridge: mask on first), persist batch blobs in the device
draft, Resume Continue restores. Keeps Mask/Axis/Measure intact.
2026-09-15 21:08:44 +00:00
grokbot_ty e919fe9a35 test(photos): batch add + draft restore before green (#59)
Failing session/UI tests for M2-2: multi-photo batch state, Continue
when ≥1, device-draft persistence of batch blobs, Resume Continue
restores. No production change yet (TDD).
2026-09-15 21:07:17 +00:00
grokbot_ty ab5bdafbd8 docs(m2): #58 EXIF bottom + Photos-ready lineup order
Lock Ty’s decisions: width stations start 6in from EXIF-oriented
photo bottom along the approved length axis; lineup is clean cal,
dimension overlay, then other batch PNGs in capture order.
2026-09-15 21:04:16 +00:00
grokbot_ty 2eb825c84e test(fixtures): add Ty matched slab photo sets for M2
Set1 L=48in thickness=2in (2 faces); set2 L=31in thickness=2.5in
(2 faces). Black-sheet samples for Playwright and calibration TDD.
2026-09-15 20:54:51 +00:00
grokbot_ty 4ab68d6b68 docs(m2): lock Photos milestone — batch, calibrate, overlays
Record Ty's narrowed M2 scope on m2-ds: multi-photo batch, pick
calibration, reuse M1 mask/crop, lined-up inventory PNGs, and
axis-oriented dimension overlay copy. Not taxonomy or Woo create.
2026-09-15 20:37:46 +00:00
grokbot_ty eaedcb53dd fix(capture): drop first and last 6in from width samples
sampleWidths used floor(L/6)+1 stations from t=0, so tapered tips
dominated min/max. Sample only interior stations at 6, 12, … ≤ L−6.
When L≤12 there is no interior span: every6In stays empty and
min/max/avg stay 0. CAPTURE.md Widths bullet matches.

sqft, bdft, scale, and inventory PNG are unchanged.
2026-09-15 03:20:28 +00:00
grokbot_ty 11c8124674 test(capture): expect tip-trimmed every-6in width stations
Ty UAT: width min/max must describe bulk, not tips. Pin L=48 tapered
case (7 interior stations, no tip endpoints), uniform mid-board count,
and L≤12 empty/zero fallback before the sampleWidths change lands.
2026-09-15 03:20:17 +00:00
grokbot_ty 44d428b6f4 fix(capture): lower inventory PNG floor to 800px
Product call for the WooCommerce redo. Calculate accepts
sources whose post-crop shorter side is at least 800px.
Warn copy and CAPTURE.md match. No upscale still holds.
2026-09-14 23:40:02 +00:00
grokbot_ty f20d84c543 test(capture): expect 800px inventory PNG floor
Ty UAT rejected phone photos under the 1600px bar.
Lock the mid-band case (shorter side 1000) and floor
geometry at 800×1067 / 0.8×800=640 before the code change.
2026-09-14 23:40:01 +00:00
grokbot_ty fbcd05169f fix(capture): apply approved mask alpha in inventory PNG
Why
CAPTURE.md Crop keeps slab pixels and makes removed pixels transparent.
encodeInventoryPng only drawImage-cropped the AABB from the raw photo.

Scope
composeInventoryFrame samples the source through approvedMask.bitset.
Non-slab pixels stay alpha 0. Drop the 8% MARGIN; fill 80% of mask
extents in a 3:4 frame. Floor rules unchanged.

Verification
cd frontend && npm test
12 pass, including alpha contract (no sheet green in opaque pixels).
2026-09-14 19:11:52 +00:00
grokbot_ty b3a9fdf330 test(capture): require mask alpha in inventory PNG compose
Why
Calculate showed accurate numbers but the inventory PNG kept the sheet
background. Measure already uses approvedMask.bitset; encode did not.

Scope
Add composeInventoryFrame and inventory.test.ts alpha/crop proofs.
Wire encodeInventoryPng({ bitmap, mask, source }) at calculate().
This commit still paints the slabBounds AABB without the bitset gate so
the alpha contract fails until the follow-up fix.

Verification
node --import tsx --test src/png/inventory.test.ts
alpha contract fails (sheet green leaks); 3:4 / 80% / floor pass.
2026-09-14 19:11:52 +00:00
grokbot_ty 114e0b5116 fix(capture): type Length L and Thickness as inch inputs
Replace MeasurePanel steppers with number inputs. Commit on blur, change,
and Calculate snaps inches to nearest 1/8 via inToEighths. Calculate
enables when both drafts parse to > 0. Axis, mask, and scale math unchanged.
2026-09-14 18:26:31 +00:00
grokbot_ty 81e9184c7f test(capture): require typed Measure length and thickness inputs
Ty UAT rejects ± steppers as the only Length L / Thickness control.
Assert MeasurePanel exposes type=number inputs and that inches snap via inToEighths.
2026-09-14 18:26:31 +00:00
grokbot_ty b328871549 fix(capture): rotate length-axis rectangle and scale from mask span
Length axis keeps the approved mask, replaces Flip 180 with a ± angle
slider, and sets scale from wood span along the approved direction rather
than bbox.longSidePx. Widths still sample every 6 in perpendicular to that
axis.
2026-09-14 16:37:00 +00:00
grokbot_ty b781ffeb66 fix(capture): preserve PhotoStage preview aspect on first paint
Contain-fit waits for a real parent width, uses ResizeObserver, and shrinks
width when maxH would otherwise stretch the CSS box. Pure fitDisplay is
covered by node tests.
2026-09-14 16:37:00 +00:00
grokbot_ty 0e94b1fd2a fix(capture): offer camera and gallery on Add photo
Why
On phone, the single file control opened the camera because it set
capture=environment. CAPTURE.md requires camera or picker.

Scope
AddPhoto.svelte now has Take photo (capture=environment) and Choose
from gallery (no capture). Both call the same onPicked path.

Verification
Playwright against overnight after redeploy asserts two inputs and
gallery has no capture attribute.
2026-09-14 15:23:08 +00:00
grokbot_ty c6a48c8d91 deploy: overnight M1 UAT on ubudual :10881 2026-09-14 15:12:30 +00:00
grokbot_ty 0679e1cef7 deploy: keep overnight M1 UAT on box :18080
ubudual :10880 is Ty local Node/SvelteKit — do not overwrite.
2026-09-14 15:10:03 +00:00
grokbot_ty 503449452c deploy: pin M1 UAT to ubudual5060:10880 2026-09-14 15:03:47 +00:00
Ty bb78e35ac3 docs: name crop as Calculate step — 3:4, 80% fill, transparent PNG 2026-09-14 14:16:41 +00:00
grokbot_ty d86fc93ed6 feat(capture): ship Milestone 1 browser capture app
Why
Phone and PC need a single capture flow that ends at inventory PNG and
board-foot numbers with no backend, inference, or Woo create.

Scope
Add frontend/ Vite+Svelte capture UI with Resume, Add photo, Mask,
Length axis, and Measure. Mask runs in a worker with Auto/Green/Black
and a 2.0s sensitivity debounce. Measure computes scale, widths, sqft,
bdft, and a 3:4 alpha inventory PNG. Persist one device draft in
IndexedDB. Serve the static build from frontend/Dockerfile via nginx
(deploy/nginx-m1.conf). No FastAPI.

Verification
sudo docker build -f frontend/Dockerfile -t slabuploader-m1 .
sudo docker run -d --name slabuploader-m1 -p 0.0.0.0:18080:80 slabuploader-m1
curl http://127.0.0.1:18080/ returns 200
Playwright: synthetic green-sheet photo through Calculate shows sqft/bdft
2026-09-14 07:53:39 +00:00
Ty 3bae76cea3 docs: Calculate runs measure after length and thickness 2026-09-11 15:16:14 +00:00
Ty 74bd8b2863 docs: restore Milestone 1 user/app use case 2026-09-11 15:14:00 +00:00
Ty 92c4f81640 docs: remove structure check that pins the old doc set 2026-09-11 15:11:23 +00:00
Ty 566ea0675c docs: mark leftover compose as pre-Milestone 1 2026-09-11 15:06:24 +00:00
Ty 7db28438ad docs: strip full-factory release process from Milestone 1 2026-09-11 15:06:04 +00:00
Ty d411352644 docs: strip host-specific deploy inventory 2026-09-11 15:06:02 +00:00
Ty 47abad22bc docs: Milestone 1 deploy is a Docker image; host is runtime 2026-09-11 15:06:00 +00:00
Ty 0f0bd71f35 docs: system seams for client capture vs server Woo 2026-09-11 15:02:56 +00:00
Ty daf03248c4 docs: runtime, one photo, empty mask, browsers 2026-09-11 15:02:47 +00:00
Ty 188905e778 docs: Milestone 1 states, display vs source pixels, mask controls 2026-09-11 14:53:33 +00:00
Ty ea4931e53f docs: state Milestone 1 has no inference URL 2026-09-11 14:43:58 +00:00
Ty baf2f89b3e docs: Milestone 1 is inference-free client code 2026-09-11 14:43:48 +00:00
Ty 9ca4b4520d docs: CAPTURE.md is Milestone 1 only 2026-09-11 14:36:38 +00:00
Ty 53830dcb91 docs: PRD milestones with acceptance 2026-09-11 14:36:25 +00:00
Ty 9418cc2eb5 docs: agent context is Milestone 1 2026-09-11 14:36:16 +00:00
Ty fb9a8c820c docs: use milestone vocabulary in README 2026-09-11 14:36:12 +00:00
Ty fd48105c99 docs: name device draft vs Woo draft in PRD 2026-09-11 14:33:19 +00:00
Ty 121ff7035e docs: Milestone 1 ends at step 8; separate device draft from Woo draft 2026-09-11 14:33:13 +00:00
Ty 65ec1ca3d2 docs: device draft continue or start fresh 2026-09-11 14:30:58 +00:00
Ty ff245529aa docs: lock inventory PNG properties from Woo research 2026-09-11 14:20:51 +00:00
Ty f08569894e docs: PRD starting state is green or black sheet 2026-09-11 14:16:06 +00:00
Ty 82e9e652f8 docs: capture setup on green or black sheet 2026-09-11 14:15:57 +00:00
Ty 10eee46097 docs: PRODUCT.md as PRD with milestones 2026-09-11 14:14:17 +00:00