grokbot_ty
8d8b3a2ff1
Gate B: SvelteKit capture→mask→numbers→review UI with deterministic pipeline
...
- Scaffold SvelteKit app (svelte.config.js, vite.config.ts, app.html, app.d.ts)
- Build full capture flow: photo input → mask overlay + 4 knobs → axis overlay
+ rotation → length/thickness/SKU inputs → review + upload to /api/v1/slabs
- Uses existing lib/pipeline/* pure modules (mask, axis, units, crop, pricing, types)
- Uses existing validation/sku.ts for SKU validation
- Svelte 5 runes ($state, $effect, $derived) for reactive state
- Canvas-based rendering for mask overlay, axis visualization, and 3:4 crop preview
- Dockerfile updated for Vite production build with static Node server on :80
- All 54 existing tests pass, build succeeds
2026-09-07 18:53:35 +00:00
grokbot_ty
fb892e4a32
feat(gate-b): add product-state fixture harness for TV-3/6/7/10
...
Real-fixture path and harness for product-state evidence on TV-3 bdft identity,
TV-6 crop/PNG rules, TV-7 undersized warn/retake, and TV-10 rounding.
- fixtures/real/: acquisition README, placeholder metadata JSON templates
- fixtures/real-fixtures.ts: loader that decodes real PNGs, generates masks,
runs the pipeline, fails-closed when absent or unmarked
- tv3-real.test.ts / tv6-real.test.ts / tv7-real.test.ts / tv10-real.test.ts:
product-state tests that skip when real fixtures are absent
- Updated RESULTS.md with real-fixture harness note
- Added pngjs devDependency for PNG decoding in Node.js
Dual-proof preserved: proxy-synthetic unit rows remain separate and unchanged.
Gate B is not green; product-state rows are blocked pending Ty-supplied photos.
2026-09-07 18:23:04 +00:00
grokbot_ty
68d236961a
feat( #30 ): Gate B [10/10]: Deploy compose + WOO_BASE_URL (OPS-1, GC-5)
...
- deploy/.env.example: placeholders only (no real URLs, proper comments)
- frontend/Dockerfile: Node 20 stub server for compose build
- deploy/tests/test-compose-health.sh: OPS-1 compose health smoke test
- deploy/tests/test-woo-base-url.sh: GC-4/5/FUND-25 validation suite
- backend/app/api/settings.py: PUT rejects woo_base_url (422), consumer keys (422),
text() wrapping for SQLAlchemy 2.x, key primary key fix
- backend/tests/contract/test_woo_base_url.py: 8 contract tests for GC-4/GC-5
Tests: 39/39 backend tests pass (8 new, 31 existing green)
Deploy: 5/5 shell tests pass (Docker unavailable for compose-up path)
2026-09-07 08:18:25 +00:00
grokbot_ty
d5d8c49e04
Gate B #26 : shared validation module (V-1, V-2, V-3)
...
- V-1: SKU charset [A-Z0-9-]{3,24}, accepted/rejected with specific error codes
- V-2: title/short_title/description UTF-8 within WooCommerce maxLength,
enforced at field-exit and submit (200/200/2500 chars, Unicode code-point counting)
- V-3: validation module version hash, client caches, submit carries hash,
mismatch returns 412 with fresh module (not 409)
25 unit tests green, zero browser/DOM/network dependencies.
Re-exports through pipeline/index.ts for shared use.
2026-09-07 07:43:50 +00:00
grokbot_ty
34dbfa5d7d
feat( #25 ): Gate B pricing and thickness band (TV-8, TV-9)
...
TV-8 pricing:
- computeRecommendedPrice(bdft, pricePerBdft) returns bdft × price/bdft rounded half-up to 2 decimals
0.96 bdft × 12.50/bdft → 12.00
- computeSlabPrice handles three paths:
1. Has rule, no override → recommended price, source 'recommendation'
2. Has rule, override → override stored (150.00), source 'override'
3. No rule, manual → manual stored (99.99), recommendedPrice null
TV-9 thickness band:
- findThicknessBand(thicknessIn, ranges) rounds to 1/8" then matches [min, max) half-open ranges
- 1" → 1"–1 1/2" (rounds up, label from synced Woo attribute, not hardcoded)
Test output (all 29 tests green, 6 new):
- tv8-pricing.test.ts: 6 passed (recommended, override, no-rule, rounding)
- tv9-thickness-band.test.ts: 6 passed (1"→1"–1 1/2", 0.75"→3/4"–1", 0.875"→3/4"–1", 1.5"→1 1/2"–2", null for out-of-range, rounding to 1/8")
2026-09-07 06:33:24 +00:00
grokbot_ty
f7040f5947
feat( #24 ): Gate B 3:4 crop + no upscale (TV-6, TV-7)
...
TV-6: 3:4 portrait crop, 80% fill at extremes, transparent PNG, shorter side >= 1600px when source allows.
TV-7: undersized source warning, no upscaling, photo not publishable until retake.
Real fixture output:
- TV-6 large source (4000x3200, slab 1281x3000): crop target 1601x2135, shorter 1601 >= 1600, fill at limiting dim 0.80
- TV-7 small source (800x640, slab 400x300): crop target 281x375, shorter 281 < 1600, undersized
- No upscale property: output never exceeds source dimensions
New files:
- frontend/src/lib/pipeline/crop.ts: cropTo34(), findSlabBounds(), computeCropTarget(), checkSourceSize()
- frontend/src/__tests__/fixtures/crop.ts: tv6LargeSourceFixture, tv7SmallSourceFixture, simpleAxis
- frontend/src/__tests__/tv6-tv7-crop.test.ts: 7 tests (2 TV-6, 2 TV-7, 3 property)
2026-09-07 06:24:00 +00:00
grokbot_ty
08c463b8d8
feat( #23 ): Gate B length axis and 6" widths (TV-4, TV-5)
...
Pure client axis module: min-area length axis, rotate/confirm session,
scale, and perpendicular width samples every 6".
2026-09-07 06:07:07 +00:00
grokbot_ty
55d66b9644
feat( #22 ): Gate B BDFT identity and rounding (TV-3, TV-10)
...
Pure units module: bdft = sqft × thickness_in (no /12), half-up
rounding for sqft/bdft/price, length to nearest 1/8". Property
checks for monotonicity in thickness and sqft.
TDD: red evidence in test-results/tv3-tv10-red.txt, then minimum impl.
Results:
TV-3 | pass | test-results/tv3-tv10-green.txt
TV-10 | pass | test-results/tv3-tv10-green.txt
2026-09-07 06:02:08 +00:00
grokbot_ty
3c2f8871a8
feat( #21 ): Gate B green/black sheet mask (TV-1, TV-2)
...
Pure client modules for TECH-SPEC sheet detect, chroma-key / black
threshold with border flood-fill, four knobs (live re-run), and mask
confirm hooks. Synthetic fixtures. U2Net never invoked.
TDD: red evidence in test-results/tv1-tv2-red.txt, then minimum impl.
Results:
TV-1 | pass | test-results/tv1-tv2-green.txt
TV-2 | pass | test-results/tv1-tv2-green.txt
2026-09-07 05:53:43 +00:00