← back to Tk11438 Postgres Migration
Verify existing Gracie domain and All-DW catalog link
469a2b2e3a1e462d2400236b3b44025d4f9667c1 · 2026-09-11 14:42:55 -0700 · Steve Abrams
Files touched
A verification/tk11517-domain/all-gracie.pngA verification/tk11517-domain/browser-check.cjsA verification/tk11517-domain/browser-proof.jsonA verification/tk11517-domain/directory-review.jsonA verification/tk11517-domain/e2e-proof.jsonA verification/tk11517-domain/gracie-live.pngA verification/tk11517-domain/live-verification.jsonA verification/tk11517-domain/urllib-verification.jsonA verification/tk11517-domain/verify-existing.py
Diff
commit 469a2b2e3a1e462d2400236b3b44025d4f9667c1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Sep 11 14:42:55 2026 -0700
Verify existing Gracie domain and All-DW catalog link
---
verification/tk11517-domain/all-gracie.png | Bin 0 -> 85555 bytes
verification/tk11517-domain/browser-check.cjs | 28 +++
verification/tk11517-domain/browser-proof.json | 33 ++++
verification/tk11517-domain/directory-review.json | 200 +++++++++++++++++++
verification/tk11517-domain/e2e-proof.json | 62 ++++++
verification/tk11517-domain/gracie-live.png | Bin 0 -> 71139 bytes
verification/tk11517-domain/live-verification.json | 212 +++++++++++++++++++++
.../tk11517-domain/urllib-verification.json | 168 ++++++++++++++++
verification/tk11517-domain/verify-existing.py | 46 +++++
9 files changed, 749 insertions(+)
diff --git a/verification/tk11517-domain/all-gracie.png b/verification/tk11517-domain/all-gracie.png
new file mode 100644
index 0000000..0ac12bf
Binary files /dev/null and b/verification/tk11517-domain/all-gracie.png differ
diff --git a/verification/tk11517-domain/browser-check.cjs b/verification/tk11517-domain/browser-check.cjs
new file mode 100644
index 0000000..029f7e5
--- /dev/null
+++ b/verification/tk11517-domain/browser-check.cjs
@@ -0,0 +1,28 @@
+const fs=require('fs'),assert=require('assert/strict');
+const {chromium}=require('/Users/macstudio3/.agents/skills/hero-readability-auditor/node_modules/playwright');
+const src=fs.readFileSync('/Users/macstudio3/Projects/all-designerwallcoverings/server.js','utf8');
+const auth=src.match(/['"](admin:[^'"]+)['"]/)[1];
+const hosts=new Set(['all.designerwallcoverings.com','gracie-internal.designerwallcoverings.com']);
+const profile='/tmp/tk11517-browser-profile',out='/tmp/tk11517-browser-proof.json';
+fs.mkdirSync(profile,{recursive:true,mode:0o700});fs.chmodSync(profile,0o700);
+(async()=>{
+ const browser=await chromium.launchPersistentContext(profile,{channel:'chrome',headless:false,viewport:{width:1440,height:1000}});
+ const proof={ticket:'TK-11517',at:new Date().toISOString(),checks:[],application_mutations:0,email_sends:0},errors=[];
+ try{
+ await browser.route('**/*',async route=>{const request=route.request(),headers={...request.headers()};if(hosts.has(new URL(request.url()).hostname))headers.authorization='Basic '+Buffer.from(auth).toString('base64');else delete headers.authorization;await route.continue({headers});});
+ const page=await browser.newPage();page.on('pageerror',e=>errors.push(e.message));
+ const response=await page.goto('https://all.designerwallcoverings.com/microsites.html',{waitUntil:'domcontentloaded',timeout:30000});assert.equal(response.status(),200);
+ // The grid renders batches. Search before waiting for a card beyond the first batch.
+ await page.locator('#q').waitFor({state:'visible'});await page.locator('#fFeeds').click();
+ await page.locator('#q').fill('gracie');
+ const card=page.locator('a.card[href="https://gracie-internal.designerwallcoverings.com/"]');await card.waitFor({state:'visible',timeout:30000});assert.equal(await card.count(),1);
+ proof.checks.push({name:'Gracie visible under With Catalogs after search',pass:true});
+ const text=await card.innerText();assert(text.includes('150'));proof.checks.push({name:'Search Gracie yields unique internal card with150products',pass:true,text});
+ await page.screenshot({path:'/tmp/tk11517-all-gracie.png',fullPage:false});
+ const [popup]=await Promise.all([page.waitForEvent('popup'),card.click()]);await popup.waitForURL('https://gracie-internal.designerwallcoverings.com/**',{waitUntil:'domcontentloaded',timeout:30000});assert.equal(new URL(popup.url()).hostname,'gracie-internal.designerwallcoverings.com');await popup.waitForFunction(()=>document.body.innerText.includes('Gracie'),null,{timeout:15000});
+ const api=await popup.evaluate(async()=>{const r=await fetch('/api/products');const d=await r.json();return{status:r.status,count:d.count};});assert.equal(api.status,200);assert.equal(api.count,150);
+ proof.checks.push({name:'Actual directory click opens authenticated Gracie with150products',pass:true,url:popup.url(),title:await popup.title(),api});
+ await popup.screenshot({path:'/tmp/tk11517-gracie-live.png',fullPage:false});proof.page_errors=errors;assert.equal(errors.length,0);
+ proof.verdict='PASS';proof.screenshots=['/tmp/tk11517-all-gracie.png','/tmp/tk11517-gracie-live.png'];
+ }catch(e){proof.verdict='FAIL';proof.error=e.message;const p=browser.pages().at(-1);if(p){proof.page={url:p.url(),text:(await p.locator('body').innerText()).slice(0,1800)};await p.screenshot({path:'/tmp/tk11517-browser-failure.png'}).catch(()=>{});}process.exitCode=1;}finally{fs.writeFileSync(out,JSON.stringify(proof,null,2)+'\n');await browser.close();console.log(JSON.stringify(proof,null,2));}
+})().catch(e=>{console.error(e.message);process.exitCode=1;});
diff --git a/verification/tk11517-domain/browser-proof.json b/verification/tk11517-domain/browser-proof.json
new file mode 100644
index 0000000..f3b872c
--- /dev/null
+++ b/verification/tk11517-domain/browser-proof.json
@@ -0,0 +1,33 @@
+{
+ "ticket": "TK-11517",
+ "at": "2026-09-11T21:40:04.019Z",
+ "checks": [
+ {
+ "name": "Gracie visible under With Catalogs after search",
+ "pass": true
+ },
+ {
+ "name": "Search Gracie yields unique internal card with150products",
+ "pass": true,
+ "text": "150 DESIGNS\nG\nGracie — Internal Line Viewer\n150 DESIGNS\nCREATED 🕓 —\nVISIT MICROSITE →\n✉ STOCK & PRICE"
+ },
+ {
+ "name": "Actual directory click opens authenticated Gracie with150products",
+ "pass": true,
+ "url": "https://gracie-internal.designerwallcoverings.com/",
+ "title": "Gracie — Internal Line Viewer",
+ "api": {
+ "status": 200,
+ "count": 150
+ }
+ }
+ ],
+ "application_mutations": 0,
+ "email_sends": 0,
+ "page_errors": [],
+ "verdict": "PASS",
+ "screenshots": [
+ "/tmp/tk11517-all-gracie.png",
+ "/tmp/tk11517-gracie-live.png"
+ ]
+}
diff --git a/verification/tk11517-domain/directory-review.json b/verification/tk11517-domain/directory-review.json
new file mode 100644
index 0000000..4a7a64f
--- /dev/null
+++ b/verification/tk11517-domain/directory-review.json
@@ -0,0 +1,200 @@
+{
+ "ticket": "TK-11517-serve-authenticated-gracie-internal-doma",
+ "status": "complete-read-only-review",
+ "reviewed_at": "2026-09-11T20:44:19.132920+00:00",
+ "source_root": "/Users/macstudio3/Projects/all-designerwallcoverings",
+ "artifact_only_mutation": true,
+ "changes": [],
+ "scope": "Local source and existing JSON snapshots only; no crawler, app restart, remote request, DB query or send.",
+ "directory": {
+ "ui_url": "https://all.designerwallcoverings.com/microsites.html",
+ "api_url": "https://all.designerwallcoverings.com/api/microsites",
+ "ui_entrypoint": "public/index.html:303 microsites link",
+ "api_shape": {
+ "top_level": [
+ "crawled_at",
+ "took_ms",
+ "total_candidates",
+ "up",
+ "with_feed",
+ "with_handles",
+ "total_handles",
+ "products",
+ "sites",
+ "merged",
+ "vendor_pairs"
+ ],
+ "gracie_site_required": [
+ "slug",
+ "host",
+ "url",
+ "type",
+ "vendor",
+ "up",
+ "status",
+ "title",
+ "productCount",
+ "feed",
+ "products",
+ "handles",
+ "handleCount",
+ "created_at"
+ ]
+ },
+ "client_filters": {
+ "initial": "sites.filter(s => s.up)",
+ "default": "localStorage.adwm_filter or feeds; feeds requires s.feed",
+ "all_sites_button": "#fAll (All Live Sites), persists adwm_filter=all",
+ "catalogs_button": "#fFeeds (With Catalogs)",
+ "search": "#q input, client state only; matches slug/title/vendor. No query-string initialization.",
+ "card_selector": "a.card[href=\"https://gracie-internal.designerwallcoverings.com/\"]",
+ "click": "target=_blank to s.url",
+ "gate_display": "status===401 renders Trade Access badge and Trade-Gated field"
+ }
+ },
+ "existing_seeds": {
+ "brand": [
+ {
+ "slug": "gracie",
+ "vendor": "Gracie",
+ "knownProject": "~/Projects/dw-vendor-microsites/vendors/gracie",
+ "note": "ONBOARDING/STAGING 2026-07-09 \u2014 ultra-luxury hand-painted scenic & chinoiserie wallpaper panels (Gracie Studio, est. 1898). 150 patterns in gracie_catalog (feed-first Next.js/Sanity page-data, $0). QUOTE-ONLY bespoke. Shopify DRAFT import gated (DWGA-, MANDATORY settlement-gate \u2014 chinoiserie is bird/butterfly/botanical heavy). Microsite deploy + DNS gated.",
+ "hasMicrosite": true,
+ "internalViewer": "http://127.0.0.1:10104 (~/Projects/gracie-internal, pm2 gracie-internal)"
+ }
+ ],
+ "internal": [
+ {
+ "slug": "gracie-internal",
+ "label": "Gracie \u2014 internal curation viewer",
+ "note": "dw-vendor-microsites gracie internal viewer; Kamatera pm2 gracie-internal on :10105"
+ }
+ ],
+ "already_seeded": true,
+ "internal_issue": "Internal seed lacks internalViewer; note mentions obsolete10105. Brand seed already has10104. seedFromRegistry forwards internalViewer but ignores internal note (uses label)."
+ },
+ "local_snapshot": {
+ "crawled_at": "2026-09-11T20:42:57.360Z",
+ "sites": [
+ {
+ "slug": "gracie",
+ "host": "gracie.designerwallcoverings.com",
+ "url": "https://gracie.designerwallcoverings.com/",
+ "type": "brand",
+ "vendor": "Gracie",
+ "note": "ONBOARDING/STAGING 2026-07-09 \u2014 ultra-luxury hand-painted scenic & chinoiserie wallpaper panels (Gracie Studio, est. 1898). 150 patterns in gracie_catalog (feed-first Next.js/Sanity page-data, $0). QUOTE-ONLY bespoke. Shopify DRAFT import gated (DWGA-, MANDATORY settlement-gate \u2014 chinoiserie is bird/butterfly/botanical heavy). Microsite deploy + DNS gated.",
+ "pairSlug": null,
+ "variant": null,
+ "source": null,
+ "created_at": null,
+ "activeProductsDB": null,
+ "up": true,
+ "status": 401,
+ "finalUrl": "https://gracie.designerwallcoverings.com/",
+ "title": "Gracie",
+ "hero": null,
+ "productCount": 0,
+ "feed": false,
+ "handleCount": 0
+ },
+ {
+ "slug": "gracie-internal",
+ "host": "gracie-internal.designerwallcoverings.com",
+ "url": "https://gracie-internal.designerwallcoverings.com/",
+ "type": "internal",
+ "vendor": null,
+ "note": "Gracie \u2014 internal curation viewer",
+ "pairSlug": null,
+ "variant": null,
+ "source": null,
+ "created_at": null,
+ "activeProductsDB": null,
+ "up": true,
+ "status": 401,
+ "finalUrl": "https://gracie-internal.designerwallcoverings.com/",
+ "title": "gracie-internal",
+ "hero": null,
+ "productCount": 0,
+ "feed": false,
+ "handleCount": 0
+ }
+ ],
+ "scope_limit": "Local generated snapshot is not proof of current production state."
+ },
+ "crawl_behavior": {
+ "401": "Healthy up=true, but no product feed is fetched for public401 unless explicit localhost internalViewer exists or unified vendor-pair logic applies.",
+ "localhost_feed": "internalViewer regex extracts http://127.0.0.1:PORT or localhost; probes /api/products?limit=100000 then /api/skus?limit=100000&all=1.",
+ "feed_shapes": "products endpoint: rows[] or products[], count from total/count; skus endpoint: rows[] or skus[], count from total/all/count. Nonempty array required.",
+ "refresh": "Server starts crawl after initial snapshot and repeats every10minutes (30sec offset). API serves generated file with mtime cache.",
+ "pair_caveat": "If production vendors snapshot includes Gracie, paired internal variant can merge with registry; when variant and up, crawler uses activeProductsDB and skips actual feed. Verify production rec.variant and activeProductsDB before assuming internalViewer alone resolves empty feeds.",
+ "pm2_caveat": "seedFromPm2 strips -internal, so gracie-internal process fills gracie seed, not gracie-internal. Local source uses hard-coded Mac serialized PM2 helper; do not rely on it on Kamatera."
+ },
+ "reviewable_fix_if_production_matches": {
+ "file": "config/known-subdomains.json",
+ "entry": "internal[slug=gracie-internal]",
+ "add_field": {
+ "internalViewer": "http://127.0.0.1:10104 (~/Projects/gracie-internal, pm2 gracie-internal)"
+ },
+ "correct_note": "Replace obsolete10105 reference with verified10104; informational only.",
+ "avoid_duplicate": "Do not add another gracie-internal entry; existing entry already seeds hostname.",
+ "identity_limitation": "seedFromRegistry currently sets vendor=null for every internal entry; simply adding vendor to JSON will not create vendor drill-through. Not needed for hostname card."
+ },
+ "parent_e2e_assertions": [
+ "Read production registry and /api/microsites before changing anything.",
+ "Verify unique gracie-internal record URL matches authenticated hostname and up is true.",
+ "If goal includes default directory visibility, verify feed true and productCount positive.",
+ "Open /microsites.html, select All Live Sites, type gracie, assert intended card and link.",
+ "Verify With Catalogs shows card after feed integration.",
+ "Click card; assert Gracie authenticated page and unauthenticated401/noindex independently.",
+ "Check positive handleCount and actual feed schema only if product membership needed; do not infer from health200."
+ ],
+ "deployment_rule": "CLAUDE.md: targeted changed files only; never sync data/ or full tree, never --delete. Parent owns any authorized rollout.",
+ "separate_grid_note": "server.js defaults microsite product-grid Gracie feed to10073, independently overrideable with MICROSITE_FEED_PORTS; this is distinct from directory registry10104. Check existing production override only if grid ingestion is in scope.",
+ "evidence_lines": {
+ "registry": [
+ 68,
+ 73,
+ 125,
+ 127
+ ],
+ "scripts/crawl-microsites.js": [
+ 49,
+ 53,
+ 60,
+ 76,
+ 213,
+ 235,
+ 341,
+ 386,
+ 408,
+ 423,
+ 455,
+ 469
+ ],
+ "public/microsites.html": [
+ 187,
+ 264,
+ 321,
+ 350,
+ 360,
+ 473,
+ 477,
+ 478
+ ],
+ "server.js": [
+ 546,
+ 559,
+ 1033,
+ 1718,
+ 1745,
+ 1747
+ ]
+ },
+ "source_sha256": {
+ "server.js": "8d7265e888960fb0e8a298bb0f97e4d5c154baa57352f62524b4b607ebe74e0d",
+ "scripts/crawl-microsites.js": "a5f4f54eee686e64f72d9460573c2dd2f309eb5bd0dcf7a9efeaf99a1fef941f",
+ "public/microsites.html": "73113595c8061f11a067b88bfe1b85c210cc3ab2850f2c65cf060b68fa33db1b",
+ "config/known-subdomains.json": "9abea7bb19e0c2f29e45c286a35ec599a78ef3b05f5917b55767a5e7f6822f0f",
+ "lib/vendor-pairs.js": "b2c4c9fc9f00cb194a17f9f1b5583ada7823439c1c6e714c185b6e79c22ffc4f"
+ }
+}
diff --git a/verification/tk11517-domain/e2e-proof.json b/verification/tk11517-domain/e2e-proof.json
new file mode 100644
index 0000000..e6bfc2f
--- /dev/null
+++ b/verification/tk11517-domain/e2e-proof.json
@@ -0,0 +1,62 @@
+{
+ "ticket": "TK-11517-serve-authenticated-gracie-internal-doma",
+ "at": "2026-09-11T21:42:55.065339+00:00",
+ "verdict": "PASS",
+ "risk_tier": "R3 authenticated read-only verification",
+ "intent": "Serve Gracie authenticated hostname and include its working link in All-DW",
+ "outcome": "Existing production deployment and directory already fulfill request; no duplicate/redeploy needed",
+ "gracie_url": "https://gracie-internal.designerwallcoverings.com/",
+ "directory_url": "https://all.designerwallcoverings.com/microsites.html",
+ "entry": {
+ "slug": "gracie-internal",
+ "url": "https://gracie-internal.designerwallcoverings.com/",
+ "type": "internal",
+ "vendor": null,
+ "variant": null,
+ "up": true,
+ "status": 200,
+ "title": "Gracie \u2014 Internal Line Viewer",
+ "productCount": 150,
+ "feed": true,
+ "handleCount": 150
+ },
+ "http_checks": 15,
+ "browser_checks": [
+ {
+ "name": "Gracie visible under With Catalogs after search",
+ "pass": true
+ },
+ {
+ "name": "Search Gracie yields unique internal card with150products",
+ "pass": true,
+ "text": "150 DESIGNS\nG\nGracie \u2014 Internal Line Viewer\n150 DESIGNS\nCREATED \ud83d\udd53 \u2014\nVISIT MICROSITE \u2192\n\u2709 STOCK & PRICE"
+ },
+ {
+ "name": "Actual directory click opens authenticated Gracie with150products",
+ "pass": true,
+ "url": "https://gracie-internal.designerwallcoverings.com/",
+ "title": "Gracie \u2014 Internal Line Viewer",
+ "api": {
+ "status": 200,
+ "count": 150
+ }
+ }
+ ],
+ "commands": [
+ "DNS resolution",
+ "SSH read nginx/current registry/snapshot",
+ "curl authenticated and negative HTTPS checks using stdin config",
+ "Isolated browser search,cardclick and GracieAPI proof"
+ ],
+ "application_mutations": 0,
+ "dns_mutations": 0,
+ "restarts": 0,
+ "email_sends": 0,
+ "private_access": "Both sites reject absent/invalid credentials401; validcredentials200; Gracie noindex/nofollow",
+ "notes": [
+ "Initial urllib client403 retained; standardcurl/browser pass without edge changes",
+ "Directory uses batched rendering; search used before locating card",
+ "Mac Gracie socket migration retained; Kamatera existing service remains on10104",
+ "TK11438 parent fleet migration remains incomplete and is not closed"
+ ]
+}
diff --git a/verification/tk11517-domain/gracie-live.png b/verification/tk11517-domain/gracie-live.png
new file mode 100644
index 0000000..4044792
Binary files /dev/null and b/verification/tk11517-domain/gracie-live.png differ
diff --git a/verification/tk11517-domain/live-verification.json b/verification/tk11517-domain/live-verification.json
new file mode 100644
index 0000000..c643a87
--- /dev/null
+++ b/verification/tk11517-domain/live-verification.json
@@ -0,0 +1,212 @@
+{
+ "task": "TK-11517",
+ "checks": [
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/",
+ "auth": "missing",
+ "status": 401,
+ "bytes": 1434,
+ "body_sha256": "521ada55b4a198d82072e94b63e7f4a1d38aae6a2e578159c0c9f37de853d9c0",
+ "robots": "noindex, nofollow"
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/",
+ "auth": "invalid",
+ "status": 401,
+ "bytes": 1436,
+ "body_sha256": "c55cdcbc1b0c66319c6955776946478e9facad613e0189eb2c8be57a786a4c90",
+ "robots": "noindex, nofollow"
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/",
+ "auth": "valid",
+ "status": 200,
+ "bytes": 23971,
+ "body_sha256": "c8c84f1799108c59b64994427690aec1f440b0ede9b0cac15bbc2776a46b7088",
+ "robots": "noindex, nofollow"
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/api/products",
+ "auth": "missing",
+ "status": 401,
+ "bytes": 1436,
+ "body_sha256": "0d593aedf0eaefe991533492b3547c85f8fe466e0c9a6b811a42980cec0538bc",
+ "robots": "noindex, nofollow"
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/api/products",
+ "auth": "invalid",
+ "status": 401,
+ "bytes": 1436,
+ "body_sha256": "27ce6a905e6dc33a2ea4f83e560f7990569bb1eec8e70fc2289c5294d5c932d0",
+ "robots": "noindex, nofollow"
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/api/products",
+ "auth": "valid",
+ "status": 200,
+ "bytes": 188603,
+ "body_sha256": "b01acb69f4bd1d7d3c64d4dead18b84cf7f7026e9a702a2e9a77b08f66940264",
+ "robots": "noindex, nofollow",
+ "count": 150
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/",
+ "auth": "missing",
+ "status": 401,
+ "bytes": 23,
+ "body_sha256": "0fcfb12dfad07ba0b1ab80f7cd6c6c3c5aaea0804be09faee6ca0819e3769659",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/",
+ "auth": "invalid",
+ "status": 401,
+ "bytes": 23,
+ "body_sha256": "0fcfb12dfad07ba0b1ab80f7cd6c6c3c5aaea0804be09faee6ca0819e3769659",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/",
+ "auth": "valid",
+ "status": 200,
+ "bytes": 91422,
+ "body_sha256": "3644f6a9339f86828b9da9073a950ffecefb03b64d3ff7339fbea161ee79fdbc",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/api/microsites",
+ "auth": "missing",
+ "status": 401,
+ "bytes": 23,
+ "body_sha256": "0fcfb12dfad07ba0b1ab80f7cd6c6c3c5aaea0804be09faee6ca0819e3769659",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/api/microsites",
+ "auth": "invalid",
+ "status": 401,
+ "bytes": 23,
+ "body_sha256": "0fcfb12dfad07ba0b1ab80f7cd6c6c3c5aaea0804be09faee6ca0819e3769659",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/api/microsites",
+ "auth": "valid",
+ "status": 200,
+ "bytes": 2803018,
+ "body_sha256": "55e324df62785b363fb1c3e6313d480e49d1a32cfe77a9bd0a399e2dc68c378f",
+ "robots": null,
+ "response_keys": [
+ "crawled_at",
+ "took_ms",
+ "total_candidates",
+ "up",
+ "with_feed",
+ "with_handles",
+ "total_handles",
+ "products",
+ "sites",
+ "merged",
+ "vendor_pairs"
+ ],
+ "sites_total": 1097,
+ "gracie": [
+ {
+ "slug": "gracie",
+ "url": "https://gracie.designerwallcoverings.com/",
+ "type": "brand",
+ "vendor": "Gracie",
+ "variant": null,
+ "up": true,
+ "status": 200,
+ "title": "Trade Lines",
+ "productCount": 150,
+ "feed": true,
+ "handleCount": 150
+ },
+ {
+ "slug": "gracie-internal",
+ "url": "https://gracie-internal.designerwallcoverings.com/",
+ "type": "internal",
+ "vendor": null,
+ "variant": null,
+ "up": true,
+ "status": 200,
+ "title": "Gracie \u2014 Internal Line Viewer",
+ "productCount": 150,
+ "feed": true,
+ "handleCount": 150
+ }
+ ],
+ "snapshot_timestamp": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/microsites.html",
+ "auth": "missing",
+ "status": 401,
+ "bytes": 23,
+ "body_sha256": "0fcfb12dfad07ba0b1ab80f7cd6c6c3c5aaea0804be09faee6ca0819e3769659",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/microsites.html",
+ "auth": "invalid",
+ "status": 401,
+ "bytes": 23,
+ "body_sha256": "0fcfb12dfad07ba0b1ab80f7cd6c6c3c5aaea0804be09faee6ca0819e3769659",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/microsites.html",
+ "auth": "valid",
+ "status": 200,
+ "bytes": 30280,
+ "body_sha256": "ad23b9f51ad7285778d4ca37eb0e17b99364d9e197ff21b2a41b3c54d8863865",
+ "robots": null
+ }
+ ],
+ "application_mutations": 0,
+ "email_sends": 0,
+ "registry_gracie": {
+ "brands": [
+ {
+ "slug": "gracie",
+ "vendor": "Gracie",
+ "knownProject": "~/Projects/dw-vendor-microsites/vendors/gracie",
+ "note": "ONBOARDING/STAGING 2026-07-09 \u2014 ultra-luxury hand-painted scenic & chinoiserie wallpaper panels (Gracie Studio, est. 1898). 150 patterns in gracie_catalog (feed-first Next.js/Sanity page-data, $0). QUOTE-ONLY bespoke. Shopify DRAFT import gated (DWGA-, MANDATORY settlement-gate \u2014 chinoiserie is bird/butterfly/botanical heavy). Microsite deploy + DNS gated.",
+ "hasMicrosite": true,
+ "internalViewer": "http://127.0.0.1:10104 (~/Projects/gracie-internal, pm2 gracie-internal)"
+ }
+ ],
+ "internal": [
+ {
+ "slug": "gracie-internal",
+ "label": "Gracie \u2014 internal curation viewer",
+ "note": "dw-vendor-microsites gracie internal viewer; Kamatera pm2 gracie-internal on :10105"
+ }
+ ]
+ },
+ "gracie_saved_metadata": {
+ "name": "gracie-internal",
+ "pm_exec_path": "/root/Projects/gracie-internal/server.js",
+ "pm_cwd": "/root/Projects/gracie-internal",
+ "PORT": "10104",
+ "DATA_SOURCE": "jsonl"
+ }
+}
diff --git a/verification/tk11517-domain/urllib-verification.json b/verification/tk11517-domain/urllib-verification.json
new file mode 100644
index 0000000..a32b671
--- /dev/null
+++ b/verification/tk11517-domain/urllib-verification.json
@@ -0,0 +1,168 @@
+{
+ "task": "TK-11517",
+ "checks": [
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/",
+ "auth": "missing",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/",
+ "auth": "invalid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/",
+ "auth": "valid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/api/products",
+ "auth": "missing",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/api/products",
+ "auth": "invalid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "gracie-internal.designerwallcoverings.com",
+ "route": "/api/products",
+ "auth": "valid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/",
+ "auth": "missing",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/",
+ "auth": "invalid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/",
+ "auth": "valid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/api/microsites",
+ "auth": "missing",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/api/microsites",
+ "auth": "invalid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/api/microsites",
+ "auth": "valid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/microsites.html",
+ "auth": "missing",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/microsites.html",
+ "auth": "invalid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ },
+ {
+ "host": "all.designerwallcoverings.com",
+ "route": "/microsites.html",
+ "auth": "valid",
+ "status": 403,
+ "bytes": 17,
+ "body_sha256": "2938e9f1284180959e33ab1718d0793a72ff6e4cdb8108c34dcd14e69446de5c",
+ "robots": null
+ }
+ ],
+ "application_mutations": 0,
+ "email_sends": 0,
+ "registry_gracie": {
+ "brands": [
+ {
+ "slug": "gracie",
+ "vendor": "Gracie",
+ "knownProject": "~/Projects/dw-vendor-microsites/vendors/gracie",
+ "note": "ONBOARDING/STAGING 2026-07-09 \u2014 ultra-luxury hand-painted scenic & chinoiserie wallpaper panels (Gracie Studio, est. 1898). 150 patterns in gracie_catalog (feed-first Next.js/Sanity page-data, $0). QUOTE-ONLY bespoke. Shopify DRAFT import gated (DWGA-, MANDATORY settlement-gate \u2014 chinoiserie is bird/butterfly/botanical heavy). Microsite deploy + DNS gated.",
+ "hasMicrosite": true,
+ "internalViewer": "http://127.0.0.1:10104 (~/Projects/gracie-internal, pm2 gracie-internal)"
+ }
+ ],
+ "internal": [
+ {
+ "slug": "gracie-internal",
+ "label": "Gracie \u2014 internal curation viewer",
+ "note": "dw-vendor-microsites gracie internal viewer; Kamatera pm2 gracie-internal on :10105"
+ }
+ ]
+ },
+ "gracie_saved_metadata": {
+ "name": "gracie-internal",
+ "pm_exec_path": "/root/Projects/gracie-internal/server.js",
+ "pm_cwd": "/root/Projects/gracie-internal",
+ "PORT": "10104",
+ "DATA_SOURCE": "jsonl"
+ }
+}
diff --git a/verification/tk11517-domain/verify-existing.py b/verification/tk11517-domain/verify-existing.py
new file mode 100644
index 0000000..fdbb4b3
--- /dev/null
+++ b/verification/tk11517-domain/verify-existing.py
@@ -0,0 +1,46 @@
+import base64,hashlib,json,pathlib,re,urllib.request,urllib.error,subprocess
+root=pathlib.Path('/root/Projects')
+dump=json.loads(pathlib.Path('/root/.pm2/dump.pm2').read_text())
+def effective(name):
+ rows=[x for x in dump if x.get('name')==name]
+ return rows[0] if len(rows)==1 else {}
+def fileenv(p):
+ if not p.exists():return {}
+ return {m[1]:m[2].strip().strip('"\'') for m in re.finditer(r'^([A-Z_][A-Z0-9_]*)=(.*)$',p.read_text(),re.M)}
+allroot=root/'all-designerwallcoverings';source=(allroot/'server.js').read_text()
+env={**fileenv(allroot/'.env'),**effective('all-designerwallcoverings')}
+auth=env.get('BASIC_AUTH') or (env.get('BASIC_AUTH_USER','')+':'+env.get('BASIC_AUTH_PASS','') if env.get('BASIC_AUTH_PASS') else None)
+auth=auth or re.search(r"['\"](admin:[^'\"]+)['\"]",source)[1]
+class NoRedirect(urllib.request.HTTPRedirectHandler):
+ def redirect_request(self,*args,**kwargs):return None
+class CurlResponse:
+ def __init__(self,request):
+ config='url = '+json.dumps(request.full_url)+'\n'
+ for key,val in request.header_items():config+='header = '+json.dumps(key+': '+val)+'\n'
+ r=subprocess.run(['curl','--silent','--show-error','--include','--max-time','15','--config','-'],input=config.encode(),capture_output=True,timeout=20)
+ if r.returncode:raise RuntimeError('curl failed '+str(r.returncode))
+ head,body=r.stdout.split(b'\r\n\r\n',1)
+ while body.startswith(b'HTTP/'):
+ head,body=body.split(b'\r\n\r\n',1)
+ self.code=int(head.splitlines()[0].split()[1]);self.body=body
+ self.headers={k.decode().lower():v.decode().strip() for l in head.splitlines()[1:] if b':' in l for k,v in [l.split(b':',1)]}
+ def read(self):return self.body
+proof={'task':'TK-11517','checks':[],'application_mutations':0,'email_sends':0}
+for host,route in [('gracie-internal.designerwallcoverings.com','/'),('gracie-internal.designerwallcoverings.com','/api/products'),('all.designerwallcoverings.com','/'),('all.designerwallcoverings.com','/api/microsites'),('all.designerwallcoverings.com','/microsites.html')]:
+ for label,credential in [('missing',None),('invalid','TK11517:invalid'),('valid',auth)]:
+ request=urllib.request.Request('https://'+host+route,headers={'Authorization':'Basic '+base64.b64encode(credential.encode()).decode()} if credential else {})
+ response=CurlResponse(request)
+ body=response.read();item={'host':host,'route':route,'auth':label,'status':response.code,'bytes':len(body),'body_sha256':hashlib.sha256(body).hexdigest(),'robots':response.headers.get('x-robots-tag')}
+ if label=='valid' and response.code==200:
+ if route=='/api/products':
+ d=json.loads(body);item['count']=d.get('count',len(d.get('products',[])))
+ if route=='/api/microsites':
+ d=json.loads(body);item['response_keys']=list(d);sites=d.get('sites',d.get('microsites',[]));item['sites_total']=len(sites)
+ item['gracie']=[{k:v for k,v in s.items() if k in ['slug','url','domain','vendor','title','type','status','ok','up','http_status','productCount','handleCount','count','feed','internalViewer','variant','name','feed_count','public_url','error','feed_url']} for s in sites if 'gracie' in s.get('slug','').lower()]
+ item['snapshot_timestamp']=d.get('at') or d.get('updated_at') or d.get('generated_at')
+ proof['checks'].append(item)
+reg=allroot/'config/known-subdomains.json'
+if reg.exists():
+ d=json.loads(reg.read_text());proof['registry_gracie']={k:[v for v in vals if 'gracie' in json.dumps(v).lower()] for k,vals in d.items() if isinstance(vals,list)}
+proof['gracie_saved_metadata']={k:v for k,v in effective('gracie-internal').items() if k in ['name','pm_cwd','pm_exec_path','PORT','DATA_SOURCE']}
+print(json.dumps(proof,indent=2))
← 676734b Record verified private Gracie socket migration
·
back to Tk11438 Postgres Migration
·
Save session closeout and remaining PostgreSQL migration han 7dd2703 →