diff --git a/data/seeds/mint-on-the-avenue.json b/data/seeds/mint-on-the-avenue.json index 6866f2c..f867570 100644 --- a/data/seeds/mint-on-the-avenue.json +++ b/data/seeds/mint-on-the-avenue.json @@ -48,7 +48,8 @@ ], "priceRange": "$$-$$$", "bookingPlatform": "Phorest", - "bookingUrl": "TO_CONFIRM — 'Book Now via Phorest' target URL not captured from static HTML", + "bookingUrl": "https://www.phorest.com/salon/mintontheavenue", + "$bookingNote": "Confirmed by Mark 2026-07-07 — the canonical Phorest booking page. mintontheavenue.com/request-appointment is being phased out.", "gbp": { "listedName": "Mint On The Avenue Aveda Salon", "placeId": "ChIJQfwznhBw54gRZHRHaFdWJxA", @@ -229,7 +230,6 @@ ], "toConfirmWithMark": [ - "Exact Phorest booking URL (Book Now target)", "Social links (Instagram/Facebook) — not present in crawled static HTML", "Canonical text number (833 vs 830 — 833 presumed, matches homepage + blog)", "Canonical price source (service pages vs homepage widget)", diff --git a/src/server/pages.ts b/src/server/pages.ts index 2af2090..1e42164 100644 --- a/src/server/pages.ts +++ b/src/server/pages.ts @@ -36,6 +36,7 @@ interface SalonDoc { cityId?: string | null; entity?: SalonEntityLike & { textLine?: string; + bookingUrl?: string; positioning?: { tagline?: string; heroLine?: string; philosophy?: string }; serviceInclusions?: string; stylistLevels?: string; @@ -60,15 +61,17 @@ function track(db: NedbClient, event: Record): void { }); } -/** Tracked CTA row — every conversion path goes through /go. */ +/** Tracked CTA row — every conversion path goes through /go. The booking + * URL is DATA (entity.bookingUrl from the seed) — a salon without one + * simply doesn't get the button; call/text remain. */ function ctaRow(salon: SalonDoc, origin: string): string { const e = salon.entity ?? {}; const tel = telHref(e.nap?.phone); const sms = smsHref(e.textLine); - const book = "https://mintontheavenue.com/request-appointment/"; + const book = typeof e.bookingUrl === "string" && /^https:\/\//.test(e.bookingUrl) ? e.bookingUrl : null; const go = (kind: string, to: string) => `/go/${kind}?to=${encodeURIComponent(to)}`; const parts: string[] = []; - parts.push(`Book an appointment`); + if (book) parts.push(`Book an appointment`); if (sms) parts.push(`Text ${esc(e.textLine ?? "")}`); if (tel) parts.push(`Call ${esc(e.nap?.phone ?? "")}`); if (e.gbp?.mapsUrl) parts.push(`Directions`); diff --git a/test/api.test.ts b/test/api.test.ts index 8ffc11c..85c6ef8 100644 --- a/test/api.test.ts +++ b/test/api.test.ts @@ -180,6 +180,10 @@ test("orlando surfaces: server-rendered pages from real engine data", async () = assert.ok(!homeHtml.includes("aggregateRating"), "no self-marked-up Google rating"); assert.ok(homeHtml.includes(`