✓ Major Milestone — 6 June 2026: Controlled Supabase-backed staging layer is live and working on Cloudflare Pages. Build passing. PRs #67 and #68 merged.
⏰ Still required: Enquiry Worker not yet wired to /listing/:slug · Admin routes still have no auth guard · VITE_GHL_WEBHOOK_URL must be confirmed set · Privacy Policy + Terms still empty shells.
Status Summary (Verified — Claude Code Audit)
Current state (6 June 2026): Build passing (PR #68 merged, commit b4c15cf). Controlled staging listing + blog + business-tips routes confirmed live on Cloudflare Pages. Supabase anon SELECT grants, RLS policies, categories, articles, seo_metadata, schema_blocks all working. Free listing restrictions preserved — no direct phone/website/WhatsApp exposed. Still outstanding: Enquiry Worker not wired to listing profile · Admin auth guard missing · Privacy Policy + Terms empty · GHL webhook URL unconfirmed.
Full Route Inventory (src/router/index.tsx)
| Route | Component | Status | Notes | Priority | Action |
| / | HomePageRoute.tsx | Live Ready | Hero, SEO, sections confirmed | — | Safe to publish |
| /add-listing | AddListingHubRoute.tsx | Live Ready | DIY/DFY hub confirmed | — | Safe to publish |
| /add-listing/diy | AddListingDiyRoute.tsx | Live Ready | Full form + GHL webhook wired | Set env var | Set VITE_GHL_WEBHOOK_URL in CF Pages |
| /add-listing/dfy | AddListingDfyRoute.tsx | Live Ready | AED 247 DFY, GHL wired. No payment flow yet. | P2 | Set GHL URL; plan payment |
| /add-listing/thank-you | AddListingThankYouRoute.tsx | Live Ready | Clean, noindex | — | Safe to publish |
| /add-listing/dfy-thank-you | AddListingDfyThankYouRoute.tsx | Live Ready | Clean, noindex | — | Safe to publish |
| /claim-listing | ClaimListingRoute.tsx | Live Ready | Full form, GHL wired | Set env var | Set VITE_GHL_WEBHOOK_URL in CF Pages |
| /claim-listing/thank-you | ClaimListingThankYouRoute.tsx | Live Ready | Clean | — | Safe to publish |
| /claim | Redirect | Live Ready | 301 → /claim-listing | — | Safe |
| /contact | ContactRoute.tsx | Live Ready | Route confirmed. Form wiring needs audit. | P2 | Verify form submission |
| /businesses | SearchResultsRoute.tsx | Minor Fixes | Supabase + placeholder fallback. No enquiry endpoint. | P2 | Wire enquiry worker |
| /category/:slug | CategoryPageRoute.tsx | Minor Fixes | Supabase fallback; no MDX content yet | P2 | Add content; stay on WP for now |
| /emirate/:slug | EmiratePageRoute.tsx | Minor Fixes | Renders per-emirate listings. Thin content. | P2 | Add content before replacing WP |
| /location/:slug | EmiratePageRoute.tsx | Minor Fixes | Alias of /emirate/:slug | P2 | Same as above |
| /listing/:slug | ListingProfileRoute.tsx | Major Fixes | CTAs point to old WP URLs. No enquiry form. Fallback query has no status filter. Blank-title suppression missing. | P1 | Wire Worker; fix CTAs; fix fallback; suppress untitled |
| /arabian-ranches-3/souk/ | VenueDirectoryRoute.tsx | Major Fixes | PR #39 open. TS build errors: SurfaceCard children. | P1 | Fix typing → merge PR #39 |
| /privacy-policy | PublicPlaceholderRoute | Blocked | Empty placeholder. Legal requirement. | P1 | Write legal content |
| /terms | PublicPlaceholderRoute | Blocked | Empty placeholder. Legal requirement. | P1 | Write legal content |
| /admin/* | AdminLayout.tsx | Major Fixes | No auth guard. Any user gets full access. | P1 | Gate behind Supabase auth |
| /categories /emirates /featured /insights /guides /for-businesses /benefits /trust-method /pricing /faqs /about /premium-visibility /advertise /add-business | PublicPlaceholderRoute (×14) | Placeholder | Coming-soon shells | P3 | Keep on WordPress for now |
| /dashboard | DashboardOverviewRoute | Placeholder | All sub-routes placeholder. Not user-facing yet. | P3 | Not a launch blocker |
Missing — Not In Codebase
| Item | Status | Impact | Priority |
Enquiry Worker integration uaethrive-enquiry.alan-3e1.workers.dev — zero references in src/ | Missing | No enquiry form on listing profile. CTAs link to WP. Core revenue loop broken. | P1 |
useZiinaPayment hook + payment result pages experts.uaethrive.com — /payment-success /payment-cancelled /payment-failed | Missing | No paid expert signups can complete. | P1 (experts) |
VITE_GHL_WEBHOOK_URL env var ghlWebhook.ts silently no-ops if unset | Unset | All Add Listing + Claim Listing submissions reach thank-you but never reach GHL. | P1 |
Open PRs (5 remaining)
| PR | Title | State | Action |
| open | Report on safe public listing creation | Open | Branch: codex/report-on-safe-public-listing-creation (+1431/-10). Review before next implementation PR. |
| #54 | Public listing safety gates, view model, staging dry-run | Open | Merge this — needed for listing safety |
| #47 | Training consultants import review queue | Draft | Park for now |
| #44 | Import action plan docs | Parked | Do not merge yet — conflict review needed later |
| #39 | Arabian Ranches 3 Souk venue directory | Open | Fix SurfaceCard TS error first |
| #29 | Dubai category hub Markdown content | Open | Review content, then merge |
Major Milestone — 6 June 2026
Controlled Supabase-backed staging layer live on Cloudflare Pages
Confirmed working URLs:
uaethrive-platform.pages.dev/listing/dubai-marina-dental-clinic-demo
uaethrive-platform.pages.dev/blog/uae-school-fee-payment-plans
uaethrive-platform.pages.dev/business-tips/how-to-get-more-local-enquiries-in-the-uae
What is working: Controlled staging listing renders · Staging/template banner visible · Free listing restrictions preserved · No direct phone/website/WhatsApp/booking URL exposed · Articles render from Supabase · SEO metadata rows readable and mapped · Schema blocks readable · Categories readable · Locations readable · noindex,follow preserved · Cloudflare deployment confirmed
Supabase fixes completed: anon SELECT grants · RLS policies for controlled rows · categories/articles/seo_metadata/schema_blocks visibility all confirmed
Cloudflare env vars confirmed: VITE_SUPABASE_URL · VITE_SUPABASE_ANON_KEY
Recently Completed PRs
| PR | Title | Delivered | State |
| #68 | Fix template SEO metadata live column mapping | fetchSeo patched to use live seo_metadata schema. Staging layer fully functional. | Merged ✓ |
| #67 | Controlled staging template listing fallback + safety mapping | Staging/template banner, free listing restrictions, no premium field exposure, Supabase-backed listing + article routes confirmed. | Merged ✓ |
| #67 | Controlled staging template listing fallback + safety mapping | Staging/template banner, free listing restrictions, no premium field exposure, Supabase-backed listing + article routes confirmed. | Merged ✓ |
| #68 | Fix template SEO metadata live column mapping | fetchSeo patched to use live seo_metadata schema. Staging layer fully functional. | Merged ✓ |
| #67 | Controlled staging template listing fallback + safety mapping | Staging/template banner, free listing restrictions, no premium field exposure, Supabase listing + article routes confirmed. | Merged ✓ |
| #55 | Content operations validation scaffold | Dependency-free local validator. npm run content:score / content:refresh-audit / content:image-brief / content:qa / content:validate-schemas. Build passed. No external APIs or secrets added. | Merged ✓ |
| #53 | Content operations dashboard + newsletter docs | Schema files for content actions, statuses, dashboard items, image briefs, newsletter editions. | Merged ✓ |
| #52 | Unified content action taxonomy + scoring fix | Canonical actions: CREATE_NEW, REFRESH, MERGE, ARCHIVE, REDIRECT, REPURPOSE, NO_ACTION. | Merged ✓ |
| #51 | Auto-blogging seasonal GSC documentation pack | Auto-blogging docs added. | Merged ✓ |
Confirmed merge head: b4c15cf — Merge PR #68 (Fix template SEO metadata live column mapping) · 3 untracked local files pending decision: docs/auto-blogging/uaethrive_live_ready_status.html · docs/content-operations/local-validation-scaffold.md · fixtures/content-operations/content-priority.sample.json
GAIS Content Operations Dashboard — Design Reference
Status: Prototype complete — not yet a live route
Google AI Studio produced a visual prototype for the UAEThrive Internal Content Operations Dashboard (slate-grey / industrial-blue styling).
Prototype includes: Workspace queues · Blog refresh queue · Newsletter queue · Image desk · GSC opportunity view · Priority scoring algorithm · Filters by content action, approval status, seasonal cluster, content type.
Caveat: Must not claim live Supabase, Prisma or GSC integration. Change "Supabase & Prisma Schema Mapping Active" to "Local Validation Scaffold Active" or "Schema Mapping Planned".
Implementation: Review-first internal tool only. Local fixtures/mock data initially. Supabase-backed approvals introduced later after schema + RLS review.
Safe to Publish Now (once VITE_GHL_WEBHOOK_URL is set)
Confirmed live-ready: / · /add-listing · /add-listing/diy · /add-listing/dfy · /add-listing/thank-you · /add-listing/dfy-thank-you · /claim-listing · /claim-listing/thank-you · /claim · /contact
Must Stay on WordPress Until Replaced
| Page / Route | Reason |
| /listing/:slug (all 6,800+) | Enquiry form missing; WP CTAs still in ListingProfileRoute; safety gates unmerged |
| /privacy-policy + /terms | Empty placeholder — legal blocker |
| All 14 placeholder routes | PublicPlaceholderRoute — no content |
| /arabian-ranches-3/souk/ | Build-breaking TS errors until PR #39 fixed |
| All blog posts + /blog/* | Migration in progress; redirects must be planned per URL |
Two-PR approach agreed 5 June 2026. PR 1 = pre-launch fixes first. PR 2 = controlled live-page rollout foundation. Do not combine. WordPress stays live as safety net throughout.
PR 1 — Pre-Launch Fixes
✓ Fix build errors — DONE (PR #68, commit b4c15cf)
- Build now passing. npm run build and npm run validate:template-content both confirmed.
b Add auth guard to /admin/* routes
- Gate all admin routes behind existing Supabase auth before any public deployment.
c Fix listingQueries.ts fallback (lines 44–49)
- Hard-fail on schema error — never return unfiltered records.
d Suppress blank-title records in toItem()
- Filter out null/blank title records rather than falling back to "Untitled Listing".
PR 1 name: "Pre-launch fixes: build, admin auth, listing safety" · Build must pass before PR is opened.
PR 2 — Controlled Live-Page Rollout Foundation
1 Homepage audit
- Check HomePageRoute.tsx for placeholder copy, broken links, missing CTAs.
- Confirm SEO title, meta description, canonical, H1, Open Graph tags present.
- Add Listing CTA and Browse Businesses CTA above the fold.
- Add JSON-LD Organization schema if not already present.
2 Add Listing + Claim Listing — harden GHL wiring
- Confirm VITE_GHL_WEBHOOK_URL is referenced correctly in ghlWebhook.ts.
- Add visible error state if GHL submission fails — do not show success on webhook error.
- Confirm thank-you pages are noindex.
3 Listing profile — wire enquiry Worker + remove WP CTAs
- Remove CTAs linking to: /add-your-free-business-listing-uaethrive/ and /free-business-listing-uae-expand-your-local-reach-with-uae-thrive/
- Replace with: Enquire button → POST to uaethrive-enquiry.alan-3e1.workers.dev with listing_name + listing_slug. Inline success message. No page reload.
- Claim this listing → internal link to /claim-listing
- Free listings must NOT expose: direct phone, WhatsApp, website URL, multiple images, premium fields.
- Add JSON-LD LocalBusiness schema using listing data.
- Confirm published/approved status filter always applied.
4 Footer cleanup
- Replace placeholder links with real routes or # anchor + TODO comment.
- Add minimal Privacy Policy + Terms copy ("This page is being updated") — cannot be blank shells in footer.
- Confirm /add-listing and /claim-listing footer links are correct.
PR 2 name: "Controlled live-page rollout foundation" · Requires PR 1 reviewed + approved first · Build must pass · No auto-deploy · No mass migration.
What Not To Do Yet
Do not migrate all 6,800+ listings ·
Do not redirect WordPress listing URLs ·
Do not replace ranking blog posts ·
Do not publish unreviewed imported listings ·
Do not expose phone/email/WhatsApp on free listings ·
Do not turn on auto-blogging ·
Do not enable GHL outbound workflows until page flow is proven ·
Do not add KV lead capping until basic live enquiry path is stable ·
Do not write directly to production Supabase ·
Do not change RLS
Listing Safety — Current Gaps
| Issue | File | Risk | Fix |
| Fallback query has no status filter | listingQueries.ts:44–49 | Unapproved records can surface | Hard-fail — never return unfiltered records |
| Blank-title records not suppressed | listingQueries.ts:18 toItem() | Renders as "Untitled Listing" | Filter null/blank titles |
| No slug deduplication | listingQueries.ts | Duplicate slugs resolve unpredictably | DISTINCT ON slug at query level |
| Safety gates in PR #54 — not merged | publicListingGuards.js | Guard logic exists but inactive | Merge PR #54 |
experts.uaethrive.com — Outstanding
| Item | Status | Priority | Notes |
| useZiinaPayment hook | Missing | P1 | Not built. No paid signups can complete. |
| /payment-success /payment-cancelled /payment-failed | Missing | P1 | Result pages not built. Dependent on hook. |
| Wire hook into pricing/apply button | Missing | P1 | After hook built. |
| Profile + gallery upload to Supabase Storage | Not Started | P2 | On roadmap. |
| GTM containers verification | Unverified | P2 | GTM-5J59S546 + GTM-M9D9SJV8 not confirmed firing on SPA. |
Now Active sprint
Next Queued
Later Planned
Done Complete
Parked Deferred
UAEThrive — Core Platform
| Item | Area | Horizon | Priority | Notes |
| Delete CF API token "UAEThrive Enquiry Worker Deploy" | Security | Now | P1 | Expires 12 June 2026. Delete today. |
| Fix build (DONE PR #68) + remaining PR 1 items | Engineering | Now | P1 | Build passing. Still needed: admin auth guard, listing safety fallback fix. |
| Set VITE_GHL_WEBHOOK_URL in CF Pages env | Engineering | Now | P1 | Silent GHL failure on all forms right now. |
| PR 2 — controlled live-page rollout foundation | Engineering | Now | P1 | Homepage, Add Listing, Claim Listing, listing profile enquiry, footer. |
| Privacy Policy + Terms content | Legal | Now | P1 | Legal blocker. Both empty placeholder shells. |
| Merge PR #54 — listing safety gates | Engineering | Now | P1 | Fixes status filter fallback + suppresses untitled records. |
| Lead capping via Cloudflare KV (3/month free tier) | Monetisation | Next | P1 | After enquiry Worker wired. Drives upgrade pressure. |
| GHL workflow — enquirer auto-reply email | Automation | Next | P2 | Trigger: tag uaethrive-enquiry → confirmation to contact. |
| GHL workflow — owner upsell on lead cap hit | Automation | Next | P2 | After KV capping is built. |
| Category + emirate page content (MDX) | Content | Next | P2 | Merge PR #29 (Dubai hub) as first step. |
| Opportunities category MVP | Product | Next | P2 | 3-5 listings under "Opportunities" category. First: Interior Design referral post. |
| GAIS Content Operations Dashboard (/dashboard route) | Internal | Next | P2 | Review-first. Local fixtures only initially. No Supabase writes until schema + RLS reviewed. |
| NeighbourhoodHubRoute build | Engineering | Later | P2 | Foundation priority. Not started. |
| LocationCategoryHubRoute build | Engineering | Later | P2 | Foundation priority. Not started. |
| GEO/AEO content cluster — Leaving Dubai 2026 pillar | SEO | Later | P2 | Brief complete. Branch: claude/uaethrive-content-hub-template-xVMdU |
| Category/emirate hero images (Recraft) | Design | Later | P3 | Prompts produced for all categories + 7 emirate pages. |
| Blog migration — /blog/* URL redirects | SEO | Later | P2 | Plan per URL. Do not bulk redirect. |
experts.uaethrive.com
| Item | Area | Horizon | Priority | Notes |
| useZiinaPayment hook + payment result pages | Engineering | Now | P1 | No paid signups can complete without this. |
| Wire hook into pricing/apply button | Engineering | Now | P1 | Dependent on hook first. |
| Profile + gallery upload to Supabase Storage | Engineering | Next | P2 | Not started. |
| GTM containers verification | Analytics | Next | P2 | Not confirmed firing on SPA. |
| Expert post/article functionality | Product | Later | P3 | Pricing TBD. |
Other Brands
| Brand | Item | Horizon | Priority | Notes |
| Adz4Local | Elanco Home Services pilot — organic PPL, Voice AI "Layla" | Next | P2 | Validation pending. |
| MyLocalSEOGuru | Press release service co-branded with UAEThrive + RedPress | Later | P3 | — |
| Abneos | UK sales agent hiring funnel — commission-only, ex-Groupon/field sales | Later | P3 | — |
| PlumbGrow / MyLocalSEOGuru / EduConnectHR / Uanducas / AlanClark.me | Brand website builds — Next.js + Supabase | Later | P3 | Queued. Not started. |
How to use: Tell Claude "add this idea to the suggestions doc" and it will log it here with a date, area tag, and New status. During planning sessions Claude evaluates and moves items: New → Under Review → Approved / Parked / Declined. Approved items get promoted to the Roadmap tab.
| Date | Idea / Suggestion | Area | Status | Notes |
| 5 Jun 2026 |
Project Hub — Google Drive folder with status doc, brand wiki, suggestions, and roadmap managed by Claude via Drive MCP. Tabbed HTML layout for easy navigation. |
Operations |
Done |
This file is the implementation. |
| 5 Jun 2026 |
Opportunities category MVP — validate demand by posting 3-5 real opportunities as standard listings before building a dedicated listing type. First: Interior Design referral/subcontract post. |
Product |
Approved |
Agreed. Ready to execute once Add Listing flow confirmed live. |
| 5 Jun 2026 |
Lead capping via Cloudflare KV — limit free tier to 3 enquiries/month to drive upgrade pressure. |
Monetisation |
Approved |
Specced. Build after enquiry Worker wired to listing profile. |
| — |
Add your next idea — tell Claude to log it |
| | |
Wordmark
Light backgrounds
UAEThrive
Dark backgrounds
UAEThrive
| Rule | Detail |
| Font | Inter, weight 800 |
| Colour (light bg) | #008080 Teal |
| Colour (dark bg) | #ffffff White — on #0B3A6A or #008080 backgrounds only |
| Letter spacing | -0.5px |
| CSS class | .uaethrive-wordmark |
| Header/navbar | Image logo file only |
| All other contexts | Text-based wordmark only (HTML, email, mockups, code) |
| Never | Split colours · Add icons inline · Add taglines inline · Modify spacing |
Colour Palette
| Name | Hex | Swatch | Usage |
| UAEThrive Teal | #008080 | | Wordmark, H1, Primary CTAs, borders, badges |
| Deep Blue | #0B3A6A | | H2, Navigation, Footer, dark headers |
| Modern Blue | #1E88E5 | | H3, Links, Highlights, accents |
| Primary Background | #FFFFFF | | Main page background |
| Section Alternate | #F8FAFC | | Alternating section backgrounds |
| Cards / Dividers | #EEF2F7 | | Card borders, subtle dividers |
| Text Primary | #0F172A | | Body copy, H4 |
| Text Muted | #475569 | | Secondary text, captions, labels |
Typography
Inter (Google Fonts, weights 400–800) · Icons: Lucide 24px / 1.75 stroke
H1Discover UAE42px / 1.15 / Teal
H2Find Any Business32px / 1.25 / Deep Blue
H3Browse by Category24px / 1.3 / Modern Blue
H4Featured Listings18px / 1.35 / Text Primary
BodyUAE's leading business discovery platform.16px / 1.6 / Text Primary
Buttons & CTAs
Get Listed FreeClaim Your Listing
| Type | Background | Text | Border | Hover |
| Primary | #008080 | #FFFFFF | None — 16px 32px padding, 6px radius | #006666 + lift |
| Secondary | Transparent | #008080 | 2px solid #008080 | Fill #008080, text white |
One primary CTA per screen. No aggressive popups.
Pricing Tiers
Visibility Booster
97 AED/mo
447 AED/year
Leads Booster
197 AED/mo
997 AED/year
Authority Engine
2,750 AED/mo
25,000 AED/year
Voice & Tone
| Attribute | Description | Example |
| Professional but warm | Authoritative without being cold | "We make it easy for UAE businesses to get found." |
| Benefit-led | Lead with what the user gains | "Get more enquiries, not just more visibility." |
| Conversion-focused | Every page has a clear next step | Always a CTA — never a dead end |
| Local-first | UAE business context, not expat-focused | "The UAE's business discovery platform" |
| UK English | All copy, all content | optimise · recognise · colour · licence (noun) |
Do say
- UAE business discovery platform
- Find trusted businesses in the UAE
- Get more enquiries
- Claim your free listing
- Verified by UAEThrive
Don't say
- Expat directory / expat guide
- Moving to Dubai
- Foreigner-friendly
- Best in the world
- Revolutionary AI-powered platform
Brand Governance
Do
- Use global colours and fonts — never override
- Use preset section padding CSS classes
- Test on mobile / tablet / desktop before publishing
- One primary CTA per screen
- Always spell UAEThrive as one word
- UK English throughout all copy
- Lucide icons at 24px / 1.75 stroke
Don't
- Override global colours with custom hex codes
- Set manual font sizes outside the type scale
- Add Elementor padding when using CSS classes
- Multiple CTAs per screen or aggressive popups
- Split wordmark across two colours
- Add icons or taglines inline with the wordmark
- US English spellings
Key Platforms & Contacts
| Platform | Purpose | Key Detail |
| Recraft.ai | Image generation | Palette: #008080, #0B3A6A, #1E88E5. Always spell all text verbatim in prompts. |
| Fliki.ai | Video / avatar production | 0.25 credits/second. Finalise scripts before generating. Standard/Premium for avatars. |
| RightBlogger | Blog content | SEO-led. UK English. UAE business context. |
| Gamma.app | Presentations, one-pagers | Brand palette applied. Tier landing pages. |
| GHL | CRM, WhatsApp, Voice AI | Location ID: 4J4khnDKnDzwZpmvZoBx. WhatsApp only — never SMS. |
| Resend | Transactional email | Domain: send.uaethrive.com. From: [email protected] |
| Abneos WhatsApp | Business contact / notifications | 971585391704 |
Ready-to-use Claude Code prompt for the next session. Copy the block below and paste directly into Claude Code. It incorporates all confirmed audit findings so Codex doesn't re-check things already verified.
Next Claude Code Prompt — Controlled Live-Page Rollout
We are ready to start a controlled live-page rollout for UAEThrive.
CONSTRAINTS — do not violate these under any circumstances:
- Do not start mass migration.
- Do not remove or redirect any existing WordPress/indexed URLs.
- Do not write directly to production Supabase or change RLS.
- Do not enable GHL workflows, cron jobs, GitHub Actions, or any external
sending without explicit approval.
- Do not deploy to production automatically.
- Do not merge to main. Create a branch, commit, push, open a PR only.
CONTEXT FROM LAST AUDIT (branch claude/zen-gauss-UVc1K, 5 June 2026):
- Build is currently FAILING: VenueDirectoryRoute.tsx has TS errors —
SurfaceCard does not accept children prop (PR #39, unmerged).
- VITE_GHL_WEBHOOK_URL env var is unset — Add Listing and Claim Listing
forms silently fail to reach GHL.
- Enquiry Worker (uaethrive-enquiry.alan-3e1.workers.dev) has zero
references in src/ — listing profile CTAs still point to old WordPress URLs.
- /admin/* routes have no authentication guard.
- PR #54 (public listing safety gates) is open but not merged.
- PRs #51, #52, #53, #55 are confirmed merged into main.
- Confirmed merge head: 14784c2
STEP 1 — REPO STATE CHECK (report only, no changes):
1. Current branch and git status.
2. Latest commit SHA and message.
3. Confirm PRs #51–55 are reflected in local main.
4. Confirm whether PR #54 is merged or still open.
5. Run the build. Report pass or fail and exact errors if failing.
STEP 2 — PR 1: PRE-LAUNCH FIXES
Fix these in a single PR. Name it: "Pre-launch fixes: build, admin auth, listing safety"
a) Fix VenueDirectoryRoute.tsx TS error — SurfaceCard children prop
(type the prop or wrap children). Confirm build passes after fix.
b) Add authentication guard to /admin/* routes using existing Supabase auth.
c) Fix listingQueries.ts fallback query (lines 44–49) — hard-fail on
schema error, never return unfiltered records.
d) Suppress blank-title records in toItem() — filter null/empty titles
rather than falling back to "Untitled Listing".
Build must pass before PR 1 is opened.
STEP 3 — PR 2: CONTROLLED LIVE-PAGE ROLLOUT FOUNDATION
Once PR 1 is reviewed and approved, create a second PR.
Name it: "Controlled live-page rollout foundation"
Homepage:
- Audit HomePageRoute.tsx for placeholder copy, broken links, missing CTAs.
- Confirm SEO title, meta description, canonical, H1, Open Graph tags.
- Add Listing CTA and Browse Businesses CTA above the fold.
- Add JSON-LD Organization schema if not already present.
Add Listing + Claim Listing:
- Verify VITE_GHL_WEBHOOK_URL is referenced correctly in ghlWebhook.ts.
- Add visible error state if GHL submission fails — do not show success
if the webhook call errors.
- Confirm thank-you pages are noindex.
Listing profile (/listing/:slug):
- Remove these two CTAs linking to old WordPress URLs:
/add-your-free-business-listing-uaethrive/
/free-business-listing-uae-expand-your-local-reach-with-uae-thrive/
- Replace with:
"Enquire" button — POST to https://uaethrive-enquiry.alan-3e1.workers.dev
Pass: listing_name and listing_slug in request body.
Show inline success message on submit. No page reload.
"Claim this listing" button — internal link to /claim-listing
- Free listings must NOT expose: direct phone, WhatsApp, website URL,
multiple images, or any premium-only fields.
- Add JSON-LD LocalBusiness schema using listing data.
- Confirm published/approved status filter is always applied.
Footer:
- Replace placeholder links with real routes where they exist, or
# anchor + TODO comment where they don't.
- Add minimal Privacy Policy + Terms copy ("This page is being updated")
— cannot be blank shells in the footer.
- Confirm /add-listing and /claim-listing footer links are correct.
Build check:
- Run npm run build after all changes.
- Build must pass before PR 2 is opened.
- If it fails, fix before opening.
PR output required for both PRs:
- Branch name.
- List of changed files.
- Build result (pass/fail, error output if failing).
- Risks or items needing review before merge.
- PR URL.
The goal is a stable foundation for controlled live-page rollout.
Not mass migration. WordPress remains live throughout.
What This Prompt Adds vs. the Original
| Addition | Why |
| Splits into two PRs | Avoids mixing broken build fix with new feature work |
| References exact file names + line numbers from audit | Codex doesn't re-discover things already confirmed |
| Specifies exact WordPress URLs to remove from ListingProfileRoute | Unambiguous — no interpretation needed |
| Requires visible error state on GHL failure | Silent no-op is a real live bug right now |
| Skips route inventory check (already confirmed) | Saves tokens; we already have the full inventory |
| Makes Privacy/Terms minimal copy acceptable | Blank shells in footer are worse than "page being updated" |