← back to Tk11438 Postgres Migration
verification/tk11517-domain/directory-review.json
201 lines
{
"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"
}
}