← back to Koroseal Quote Only
TK-11106: Koroseal quote flow live end-to-end
70da4c77fc82208ec7f04aef3e4537a65743179a · 2026-09-02 12:46:06 -0700 · Steve Abrams
- CTA snippet: derive quote 'line' from product.vendor (was hardcoded Majilite)
- backend handler: use local George /api/send + Basic admin:$GEORGE_BASIC_AUTH_PASS
(unreachable Tailscale/no-auth path returned 401)
- deployed to koroseal-quote-api; verified delivered into info@ (ref KOR-20260902-4daeb2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M backend/quote-request-handler.jsM snippets/dw-quote-only-cta.liquid
Diff
commit 70da4c77fc82208ec7f04aef3e4537a65743179a
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Sep 2 12:46:06 2026 -0700
TK-11106: Koroseal quote flow live end-to-end
- CTA snippet: derive quote 'line' from product.vendor (was hardcoded Majilite)
- backend handler: use local George /api/send + Basic admin:$GEORGE_BASIC_AUTH_PASS
(unreachable Tailscale/no-auth path returned 401)
- deployed to koroseal-quote-api; verified delivered into info@ (ref KOR-20260902-4daeb2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
backend/quote-request-handler.js | 25 +++++++++++++++++++++----
snippets/dw-quote-only-cta.liquid | 3 ++-
2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/backend/quote-request-handler.js b/backend/quote-request-handler.js
index 0625dfa..16b6370 100644
--- a/backend/quote-request-handler.js
+++ b/backend/quote-request-handler.js
@@ -25,7 +25,16 @@ const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
-const GEORGE_EMAIL_URL = process.env.GEORGE_EMAIL_URL || 'http://100.65.187.120:9850/api/send';
+// George runs LOCALLY on Kamatera at :9850 behind Basic auth. The Tailscale IP
+// (100.x) is unreachable from Kamatera, so use the local /api/send contract that
+// the working fleet callers use (astek vendor-requests, launchd reminders). TK-11106.
+const GEORGE_SEND_URL = process.env.GEORGE_SEND_URL || 'http://127.0.0.1:9850/api/send';
+// Basic auth for the LOCAL Kamatera George: prefer a full user:pass override,
+// else build admin:<GEORGE_BASIC_AUTH_PASS> from the box's own .env (that pass is
+// this box's George credential; the Mac2 'DWSecure2024!' is a different George).
+const GEORGE_AUTH = process.env.GEORGE_BASIC_AUTH
+ || ('admin:' + (process.env.GEORGE_BASIC_AUTH_PASS || 'DWSecure2024!'));
+const GEORGE_FROM = process.env.GEORGE_FROM || 'steve@designerwallcoverings.com';
const INFO_EMAIL = process.env.INFO_EMAIL || 'info@designerwallcoverings.com';
const DEALER_DISCOUNT = process.env.DEALER_DISCOUNT || '15% Designer / Trade Discount';
const QUOTES_LOG = path.join(__dirname, 'quotes.jsonl');
@@ -96,10 +105,18 @@ async function handleQuoteRequest(req, res) {
let delivered = false;
try {
- const gr = await fetch(GEORGE_EMAIL_URL, {
+ const gr = await fetch(GEORGE_SEND_URL, {
method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ to: INFO_EMAIL, subject, html, text, replyTo: b.customerEmail }),
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Basic ' + Buffer.from(GEORGE_AUTH).toString('base64'),
+ },
+ // Mirror the working fleet caller shape (astek vendor-requests): `account`
+ // selects the sending mailbox, `body` carries the HTML. info@ is the
+ // internal DW inbox (allowlisted) so no external-send token is required.
+ body: JSON.stringify({ account: 'steve-office', from: GEORGE_FROM, to: INFO_EMAIL,
+ subject, body: html, html, text, replyTo: b.customerEmail,
+ message_class: 'transactional', source: 'quote-request' }),
});
delivered = gr.ok;
} catch (e) {
diff --git a/snippets/dw-quote-only-cta.liquid b/snippets/dw-quote-only-cta.liquid
index 2cf0bf5..96fb950 100644
--- a/snippets/dw-quote-only-cta.liquid
+++ b/snippets/dw-quote-only-cta.liquid
@@ -47,6 +47,7 @@
{%- endfor -%}
<div class="dw-quote-section"
+ data-quote-line="{{ product.vendor | escape }}"
data-product-id="{{ product.id }}"
data-product-title="{{ product.title | escape }}"
data-product-handle="{{ product.handle }}">
@@ -215,7 +216,7 @@
var nameEl=document.getElementById('dw-q-name');
var emailEl=document.getElementById('dw-q-email');
var payload={
- line:'Majilite',
+ line: (function(){var el=document.querySelector('.dw-quote-section');return (el && el.getAttribute('data-quote-line')) || 'Koroseal';})(),
productId: document.getElementById('dw-q-product-id').value,
productTitle: document.getElementById('dw-q-product-title').value,
productUrl: document.getElementById('dw-q-product-url').value,
← 6b72882 Post-crash reconcile: GMC exclude confirmed 212/212 complete
·
back to Koroseal Quote Only
·
(newest)