feat: PR-6 - Orlando surfaces: salon home, services, city page, JSON-LD, events, engine sitemap - #6
Merged
Eth-Interchained merged 1 commit intoJul 7, 2026
Conversation
…age, JSON-LD, events, engine-driven sitemap The revenue site renders. Every fact on every page came through the seed loader with provenance — nothing is invented at render time. - src/lib/seo/head.ts: buildHead — titleTemplate, meta description, canonical ALWAYS on the campaign origin, OG, noindex flag, JSON-LD script injection (</script>-escaped) - src/lib/seo/jsonld.ts: hairSalonJsonLd + breadcrumbsJsonLd — honest fields only: absent data = absent property; by-appointment days omitted from openingHoursSpecification; NO self-marked-up Google rating (renders as attributed text instead — spec §14 risk 7) - src/server/layout.ts: Park Avenue Warm page shell — pure HTML, no SPA bundle, token values mirroring the blessed design direction - src/server/pages.ts: / (salon home: real NAP, hours, GBP line as text, team, service chips, tracked CTAs), /services, /services/:category (real price tables with group heads), /:city, /go/:kind (click-tracked 302 with scheme allowlist; events fire-and-forget) - City gating with REAL 404s: known-but-held cities render a branded noindex 404 page — found live by the test suite: they previously fell through to the SPA shell as indexed 200 soft-404 doorways. Trigger was the failing assertion; root cause was fallback ownership of the city namespace. - Sitemap now queried from the ENGINE at request time — it can never advertise a page that wouldn't render (held cities excluded by the same gating the router uses) - orlando successEvents += text_click (the salon's favored channel) Verified locally: tsc clean · unit 30/30 · live 4/4 vs nedbd 2.6.1 (pages render real seeded data; /go event round-trip proven by querying the events collection; held-city 404s; sitemap contents) · portal build clean · portal audit unchanged (2 warnings, tracked). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR-6: Orlando's public plane goes live. Server-rendered salon home,
/services+ per-category price tables, the Winter Park city page,HairSalon/BreadcrumbListJSON-LD, click-tracked conversion events, and a sitemap generated from engine queries. Every rendered fact came through the provenance-chained seed — nothing is invented at render time.Why this matters
This is the storefront that earns: appointment-generation surfaces with honest structured data and attributable conversion events (
booking_click,call_click,text_click,direction_click— analytics are one NQL GROUP BY away, per the spec's engine-capability-equals-product-feature doctrine).What's inside
src/lib/seo/):buildHead(canonical locked to the campaign origin) + JSON-LD generators with hard honesty rules — absent entity data = absent property; by-appointment days omitted; no self-marked-up third-party rating (the GBP 4.6/196 renders as attributed text)layout.ts): Park Avenue Warm as pure server HTML — no SPA bundle on public pagespages.ts): home / services index / category price tables / city page — all reading PR-5's typed entity queriesnoindex404. The live suite caught the original design falling through to the SPA shell — 12 indexed soft-404 doorways in production, prevented before first deploy/go/:kind: scheme-allowlisted, click-tracked 302s; events land append-only in the engineTests run (locally, real engine)
tsc --noEmitclean · unit 30/30 (JSON-LD asserted against the REAL Mint seed entity — the seed file is the fixture)/goevent round-trip proven by querying the events collection (source attribution intact) · held-city 404 + noindex · unsafe/godestinations rejected · sitemap includes live surfaces, excludes held citiesportal buildclean ·portal auditunchanged (2 shell-page warnings, tracked since PR-3)Follow-up work
feeds.ts) once articles exist (Phase 3)Spec: §7 (routing), §8 (SEO engine), §11 (orlando strategy), §14 risks 1+7, §15 Phase 1.