{"slug":"estimate-instant","total":14,"limit":100,"offset":0,"since":null,"commits":[{"hash":"fb752d2","date":"2026-07-16 16:37:35 -0700","author":"Steve","subject":"estimate-instant: apply 5 contrarian fixes — always-gate leads/admin PII (ADMIN_CRED), targeted embed postMessage (host origin), unit-toggle value conversion, conservative per-strip half-drop math, total-linear-width hint","body":""},{"hash":"f4c6d59","date":"2026-07-16 08:50:08 -0700","author":"Steve","subject":"shopify: refresh catalog — keep sample-only as 'by request'","body":""},{"hash":"0fd0700","date":"2026-07-16 08:13:07 -0700","author":"Steve","subject":"shopify: refresh catalog — real roll prices, no $4.25 sample-only leak","body":""},{"hash":"edeca0c","date":"2026-07-16 08:12:07 -0700","author":"Steve Abrams","subject":"auto-save: 2026-07-16T08:12:03 (1 files) — data/shopify-catalog.json","body":""},{"hash":"b38a6f6","date":"2026-07-16 07:51:19 -0700","author":"Steve","subject":"security: bind server to 127.0.0.1 so the tunnel/proxy basic-auth gate can't be bypassed on the LAN","body":""},{"hash":"646c3eb","date":"2026-07-16 07:39:05 -0700","author":"Steve Abrams","subject":"shopify: add Buy N rolls CTA + TEST banner to calculator UI","body":"- Email capture still first (POST /api/lead with created_at — unchanged)\n- After estimate: green \"Buy N rolls on Designer Wallcoverings\" button appears\n  linking to https://www.designerwallcoverings.com/cart/<variant_id>:<N>\n  where N = rolls-needed from the estimate math\n- Real per-roll price and total shown in button pills\n- TEST-MODE banner below CTA: \"hands off to LIVE Shopify checkout for N rolls;\n  PayPal shows when enabled; roll specs are sample; production reads metafields\"\n- Stand-in note shown when shopify_match=false (all 8 current entries)\n- Embed iframe compatibility preserved (postHeight still fires)\n- All existing styles/behavior unchanged; only result block extended"},{"hash":"4349f95","date":"2026-07-16 07:38:55 -0700","author":"Steve Abrams","subject":"shopify: wire server to static catalog — estimate returns cart_url + /api/catalog-meta","body":"- loadCatalog() reads shopify-catalog.json (no token, static pull)\n- estimate() now accepts checkout_domain, builds cart permalink\n  https://<checkout_domain>/cart/<variant_id>:<rolls_needed>\n- estimate response includes shopify_variant_id, shopify_match, cart_url, checkout_domain\n- pricePerRoll uses shopify_price from rolls.json (falls back to price_per_roll)\n- New public /api/catalog-meta endpoint exposes checkout_domain for embed consumers\n- No Shopify token ever lives in this server"},{"hash":"1abb45d","date":"2026-07-16 07:38:46 -0700","author":"Steve Abrams","subject":"shopify: enrich rolls.json with real Shopify variant_ids + prices (0/8 SKU matches, 8/8 stand-ins)","body":"All 8 prototype SKUs (DW-GRAS-01 etc.) are pre-production and have no match in the\nlive Shopify catalog. Each entry gets shopify_variant_id + shopify_price from a real\ndistinct DW catalog product, shopify_match=false, and a _note documenting the seam.\nPrice_per_roll now mirrors the real Shopify price for each stand-in variant.\n\nPRODUCTION seam: roll_width_in / roll_length_ft / pattern_repeat_in must be pulled\nfrom Shopify metafields keyed by variant_id — documented in each _note field."},{"hash":"c033c9b","date":"2026-07-16 07:38:34 -0700","author":"Steve Abrams","subject":"shopify: add static catalog pull (200 real DW products, checkout_domain, variant_ids)","body":"Read-only copy of the live DW Shopify store — no token in the app.\nContains variant_id + price per SKU and checkout_domain for cart permalinks.\nCart permalink format: https://<checkout_domain>/cart/<variant_id>:<qty>"},{"hash":"f93b004","date":"2026-07-15 16:57:26 -0700","author":"Steve","subject":"estimate-instant: add embed-demo.html, fix /admin route + auth scope, admin sort+density (house rules)","body":"- server.js: BASIC_AUTH now gates /admin + /api/leads ONLY — estimator stays\n  public so it works when embedded cross-origin on 200+ sister sites\n- /admin route properly serves admin.html (was falling through to 404 via\n  basename mismatch); added CORS preflight headers for iframe embed POSTs\n- public/admin.html: added sort <select> (Newest/Oldest/Email/Price↑↓) +\n  density slider, both persisted to localStorage — house rule compliance\n- public/embed-demo.html: mock retailer page showing the widget embedded via\n  embed.js <script> snippet with copy-paste code block\n- scripts/pull-rollspecs.sql: one-liner to swap sample data → real dw_unified\n  products (psql \"host=/tmp dbname=dw_unified\" -Atq -f scripts/pull-rollspecs.sql > data/rolls.json)\n- Verified: 12/12 checks pass (rolls API, roll math, half-drop, lead capture,\n  admin 401→200 auth gate, embed pages, bad-email 400)"},{"hash":"6ec2a7c","date":"2026-07-15 16:52:04 -0700","author":"Steve","subject":"estimate-instant: add embeddable widget (embed.js iframe snippet + auto-height postMessage) — matches brief's 200+-site embed thesis","body":""},{"hash":"324b6db","date":"2026-07-14 10:14:12 -0700","author":"Steve","subject":"estimate-instant: fix half-drop math (consume match), honest capture copy, remove admin link from public page (contrarian FIX-FIRST)","body":""},{"hash":"25a1126","date":"2026-07-14 10:10:04 -0700","author":"Steve","subject":"estimate-instant v0: rolls-needed + instant-price calculator (server-side math), email capture, admin quotes view","body":""},{"hash":"6ef11db","date":"2026-07-14 10:05:14 -0700","author":"Steve","subject":"initial scaffold (estimate-instant) via web-dev accelerator","body":""}]}