← back to All Designerwallcoverings
Kravet family gets a $0 authoritative-price live check (kravet-db adapter, DB_AUTHORITATIVE tier)
f9158ab7072b1c0ffcf2bf145bafa081ebb4048d · 2026-07-15 14:18:28 -0700 · Steve Abrams
- new scripts/adapters/kravet-db.js: resolves the grid SKU's mfr code and answers from
dw_unified.kravet_authoritative_pricing with the MAP retail (new_map, else whls x 1.5 derived);
session_opened:false so nothing bills; wholesale never emitted
- live-scrape.js: DB adapters run without the Browserbase lib (only session adapters need it)
- server.js: session_opened:false success -> cost 0, no ledger/live-spend entry; DB_AUTHORITATIVE
tier exempt from the daily $-cap only (per-IP + inflight limits still apply)
- build-coverage.js: KRAVET_FAMILY -> DB_AUTHORITATIVE first-branch, kapMatchCount resolvability
gate, Kravet removed from NO_LIVE_STOCK_PORTAL; coverage regenerated (12 vendors in tier,
7 live-capable: Brunschwig 2636, Gaston 2142, Lee Jofa 2110, Cole & Son 1236, GP&J Baker 1185,
Kravet 840, Threads 69)
Files touched
M data/live-stock-coverage.jsonM scripts/adapters/index.jsA scripts/adapters/kravet-db.jsM scripts/build-coverage.jsM scripts/live-scrape.jsM server.js
Diff
commit f9158ab7072b1c0ffcf2bf145bafa081ebb4048d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jul 15 14:18:28 2026 -0700
Kravet family gets a $0 authoritative-price live check (kravet-db adapter, DB_AUTHORITATIVE tier)
- new scripts/adapters/kravet-db.js: resolves the grid SKU's mfr code and answers from
dw_unified.kravet_authoritative_pricing with the MAP retail (new_map, else whls x 1.5 derived);
session_opened:false so nothing bills; wholesale never emitted
- live-scrape.js: DB adapters run without the Browserbase lib (only session adapters need it)
- server.js: session_opened:false success -> cost 0, no ledger/live-spend entry; DB_AUTHORITATIVE
tier exempt from the daily $-cap only (per-IP + inflight limits still apply)
- build-coverage.js: KRAVET_FAMILY -> DB_AUTHORITATIVE first-branch, kapMatchCount resolvability
gate, Kravet removed from NO_LIVE_STOCK_PORTAL; coverage regenerated (12 vendors in tier,
7 live-capable: Brunschwig 2636, Gaston 2142, Lee Jofa 2110, Cole & Son 1236, GP&J Baker 1185,
Kravet 840, Threads 69)
---
data/live-stock-coverage.json | 574 ++++++++++++++++++++++++------------------
scripts/adapters/index.js | 1 +
scripts/adapters/kravet-db.js | 79 ++++++
scripts/build-coverage.js | 62 ++++-
scripts/live-scrape.js | 8 +-
server.js | 13 +-
6 files changed, 473 insertions(+), 264 deletions(-)
diff --git a/data/live-stock-coverage.json b/data/live-stock-coverage.json
index 004a689..b9adb92 100644
--- a/data/live-stock-coverage.json
+++ b/data/live-stock-coverage.json
@@ -1,14 +1,15 @@
{
- "generated_at": "2026-07-08T16:05:58.787Z",
+ "generated_at": "2026-07-15T21:17:59.485Z",
"generator": "scripts/build-coverage.js",
- "total_display_vendors": 252,
+ "total_display_vendors": 256,
"counts": {
+ "DB_AUTHORITATIVE": 12,
"PORTAL_CREDS": 6,
"PUBLIC_STOCK": 24,
- "PORTAL_NO_CREDS": 15,
- "QUOTE_ONLY": 36,
- "NO_STOCK": 171,
- "live_capable": 14
+ "PORTAL_NO_CREDS": 14,
+ "QUOTE_ONLY": 40,
+ "NO_STOCK": 160,
+ "live_capable": 21
},
"vendors": {
"1838 Wallcoverings": {
@@ -36,6 +37,17 @@
"products": 1,
"active": 0
},
+ "A.S. Création": {
+ "tier": "NO_STOCK",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
+ "catalog_table": null,
+ "backing": null,
+ "match": "unmatched",
+ "products": 1,
+ "active": 1
+ },
"Abel Macias": {
"tier": "NO_STOCK",
"live_capable": false,
@@ -52,11 +64,11 @@
"live_capable": false,
"adapter": null,
"reason": "vendor does not publish live stock (to-the-trade / quote-only)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
- "products": 400,
- "active": 400
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Alan Campbell",
+ "match": "exact",
+ "products": 434,
+ "active": 434
},
"Ananbo": {
"tier": "NO_STOCK",
@@ -190,26 +202,15 @@
"products": 505,
"active": 327
},
- "A.S. Création": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
- "products": 1,
- "active": 1
- },
"Atomic 50 Ceilings": {
- "tier": "NO_STOCK",
+ "tier": "QUOTE_ONLY",
"live_capable": false,
"adapter": null,
- "reason": "no live stock source identified for this line",
+ "reason": "vendor does not publish live stock (to-the-trade / quote-only)",
"catalog_table": "atomic50_catalog",
"backing": "Atomic 50 Ceilings",
"match": "exact",
- "products": 2,
+ "products": 58,
"active": 2
},
"Backdrop": {
@@ -224,15 +225,17 @@
"active": 9
},
"Baker Lifestyle": {
- "tier": "NO_STOCK",
+ "tier": "DB_AUTHORITATIVE",
"live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
+ "adapter": "kravet-db",
+ "reason": "adapter wired (kravet-db) but too few SKUs match the Kravet authoritative price file (3 of 4 active)",
"catalog_table": "baker_lifestyle_catalog",
"backing": "Baker Lifestyle",
"match": "exact",
"products": 8,
- "active": 4
+ "active": 4,
+ "resolvable_active": 3,
+ "resolvable_pct": 75
},
"Belarte Studio": {
"tier": "NO_STOCK",
@@ -287,7 +290,7 @@
"backing": null,
"match": "unmatched",
"products": 32,
- "active": 31
+ "active": 0
},
"Boråstapeter Wallpaper": {
"tier": "NO_STOCK",
@@ -309,7 +312,7 @@
"backing": "Brand McKenzie",
"match": "exact",
"products": 165,
- "active": 156
+ "active": 154
},
"British Walls": {
"tier": "NO_STOCK",
@@ -323,15 +326,18 @@
"active": 356
},
"Brunschwig & Fils": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": true,
+ "adapter": "kravet-db",
+ "reason": "authoritative Kravet price file (daily email ingest — $0, instant)",
"catalog_table": "brunschwig_catalog",
"backing": "Brunschwig & Fils",
"match": "exact",
"products": 3371,
- "active": 2760
+ "active": 2760,
+ "resolvable_active": 2636,
+ "resolvable_pct": 96,
+ "verified": "wired — not yet live-verified"
},
"Carlisle & Co. Walls": {
"tier": "PUBLIC_STOCK",
@@ -384,9 +390,9 @@
"live_capable": false,
"adapter": null,
"reason": "vendor does not publish live stock (to-the-trade / quote-only)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Charles Burger",
+ "match": "exact",
"products": 83,
"active": 79
},
@@ -432,7 +438,7 @@
"backing": null,
"match": "unmatched",
"products": 175,
- "active": 164
+ "active": 163
},
"Clarence House": {
"tier": "QUOTE_ONLY",
@@ -472,9 +478,9 @@
"live_capable": false,
"adapter": null,
"reason": "vendor does not publish live stock (to-the-trade / quote-only)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Cloth and Paper",
+ "match": "exact",
"products": 41,
"active": 41
},
@@ -489,6 +495,20 @@
"products": 1,
"active": 0
},
+ "Cole & Son": {
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": true,
+ "adapter": "kravet-db",
+ "reason": "authoritative Kravet price file (daily email ingest — $0, instant)",
+ "catalog_table": "coleson_catalog",
+ "backing": "Cole & Son",
+ "match": "exact",
+ "products": 1268,
+ "active": 1238,
+ "resolvable_active": 1236,
+ "resolvable_pct": 100,
+ "verified": "wired — not yet live-verified"
+ },
"Colefax and Fowler": {
"tier": "NO_STOCK",
"live_capable": false,
@@ -500,17 +520,6 @@
"products": 361,
"active": 0
},
- "Cole & Son": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
- "catalog_table": "coleson_catalog",
- "backing": "Cole & Son",
- "match": "exact",
- "products": 1268,
- "active": 1238
- },
"Contrado": {
"tier": "NO_STOCK",
"live_capable": false,
@@ -531,7 +540,7 @@
"backing": "Coordonné",
"match": "exact",
"products": 1377,
- "active": 1341
+ "active": 1340
},
"Coordonné Europe": {
"tier": "NO_STOCK",
@@ -564,7 +573,7 @@
"backing": "Daisy Bennett",
"match": "exact",
"products": 70,
- "active": 62
+ "active": 58
},
"Dedar": {
"tier": "QUOTE_ONLY",
@@ -577,20 +586,6 @@
"products": 1,
"active": 1
},
- "Designers Guild": {
- "tier": "PUBLIC_STOCK",
- "live_capable": true,
- "adapter": "schema-public",
- "reason": "public schema.org/Magento availability (no login required)",
- "catalog_table": "designers_guild_catalog",
- "backing": "Designers Guild",
- "match": "exact",
- "products": 879,
- "active": 842,
- "resolvable_active": 189,
- "resolvable_pct": 22,
- "verified": "live-verified 2026-07-07 (schema-public → in_stock:true via structured availability vote, $0.03)"
- },
"Designer Wallcoverings": {
"tier": "PORTAL_NO_CREDS",
"live_capable": false,
@@ -600,7 +595,7 @@
"backing": "Folia Fabrics",
"match": "private-label",
"products": 2263,
- "active": 1097
+ "active": 1054
},
"Designer Wallcoverings and Fabrics": {
"tier": "NO_STOCK",
@@ -613,6 +608,20 @@
"products": 15,
"active": 0
},
+ "Designers Guild": {
+ "tier": "PUBLIC_STOCK",
+ "live_capable": true,
+ "adapter": "schema-public",
+ "reason": "public schema.org/Magento availability (no login required)",
+ "catalog_table": "designers_guild_catalog",
+ "backing": "Designers Guild",
+ "match": "exact",
+ "products": 879,
+ "active": 842,
+ "resolvable_active": 189,
+ "resolvable_pct": 22,
+ "verified": "live-verified 2026-07-07 (schema-public → in_stock:true via structured availability vote, $0.03)"
+ },
"Designtex": {
"tier": "PUBLIC_STOCK",
"live_capable": true,
@@ -621,10 +630,10 @@
"catalog_table": "designtex_catalog",
"backing": "Designtex",
"match": "exact",
- "products": 650,
- "active": 417,
- "resolvable_active": 417,
- "resolvable_pct": 100,
+ "products": 703,
+ "active": 425,
+ "resolvable_active": 279,
+ "resolvable_pct": 66,
"verified": "live-verified 2026-07-08 (schema-public → in_stock:true, $0.03; enabled after the Steve-approved dw_sku backfill of 417 active rows — base(variant_sku)=designtex_catalog.dw_sku — into the Kamatera-local dw_unified the aggregator loads; resolvability 417/417 = 100%)"
},
"Dolce & Gabbana": {
@@ -682,7 +691,7 @@
"products": 2331,
"active": 916
},
- "DW Bespoke Studios To Go": {
+ "DW Bespoke Studio To Go": {
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
@@ -690,10 +699,10 @@
"catalog_table": null,
"backing": null,
"match": "unmatched",
- "products": 592,
+ "products": 9,
"active": 0
},
- "DW Bespoke Studio To Go": {
+ "DW Bespoke Studios To Go": {
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
@@ -701,7 +710,7 @@
"catalog_table": null,
"backing": null,
"match": "unmatched",
- "products": 9,
+ "products": 592,
"active": 0
},
"DW Exclusive Wallpaper": {
@@ -715,7 +724,7 @@
"products": 1,
"active": 1
},
- "DWHD": {
+ "DW Home": {
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
@@ -723,10 +732,10 @@
"catalog_table": null,
"backing": null,
"match": "unmatched",
- "products": 1,
- "active": 1
+ "products": 79,
+ "active": 37
},
- "DW Home": {
+ "DW Internal": {
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
@@ -734,10 +743,10 @@
"catalog_table": null,
"backing": null,
"match": "unmatched",
- "products": 79,
- "active": 37
+ "products": 1,
+ "active": 0
},
- "DW Internal": {
+ "DWHD": {
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
@@ -746,7 +755,7 @@
"backing": null,
"match": "unmatched",
"products": 1,
- "active": 0
+ "active": 1
},
"Edge Wallcovering": {
"tier": "NO_STOCK",
@@ -778,8 +787,8 @@
"catalog_table": "elitis_catalog",
"backing": "Elitis",
"match": "exact",
- "products": 244,
- "active": 243
+ "products": 602,
+ "active": 579
},
"Emiliana Parati": {
"tier": "NO_STOCK",
@@ -814,6 +823,17 @@
"products": 461,
"active": 0
},
+ "F. Schumacher Fabrics": {
+ "tier": "NO_STOCK",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
+ "catalog_table": null,
+ "backing": null,
+ "match": "unmatched",
+ "products": 67,
+ "active": 0
+ },
"Fabricut": {
"tier": "PORTAL_NO_CREDS",
"live_capable": false,
@@ -855,8 +875,8 @@
"catalog_table": "fentucci_catalog",
"backing": "Fentucci",
"match": "exact",
- "products": 3209,
- "active": 403
+ "products": 3200,
+ "active": 528
},
"Fentucci Fabrics": {
"tier": "NO_STOCK",
@@ -889,7 +909,7 @@
"backing": "Fentucci Naturals",
"match": "exact",
"products": 148,
- "active": 0
+ "active": 148
},
"Fentucci Naturals Walls": {
"tier": "NO_STOCK",
@@ -968,27 +988,43 @@
"products": 1,
"active": 1
},
- "F. Schumacher Fabrics": {
- "tier": "NO_STOCK",
+ "Fromental": {
+ "tier": "QUOTE_ONLY",
"live_capable": false,
"adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
+ "reason": "vendor does not publish live stock (to-the-trade / quote-only)",
+ "catalog_table": null,
+ "backing": "Fromental",
+ "match": "exact",
+ "products": 1471,
+ "active": 0
+ },
+ "G P & J Baker": {
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": false,
+ "adapter": "kravet-db",
+ "reason": "adapter wired (kravet-db) but too few SKUs match the Kravet authoritative price file (1 of 1 active)",
"catalog_table": null,
"backing": null,
"match": "unmatched",
- "products": 67,
- "active": 0
+ "products": 2,
+ "active": 1,
+ "resolvable_active": 1,
+ "resolvable_pct": 100
},
"Gaston Y Daniela": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": true,
+ "adapter": "kravet-db",
+ "reason": "authoritative Kravet price file (daily email ingest — $0, instant)",
"catalog_table": "gaston_daniela_catalog",
"backing": "Gaston Y Daniela",
"match": "exact",
"products": 2293,
- "active": 2148
+ "active": 2148,
+ "resolvable_active": 2142,
+ "resolvable_pct": 100,
+ "verified": "wired — not yet live-verified"
},
"Glambeads by DW": {
"tier": "NO_STOCK",
@@ -1023,27 +1059,30 @@
"products": 551,
"active": 402
},
- "G P & J Baker": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
- "products": 2,
- "active": 1
- },
"GP & J Baker": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": true,
+ "adapter": "kravet-db",
+ "reason": "authoritative Kravet price file (daily email ingest — $0, instant)",
"catalog_table": "gp_baker_catalog",
"backing": "GP & J Baker",
"match": "exact",
"products": 1885,
- "active": 1197
+ "active": 1197,
+ "resolvable_active": 1185,
+ "resolvable_pct": 99,
+ "verified": "wired — not yet live-verified"
+ },
+ "Gracie": {
+ "tier": "QUOTE_ONLY",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "vendor does not publish live stock (to-the-trade / quote-only)",
+ "catalog_table": null,
+ "backing": "Gracie",
+ "match": "exact",
+ "products": 300,
+ "active": 0
},
"Graduate Collection": {
"tier": "NO_STOCK",
@@ -1076,8 +1115,8 @@
"backing": "Graham & Brown",
"match": "exact",
"products": 1679,
- "active": 405,
- "resolvable_active": 399,
+ "active": 404,
+ "resolvable_active": 398,
"resolvable_pct": 99,
"verified": "live-verified 2026-07-07 (schema-public → in_stock:true, $0.03)"
},
@@ -1086,13 +1125,24 @@
"live_capable": false,
"adapter": null,
"reason": "vendor does not publish live stock (to-the-trade / quote-only)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Grasscloth",
+ "match": "exact",
"products": 5,
"active": 0
},
"Grasscloth Wallpaper": {
+ "tier": "NO_STOCK",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "no live stock source identified for this line",
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Grasscloth",
+ "match": "suffix-strip",
+ "products": 1,
+ "active": 0
+ },
+ "Greenland": {
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
@@ -1100,7 +1150,7 @@
"catalog_table": null,
"backing": null,
"match": "unmatched",
- "products": 1,
+ "products": 344,
"active": 0
},
"Hand Crafted": {
@@ -1112,7 +1162,7 @@
"backing": null,
"match": "unmatched",
"products": 162,
- "active": 39
+ "active": 15
},
"Happy Menocal": {
"tier": "NO_STOCK",
@@ -1134,7 +1184,7 @@
"backing": "Harlequin",
"match": "exact",
"products": 586,
- "active": 583
+ "active": 580
},
"Heritage Collection": {
"tier": "NO_STOCK",
@@ -1232,17 +1282,17 @@
"catalog_table": "hollywood_catalog",
"backing": "Hollywood Wallcoverings",
"match": "exact",
- "products": 5640,
- "active": 2799
+ "products": 5856,
+ "active": 2659
},
"Home Couture": {
"tier": "QUOTE_ONLY",
"live_capable": false,
"adapter": null,
"reason": "vendor does not publish live stock (to-the-trade / quote-only)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Home Couture",
+ "match": "exact",
"products": 235,
"active": 229
},
@@ -1261,12 +1311,12 @@
"tier": "PUBLIC_STOCK",
"live_capable": false,
"adapter": "shopify-public",
- "reason": "adapter wired (shopify-public) but display SKUs don't align with the hygge_catalog catalog (0 of 0 active resolvable) — needs SKU remap",
+ "reason": "adapter wired (shopify-public) but display SKUs don't align with the hygge_catalog catalog (0 of 8 active resolvable) — needs SKU remap",
"catalog_table": "hygge_catalog",
"backing": "Hygge & West",
"match": "exact",
"products": 11,
- "active": 0,
+ "active": 8,
"resolvable_active": 0,
"resolvable_pct": 0
},
@@ -1327,8 +1377,8 @@
"catalog_table": "jeffrey_stevens_catalog",
"backing": "York (Jeffrey Stevens source)",
"match": "private-label",
- "products": 3809,
- "active": 1454
+ "products": 5761,
+ "active": 2105
},
"JF Fabrics": {
"tier": "NO_STOCK",
@@ -1383,43 +1433,61 @@
"backing": "Koroseal",
"match": "exact",
"products": 2548,
- "active": 2351,
- "resolvable_active": 2351,
+ "active": 2368,
+ "resolvable_active": 2368,
"resolvable_pct": 100,
"verified": "live-verified 2026-07-07 (koroseal liveness — DWK-29052 Available via live 200 PDP / DWK-32619 Discontinued via 302→/NotFound; mfr-code URL reconstruction; price:null; $0.03 each)"
},
"Kravet": {
- "tier": "PORTAL_NO_CREDS",
- "live_capable": false,
- "adapter": null,
- "reason": "vendor portal does not expose live stock (wholesale price sheet / SFTP only)",
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": true,
+ "adapter": "kravet-db",
+ "reason": "authoritative Kravet price file (daily email ingest — $0, instant)",
"catalog_table": "kravet_catalog",
"backing": "Kravet",
"match": "exact",
- "products": 5239,
- "active": 2542
+ "products": 5319,
+ "active": 2616,
+ "resolvable_active": 840,
+ "resolvable_pct": 32,
+ "verified": "wired — not yet live-verified"
},
"Kravet Couture": {
- "tier": "NO_STOCK",
+ "tier": "DB_AUTHORITATIVE",
"live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
+ "adapter": "kravet-db",
+ "reason": "adapter wired (kravet-db) but too few SKUs match the Kravet authoritative price file (2 of 2 active)",
"catalog_table": null,
"backing": null,
"match": "unmatched",
"products": 4,
- "active": 2
+ "active": 2,
+ "resolvable_active": 2,
+ "resolvable_pct": 100
},
"Kravet Design": {
- "tier": "NO_STOCK",
+ "tier": "DB_AUTHORITATIVE",
"live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
+ "adapter": "kravet-db",
+ "reason": "adapter wired (kravet-db) but too few SKUs match the Kravet authoritative price file (2 of 2 active)",
"catalog_table": null,
"backing": null,
"match": "unmatched",
"products": 4,
- "active": 2
+ "active": 2,
+ "resolvable_active": 2,
+ "resolvable_pct": 100
+ },
+ "LA Walls": {
+ "tier": "NO_STOCK",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "no live stock source identified for this line",
+ "catalog_table": "la_walls_catalog",
+ "backing": "LA Walls",
+ "match": "exact",
+ "products": 744,
+ "active": 98
},
"Larsen": {
"tier": "NO_STOCK",
@@ -1443,49 +1511,43 @@
"products": 158,
"active": 110
},
- "LA Walls": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
- "catalog_table": "la_walls_catalog",
- "backing": "LA Walls",
- "match": "exact",
- "products": 744,
- "active": 98
- },
- "LEED Walls": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
- "catalog_table": "leed_walls_catalog",
- "backing": "LEED Walls",
- "match": "exact",
- "products": 129,
- "active": 68
- },
"Lee Jofa": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": true,
+ "adapter": "kravet-db",
+ "reason": "authoritative Kravet price file (daily email ingest — $0, instant)",
"catalog_table": "lee_jofa_catalog",
"backing": "Lee Jofa",
"match": "exact",
"products": 3695,
- "active": 2150
+ "active": 2150,
+ "resolvable_active": 2110,
+ "resolvable_pct": 98,
+ "verified": "wired — not yet live-verified"
},
"Lee Jofa Modern": {
- "tier": "NO_STOCK",
+ "tier": "DB_AUTHORITATIVE",
"live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
+ "adapter": "kravet-db",
+ "reason": "adapter wired (kravet-db) but too few SKUs match the Kravet authoritative price file (1 of 1 active)",
"catalog_table": null,
"backing": null,
"match": "unmatched",
"products": 2,
- "active": 1
+ "active": 1,
+ "resolvable_active": 1,
+ "resolvable_pct": 100
+ },
+ "LEED Walls": {
+ "tier": "NO_STOCK",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "no live stock source identified for this line",
+ "catalog_table": "leed_walls_catalog",
+ "backing": "LEED Walls",
+ "match": "exact",
+ "products": 129,
+ "active": 68
},
"Limited Stock": {
"tier": "NO_STOCK",
@@ -1607,10 +1669,10 @@
"catalog_table": "wallquest_catalog",
"backing": "Malibu Wallpaper",
"match": "exact",
- "products": 4333,
- "active": 2869,
+ "products": 4416,
+ "active": 2947,
"resolvable_active": 2081,
- "resolvable_pct": 73,
+ "resolvable_pct": 71,
"verified": "live-verified 2026-07-07 (wallquest → OutOfStock, $0.10)"
},
"Malibu Walls": {
@@ -1834,13 +1896,13 @@
"tier": "PUBLIC_STOCK",
"live_capable": false,
"adapter": "shopify-public",
- "reason": "adapter wired (shopify-public) but display SKUs don't align with the nina_campbell_catalog catalog (8 of 544 active resolvable) — needs SKU remap",
+ "reason": "adapter wired (shopify-public) but display SKUs don't align with the nina_campbell_catalog catalog (7 of 539 active resolvable) — needs SKU remap",
"catalog_table": "nina_campbell_catalog",
"backing": "Nina Campbell",
"match": "exact",
"products": 791,
- "active": 544,
- "resolvable_active": 8,
+ "active": 539,
+ "resolvable_active": 7,
"resolvable_pct": 1
},
"Nina Campbell Wallcoverings": {
@@ -1878,7 +1940,7 @@
"backing": "Nobilis",
"match": "exact",
"products": 179,
- "active": 75
+ "active": 74
},
"Novasuede": {
"tier": "NO_STOCK",
@@ -1889,7 +1951,7 @@
"backing": "Novasuede",
"match": "exact",
"products": 198,
- "active": 158
+ "active": 157
},
"OLIVIA AND POPP": {
"tier": "NO_STOCK",
@@ -1911,8 +1973,8 @@
"backing": "Osborne & Little",
"match": "exact",
"products": 1041,
- "active": 933,
- "resolvable_active": 397,
+ "active": 931,
+ "resolvable_active": 398,
"resolvable_pct": 43,
"verified": "live-verified 2026-07-07 (schema-public → in_stock:true via enabled add-to-cart; SKU remap by leading mfr code, $0.03)"
},
@@ -2017,17 +2079,6 @@
"products": 3,
"active": 3
},
- "Phillipe Romano": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
- "catalog_table": "twil_karin_catalog",
- "backing": "TWIL Karin",
- "match": "private-label",
- "products": 19359,
- "active": 8523
- },
"Phillip Jeffries": {
"tier": "PORTAL_NO_CREDS",
"live_capable": false,
@@ -2036,8 +2087,19 @@
"catalog_table": "pj_catalog",
"backing": "Phillip Jeffries",
"match": "exact",
- "products": 3167,
- "active": 2472
+ "products": 3187,
+ "active": 2469
+ },
+ "Phillipe Romano": {
+ "tier": "NO_STOCK",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "no live stock source identified for this line",
+ "catalog_table": "twil_karin_catalog",
+ "backing": "TWIL Karin",
+ "match": "private-label",
+ "products": 20740,
+ "active": 9729
},
"Phyllis Morris": {
"tier": "NO_STOCK",
@@ -2058,7 +2120,7 @@
"catalog_table": "pierre_frey_catalog",
"backing": "Pierre Frey",
"match": "exact",
- "products": 4970,
+ "products": 6520,
"active": 81
},
"Pixels": {
@@ -2076,10 +2138,10 @@
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
+ "reason": "no live stock source identified for this line",
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Plains",
+ "match": "exact",
"products": 211,
"active": 181
},
@@ -2103,7 +2165,7 @@
"backing": null,
"match": "unmatched",
"products": 418,
- "active": 119
+ "active": 102
},
"Primo Leathers": {
"tier": "NO_STOCK",
@@ -2145,11 +2207,11 @@
"live_capable": false,
"adapter": null,
"reason": "vendor does not publish live stock (to-the-trade / quote-only)",
- "catalog_table": null,
+ "catalog_table": "quadrille_house_catalog",
"backing": "Quadrille",
"match": "exact",
- "products": 399,
- "active": 372
+ "products": 478,
+ "active": 443
},
"Ralph Lauren": {
"tier": "PORTAL_NO_CREDS",
@@ -2222,13 +2284,13 @@
"live_capable": true,
"adapter": "schema-public",
"reason": "public schema.org/Magento availability (no login required)",
- "catalog_table": "rebel_walls_catalog",
+ "catalog_table": "rebelwalls_catalog",
"backing": "Rebel Walls",
"match": "exact",
- "products": 3797,
- "active": 3684,
- "resolvable_active": 2127,
- "resolvable_pct": 58,
+ "products": 3837,
+ "active": 3724,
+ "resolvable_active": 1028,
+ "resolvable_pct": 28,
"verified": "live-verified 2026-07-07 (schema-public → in_stock:true, $0.03)"
},
"Retro Walls": {
@@ -2262,7 +2324,7 @@
"backing": "Roberto Cavalli",
"match": "suffix-strip",
"products": 180,
- "active": 146
+ "active": 145
},
"Romo": {
"tier": "PORTAL_CREDS",
@@ -2287,7 +2349,7 @@
"backing": null,
"match": "unmatched",
"products": 732,
- "active": 207
+ "active": 206
},
"Sacha Walckhoff": {
"tier": "NO_STOCK",
@@ -2323,7 +2385,7 @@
"backing": "Sandberg",
"match": "exact",
"products": 991,
- "active": 761
+ "active": 752
},
"Sara Bergqvist": {
"tier": "NO_STOCK",
@@ -2388,8 +2450,8 @@
"catalog_table": "schumacher_catalog",
"backing": "Schumacher",
"match": "exact",
- "products": 5576,
- "active": 2729
+ "products": 5655,
+ "active": 2636
},
"Schumacher Fabrics": {
"tier": "PORTAL_NO_CREDS",
@@ -2562,10 +2624,10 @@
"tier": "NO_STOCK",
"live_capable": false,
"adapter": null,
- "reason": "no live stock source identified for this line (private-label aggregate or unmapped)",
- "catalog_table": null,
- "backing": null,
- "match": "unmatched",
+ "reason": "no live stock source identified for this line",
+ "catalog_table": "quadrille_house_catalog",
+ "backing": "Suncloth",
+ "match": "exact",
"products": 318,
"active": 254
},
@@ -2621,22 +2683,25 @@
"catalog_table": "thibaut_catalog",
"backing": "Thibaut",
"match": "exact",
- "products": 4275,
- "active": 2407,
+ "products": 4679,
+ "active": 2811,
"resolvable_active": 1589,
- "resolvable_pct": 66,
+ "resolvable_pct": 57,
"verified": "wired — not yet live-verified"
},
"Threads": {
- "tier": "NO_STOCK",
- "live_capable": false,
- "adapter": null,
- "reason": "no live stock source identified for this line",
+ "tier": "DB_AUTHORITATIVE",
+ "live_capable": true,
+ "adapter": "kravet-db",
+ "reason": "authoritative Kravet price file (daily email ingest — $0, instant)",
"catalog_table": "threads_catalog",
"backing": "Threads",
"match": "exact",
"products": 81,
- "active": 71
+ "active": 71,
+ "resolvable_active": 69,
+ "resolvable_pct": 97,
+ "verified": "wired — not yet live-verified"
},
"Timorous Beasties": {
"tier": "PORTAL_NO_CREDS",
@@ -2658,7 +2723,7 @@
"backing": null,
"match": "unmatched",
"products": 214,
- "active": 17
+ "active": 16
},
"Tres Tintas": {
"tier": "NO_STOCK",
@@ -2669,7 +2734,7 @@
"backing": "Tres Tintas",
"match": "exact",
"products": 605,
- "active": 602
+ "active": 601
},
"Trikes-DL Couch-Eykon-Source-One": {
"tier": "NO_STOCK",
@@ -2715,17 +2780,6 @@
"products": 4,
"active": 4
},
- "Versace": {
- "tier": "QUOTE_ONLY",
- "live_capable": false,
- "adapter": null,
- "reason": "vendor does not publish live stock (to-the-trade / quote-only)",
- "catalog_table": "versace_catalog",
- "backing": "Versace",
- "match": "exact",
- "products": 542,
- "active": 451
- },
"Versa Designed Surfaces": {
"tier": "NO_STOCK",
"live_capable": false,
@@ -2737,6 +2791,17 @@
"products": 884,
"active": 842
},
+ "Versace": {
+ "tier": "QUOTE_ONLY",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "vendor does not publish live stock (to-the-trade / quote-only)",
+ "catalog_table": "versace_catalog",
+ "backing": "Versace",
+ "match": "exact",
+ "products": 542,
+ "active": 451
+ },
"Villa Nova": {
"tier": "NO_STOCK",
"live_capable": false,
@@ -2846,6 +2911,17 @@
"match": "exact",
"products": 367,
"active": 331
+ },
+ "Zuber": {
+ "tier": "QUOTE_ONLY",
+ "live_capable": false,
+ "adapter": null,
+ "reason": "vendor does not publish live stock (to-the-trade / quote-only)",
+ "catalog_table": null,
+ "backing": "Zuber",
+ "match": "exact",
+ "products": 384,
+ "active": 0
}
}
}
\ No newline at end of file
diff --git a/scripts/adapters/index.js b/scripts/adapters/index.js
index 26f1875..d82c5e7 100644
--- a/scripts/adapters/index.js
+++ b/scripts/adapters/index.js
@@ -23,6 +23,7 @@ const ADAPTERS = {
schumacher: require('./schumacher'), // vault-portal (WIRED; parked/dim — quote-only line, portal exposes no live stock signal)
fabricut: require('./fabricut'), // vault-portal (WIRED; parked/dim — price-oriented, no stock field; catalog too small)
contrado: require('./contrado'), // made-to-order (WIRED; parked/dim — print-on-demand, no live stock signal exists)
+ 'kravet-db': require('./kravet-db'), // $0 DB read — Kravet-family authoritative MAP price file (no Browserbase session)
};
function get(key) { return ADAPTERS[key] || null; }
diff --git a/scripts/adapters/kravet-db.js b/scripts/adapters/kravet-db.js
new file mode 100644
index 0000000..decb1a9
--- /dev/null
+++ b/scripts/adapters/kravet-db.js
@@ -0,0 +1,79 @@
+// adapters/kravet-db.js — Kravet-family AUTHORITATIVE-PRICE adapter ($0 DB read, tier DB_AUTHORITATIVE).
+//
+// The Kravet umbrella (Kravet / Lee Jofa / Brunschwig & Fils / Cole & Son / GP & J Baker /
+// Gaston y Daniela / Threads / Baker Lifestyle / Kravet Couture / Kravet Design / Lee Jofa Modern)
+// publishes NO live portal stock — but Kravet emails DW an authoritative price-adjustment file,
+// ingested daily by the kravet-price-watch skill into dw_unified.kravet_authoritative_pricing
+// (mfr_sku → new_whls / new_map). So the honest "live" signal for these lines is the AUTHORITATIVE
+// MAP price: instant, $0, no Browserbase session (session_opened:false → the server bills nothing).
+//
+// PUBLIC-SAFE CONTRACT: this adapter emits ONLY the MAP-derived RETAIL price. new_whls (wholesale)
+// is read solely to derive MAP when new_map is null (standing Kravet rule: MAP = wholesale × 1.5)
+// and NEVER included in the returned object.
+//
+// SKU resolution: the grid passes a display sku (dw_sku / variant_sku / mfr code). Bridge through
+// shopify_products to recover the row's mfr_sku (Kravet format e.g. "34971.13.0"), then match
+// kravet_authoritative_pricing on upper() with cheap format fallbacks (±trailing ".0").
+
+// Candidate pricing-table keys for one raw sku string (Kravet dot format: "34971.13.0").
+function candidateKeys(raw) {
+ const keys = new Set();
+ const s = String(raw || '').trim().toUpperCase();
+ if (!s) return keys;
+ keys.add(s);
+ // ±trailing ".0" — shopify rows usually carry it, but tolerate either side missing it.
+ if (s.endsWith('.0')) keys.add(s.slice(0, -2)); else keys.add(s + '.0');
+ // leading pattern code (mirrors resolve.js's compound-SKU extraction — dash AND dot shapes).
+ const lead = s.match(/^[A-Z]*[0-9]+[-.][0-9A-Z]+/);
+ if (lead && lead[0] !== s) { keys.add(lead[0]); keys.add(lead[0] + '.0'); }
+ return keys;
+}
+
+async function run({ sku, pool, log }) {
+ try {
+ // 1. Recover the display row's dw_sku + mfr_sku (the pricing table keys on the mfr code).
+ const keys = candidateKeys(sku);
+ try {
+ const { rows } = await pool.query(
+ `SELECT dw_sku, mfr_sku, vendor FROM shopify_products
+ WHERE upper(coalesce(dw_sku,''))=upper($1) OR upper(coalesce(variant_sku,''))=upper($1)
+ OR upper(coalesce(sku,''))=upper($1) LIMIT 1`, [sku]);
+ if (rows[0]) {
+ for (const k of candidateKeys(rows[0].dw_sku)) keys.add(k);
+ for (const k of candidateKeys(rows[0].mfr_sku)) keys.add(k);
+ }
+ } catch { /* shopify_products bridge optional — raw-sku keys still tried */ }
+ if (!keys.size) return { available: false, session_opened: false, reason: 'sku required' };
+
+ // 2. Authoritative price row — exact upper() match on any candidate key.
+ const { rows: hits } = await pool.query(
+ `SELECT mfr_sku, new_map, new_whls, loaded_at FROM kravet_authoritative_pricing
+ WHERE upper(mfr_sku)=ANY($1) LIMIT 1`, [[...keys]]);
+ if (!hits.length) {
+ return { available: false, session_opened: false,
+ reason: 'SKU not in the Kravet authoritative price file' };
+ }
+ const r = hits[0];
+ // MAP retail only — new_map when present, else derive wholesale × 1.5 (standing Kravet MAP rule).
+ const price = r.new_map != null ? +(+r.new_map).toFixed(2)
+ : (r.new_whls != null ? Math.round(+r.new_whls * 1.5 * 100) / 100 : null);
+ if (price == null) {
+ return { available: false, session_opened: false,
+ reason: 'price file row has no MAP or wholesale to derive from' };
+ }
+ if (log) log('kravet-db hit', r.mfr_sku);
+ // PUBLIC-SAFE: MAP-derived retail ONLY — new_whls/wholesale is never emitted.
+ return {
+ available: true, session_opened: false, vendor: null,
+ in_stock: null, lead_time: null,
+ price,
+ raw_stock_label: 'authoritative price (Kravet price file)',
+ as_of: r.loaded_at ? new Date(r.loaded_at).toISOString() : new Date().toISOString(),
+ source: 'kravet_authoritative_pricing',
+ };
+ } catch (e) {
+ return { available: false, session_opened: false, reason: 'kravet-db lookup error: ' + (e.message || e) };
+ }
+}
+
+module.exports = { run };
diff --git a/scripts/build-coverage.js b/scripts/build-coverage.js
index 574aecf..370658a 100644
--- a/scripts/build-coverage.js
+++ b/scripts/build-coverage.js
@@ -100,8 +100,20 @@ const SCHEMA_PARSE_PENDING = new Map([
// Portals that require a login AND publish only PRICE (a wholesale price sheet / SFTP feed), never
// live inventory — enabling a metered scrape would burn a session to read a price we can't surface.
// Honest dim: creds may exist, but the portal has no live-stock signal to read.
-const NO_LIVE_STOCK_PORTAL = new Set([
- 'kravet', // Kravet SFTP master = MAP/wholesale price sheet only; no per-SKU live inventory
+// (Kravet moved OUT of here 2026-07-15 — its price sheet is now the AUTHORITATIVE signal, served
+// $0/instant by the kravet-db adapter via the KRAVET_FAMILY / DB_AUTHORITATIVE branch below.)
+const NO_LIVE_STOCK_PORTAL = new Set([]);
+
+// KRAVET FAMILY → DB_AUTHORITATIVE. Kravet emails DW an authoritative price-adjustment file
+// (kravet-price-watch skill → dw_unified.kravet_authoritative_pricing: mfr_sku → new_whls/new_map),
+// so every Kravet-umbrella line gets a $0, instant, session-free live check that returns the
+// authoritative MAP price (standing rule: MAP = wholesale × 1.5). Keys are norm()'d display-vendor
+// names as they appear in dw_unified. NOT donghia — 0 matches in kravet_authoritative_pricing;
+// it stays QUOTE_ONLY. 'g p & j baker' is the alternate spacing dw_unified also carries.
+const KRAVET_FAMILY = new Set([
+ 'kravet', 'kravet couture', 'kravet design', 'lee jofa', 'lee jofa modern',
+ 'brunschwig & fils', 'gp & j baker', 'g p & j baker', 'baker lifestyle',
+ 'gaston y daniela', 'cole & son', 'threads',
]);
// Login-gated vendors whose trade creds live in the dw-price-stock credential vault (referenced IN
@@ -230,6 +242,14 @@ async function main() {
// mostly mis-route and could associate the private label with a real vendor's site. Only 1:1
// matches (exact / suffix-strip) earn a public-stock adapter; buckets stay dim unless WallQuest-backed.
const oneToOne = method === 'exact' || method === 'suffix-strip';
+ // -1. KRAVET FAMILY → DB_AUTHORITATIVE (FIRST — precedes QUOTE_ONLY and every portal branch).
+ // The authoritative Kravet price file (daily email ingest) answers instantly at $0 with no
+ // Browserbase session; resolvability is gated on kapMatchCount (mfr_sku present in
+ // kravet_authoritative_pricing), not on a catalog product_url join.
+ if (KRAVET_FAMILY.has(v))
+ return { tier: 'DB_AUTHORITATIVE', live_capable: true, adapter: 'kravet-db',
+ reason: 'authoritative Kravet price file (daily email ingest — $0, instant)',
+ catalog_table: (backing && backing.catalog_table) || null, resolves_by: 'kap' };
// 0. WallQuest-backed private labels that don't resolve through vendor_registry — the grid
// shows the private-label name; SKUs live in wallquest_catalog (the adapter looks them up).
if (WALLQUEST_ALIASES.has(v))
@@ -351,8 +371,26 @@ async function main() {
} catch { return { active: 0, resolvable: 0 }; }
}
+ // Resolvability gate for the DB_AUTHORITATIVE tier (kravet-db): "resolvable" = the vendor's
+ // ACTIVE grid SKUs whose mfr_sku EXISTS in kravet_authoritative_pricing (exact upper() match,
+ // ±trailing ".0" — mirroring the adapter's cheap format fallback). No product_url involved —
+ // the adapter answers from the price table itself.
+ async function kapMatchCount(vendor) {
+ try {
+ const { rows } = await pool.query(
+ `SELECT count(*) FILTER (WHERE upper(s.status)='ACTIVE')::int AS active,
+ count(*) FILTER (WHERE upper(s.status)='ACTIVE' AND EXISTS (
+ SELECT 1 FROM kravet_authoritative_pricing k
+ WHERE upper(k.mfr_sku)=upper(s.mfr_sku)
+ OR upper(k.mfr_sku)=upper(s.mfr_sku)||'.0'
+ OR upper(k.mfr_sku)||'.0'=upper(s.mfr_sku)))::int AS resolvable
+ FROM shopify_products s WHERE s.vendor = $1`, [vendor]);
+ return rows[0];
+ } catch { return { active: 0, resolvable: 0 }; }
+ }
+
const vendors = {};
- const counts = { PORTAL_CREDS: 0, PUBLIC_STOCK: 0, PORTAL_NO_CREDS: 0, QUOTE_ONLY: 0, NO_STOCK: 0, live_capable: 0 };
+ const counts = { DB_AUTHORITATIVE: 0, PORTAL_CREDS: 0, PUBLIC_STOCK: 0, PORTAL_NO_CREDS: 0, QUOTE_ONLY: 0, NO_STOCK: 0, live_capable: 0 };
for (const dv of displayVendors) {
const { row: backing, method } = resolve(dv.vendor);
const c = classify(dv.vendor, backing, method);
@@ -365,16 +403,20 @@ async function main() {
// Resolvability gate: only ENABLE a wired vendor whose display SKUs actually resolve to a PDP.
// Reconstruction adapters (Koroseal) are gated on mfr-key presence; all others on catalog product_url join.
if (entry.live_capable && entry.adapter) {
- const { active, resolvable } = c.resolves_by === 'mfr'
- ? await mfrKeyCount(dv.vendor)
- : await resolvableCount(dv.vendor, entry.catalog_table);
+ const { active, resolvable } = c.resolves_by === 'kap'
+ ? await kapMatchCount(dv.vendor)
+ : c.resolves_by === 'mfr'
+ ? await mfrKeyCount(dv.vendor)
+ : await resolvableCount(dv.vendor, entry.catalog_table);
entry.resolvable_active = resolvable;
entry.resolvable_pct = active ? Math.round((resolvable / active) * 100) : 0;
if (!(resolvable >= 5 && entry.resolvable_pct >= 20)) {
entry.live_capable = false;
- entry.reason = c.resolves_by === 'mfr'
- ? `adapter wired (${entry.adapter}) but too few Koroseal SKUs carry an mfr code to reconstruct a PDP (${resolvable} of ${active} active)`
- : `adapter wired (${entry.adapter}) but display SKUs don't align with the ${entry.catalog_table} catalog (${resolvable} of ${active} active resolvable) — needs SKU remap`;
+ entry.reason = c.resolves_by === 'kap'
+ ? `adapter wired (${entry.adapter}) but too few SKUs match the Kravet authoritative price file (${resolvable} of ${active} active)`
+ : c.resolves_by === 'mfr'
+ ? `adapter wired (${entry.adapter}) but too few Koroseal SKUs carry an mfr code to reconstruct a PDP (${resolvable} of ${active} active)`
+ : `adapter wired (${entry.adapter}) but display SKUs don't align with the ${entry.catalog_table} catalog (${resolvable} of ${active} active resolvable) — needs SKU remap`;
}
}
if (entry.live_capable) entry.verified = VERIFIED[dv.vendor] || 'wired — not yet live-verified';
@@ -397,7 +439,7 @@ async function main() {
fs.writeFileSync(OUT, JSON.stringify(out, null, 2));
console.log(`coverage → ${OUT}`);
console.log(` ${out.total_display_vendors} display-vendors | live-capable ${counts.live_capable}`);
- console.log(` PORTAL_CREDS ${counts.PORTAL_CREDS} · PUBLIC_STOCK ${counts.PUBLIC_STOCK} · PORTAL_NO_CREDS ${counts.PORTAL_NO_CREDS} · QUOTE_ONLY ${counts.QUOTE_ONLY} · NO_STOCK ${counts.NO_STOCK}`);
+ console.log(` DB_AUTHORITATIVE ${counts.DB_AUTHORITATIVE} · PORTAL_CREDS ${counts.PORTAL_CREDS} · PUBLIC_STOCK ${counts.PUBLIC_STOCK} · PORTAL_NO_CREDS ${counts.PORTAL_NO_CREDS} · QUOTE_ONLY ${counts.QUOTE_ONLY} · NO_STOCK ${counts.NO_STOCK}`);
}
main().catch((e) => { console.error('coverage build failed:', e.message); process.exit(1); });
diff --git a/scripts/live-scrape.js b/scripts/live-scrape.js
index 69aaf8a..6a75ea1 100644
--- a/scripts/live-scrape.js
+++ b/scripts/live-scrape.js
@@ -70,9 +70,15 @@ function catalogForKey(key) {
if (!ADAPTER_KEY) return emit({ available: false, reason: 'live check unavailable for this vendor' });
}
// Load the Browserbase helpers (present only where the backend is installed).
+ // DB adapters ($0, in-Postgres reads — no browser session) run WITHOUT the Browserbase lib:
+ // its absence only blocks adapters that actually need a metered session.
+ const DB_ADAPTERS = new Set(['kravet-db']);
let newSession, romoLogin;
try { const lib = require(BB_LIB); newSession = lib.newSession; romoLogin = lib.login; }
- catch { return emit({ available: false, reason: 'live scrape backend not available on this host' }); }
+ catch {
+ if (!DB_ADAPTERS.has(ADAPTER_KEY)) return emit({ available: false, reason: 'live scrape backend not available on this host' });
+ newSession = undefined; romoLogin = undefined;
+ }
const result = await adapters.run(ADAPTER_KEY, { sku: SKU, pool, newSession, romoLogin, catalogTable, log });
return emit(result);
diff --git a/server.js b/server.js
index 7c56026..35028ff 100644
--- a/server.js
+++ b/server.js
@@ -857,14 +857,17 @@ function runLiveScrape(sku, adapterKey, catalogTable) {
}
return resolve({ ok: false, live: true, live_available: false, sku, reason: parsed.reason || 'live check unavailable for this vendor', cost_usd: 0 });
}
- const cost = +(elapsedMin * BB_RATE_PER_MIN).toFixed(4);
- logBrowserbase(elapsedMin, sku);
+ // $0 DB-adapter path (kravet-db etc.): no Browserbase session ever opened → no cost,
+ // no ledger entry, no live-spend.json increment. Only session-opened scrapes bill.
+ const opened = parsed.session_opened !== false;
+ const cost = opened ? +(elapsedMin * BB_RATE_PER_MIN).toFixed(4) : 0;
+ if (opened) logBrowserbase(elapsedMin, sku);
resolve({
ok: true, live: true, cached: false, sku, vendor: parsed.vendor || null,
in_stock: parsed.in_stock ?? null, lead_time: parsed.lead_time || null,
price: parsed.price ?? null, availability: parsed.raw_stock_label || null,
as_of: parsed.as_of || new Date().toISOString(), source: parsed.source || 'vendor-live',
- cost_usd: cost, session_min: +elapsedMin.toFixed(2),
+ cost_usd: cost, session_min: opened ? +elapsedMin.toFixed(2) : 0,
});
});
});
@@ -965,8 +968,10 @@ async function handleLiveStock(req, res, u) {
// ── DAILY $ KILL-SWITCH — the TOTAL ceiling the rate limits don't provide ──
// Checked AFTER cache/coalesce (those are free) but BEFORE any new billable session. When the
// day's summed spend hits the cap, hard-stop at $0 — no Browserbase session is ever opened.
+ // DB_AUTHORITATIVE tier is EXEMPT from the $-cap ONLY (it opens no billable session — a pure
+ // local Postgres read); the per-IP rate limit and inflight cap below still apply to it.
const daySpend = daySpendUSD();
- if (daySpend >= DAILY_LIVE_CAP_USD) {
+ if (cov.tier !== 'DB_AUTHORITATIVE' && daySpend >= DAILY_LIVE_CAP_USD) {
return sendJSON(res, 200, { ok: false, live: true, live_available: false, sku,
vendor: row ? row.vendor : null, tier: cov ? cov.tier : null,
reason: `daily live-stock budget reached ($${daySpend.toFixed(2)}/$${DAILY_LIVE_CAP_USD.toFixed(2)})`,
← 016fb39 chore: vendor_contacts self-heal DDL, microsites compose val
·
back to All Designerwallcoverings
·
Every SKU card gets a smart face button: live price check (t 750e7f4 →