Platform Overview
How BestPhuketGuide.com is structured, what each part does, and how bookings flow from customer to confirmation.
Three Apps, One Monorepo
The platform lives in a single pnpm monorepo with three apps deployed on Cloudflare:
apps/webCustomer-facing site at bestphuketguide.com. Tour listings, booking flow, Stripe checkout, booking confirmation page, and review submission. Built with TanStack Start on Cloudflare Pages.
apps/adminThis dashboard at admin.bestphuketguide.com. Manage tours, bookings, availability, reviews, coupons, marketing attribution, and platform settings.
apps/apiCloudflare Worker at api.bestphuketguide.com. All data access: tours, bookings, availability, payments, images, settings. Both the public site and admin talk to this API.
Infrastructure
SQLite database — all bookings, tours, reviews, settings
Object storage for tour images
Online card payments with multi-currency support
Booking confirmations and tour reminders
Transactional email — confirmations and recovery
Analytics and conversion tracking
Booking Flow
Here's what happens from the moment a customer lands on your site to when they leave a review:
Customer discovers tour
Via Google Ads, Meta Ads, organic search. UTM parameters are captured automatically.
Selects date & guests
Availability calendar shows open slots. Add-ons (transfers, equipment) shown at checkout.
Payment
Stripe card (online), bank transfer (manual verify), or cash (pay on day). Deposit-only option available.
Booking confirmed
Status set to "confirmed". WhatsApp + email confirmation sent automatically.
Tour reminder
Sent the evening before (6 PM Phuket time) with what to bring and meeting point.
Tour day
Guide checks booking ref. You can mark attendance in admin if needed.
Review request
Sent 24 hours after the tour date. Customer submits review on your public site.
Review published
Appears on tour page after you approve it in admin → Reviews.
Key Admin Capabilities
Environment Variables Reference
Set these in wrangler.toml (non-secret) and Cloudflare Worker Secrets (sensitive):
# Non-secret (wrangler.toml vars)
ENVIRONMENT=production
SITE_URL=https://bestphuketguide.com
ADMIN_URL=https://admin.bestphuketguide.com
# Secrets (wrangler secret put KEY)
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
RESEND_API_KEY=re_...
WHATSAPP_ACCESS_TOKEN=EAAxxxxx...
JWT_SECRET=your-random-secretwrangler secret put STRIPE_SECRET_KEY to add secrets securely — never put live keys in wrangler.toml.Related Guides