Quick Start
Welcome to Bike Tours — a production-ready, white-label motorcycle-expedition booking marketplace built with Next.js 16 (App Router), React 19, TypeScript, PostgreSQL, and Tailwind CSS. Built for guided group rides across India — Chennai to Ladakh, Manali–Leh, Spiti, Rann of Kutch — on Royal Enfield, Himalayan and similar motorcycles. This page takes you from a fresh download to a running storefront with real demo expeditions in about 15 minutes.
New here? Read the Product Overview for the big picture first, then come back and install. Want every detail? The Installation Guide is the long-form version of this page.
What Bike Tours Gives You
Bike Tours is a single, self-contained Next.js application — no separate API server, no microservices, no mobile codebase to wire up. One project ships:
- A public storefront — marketing pages, an expedition catalogue, destination search, and booking checkout.
- Four portals on their own URL spaces — customer (
/customer), operator (/operator), admin (/admin), and influencer/affiliate (/influencer). - A REST API under
/api/v1/**, with an admin-gated interactive reference at/api/docs/v1. - Over 60 built-in add-ons (payments, storage, email, analytics, maps, AI chatbot, and more), unlocked by license entitlement and an admin toggle.
Everything is white-label: branding, content, currency, and locale come from settings — nothing is hardcoded.
Built around group expeditions
The domain model is motorcycle-touring specific:
| Concept | What it means |
|---|---|
| Tour | A route an operator sells — Himalayan expedition, cross-country, coastal, desert, off-road, weekend ride. |
| Departure (batch) | A dated running of that tour with its own from/to dates and flag-off / wrap-up times, rider capacity and optional price overrides. A 21-day Chennai → Ladakh batch might run 4 Sep 06:00 → 24 Sep 18:00 for 50 riders. Availability comes from batches, so a tour with none is not bookable. |
| Operator | The touring company that runs the ride and owns the motorcycle fleet. |
| Rider | The customer. Priced by how they ride, not by age (see below). |
Rider pricing tiers
The booking spine was built for adult/child/infant travellers. Those three price columns are reused for rider types rather than renamed — see src/product/booking/rider-tiers.ts, the single source of truth:
| Column | Means | Typical price |
|---|---|---|
price_adult |
Rider (own bike) — brings their own motorcycle | base |
price_child |
Rider (rental bike) — takes one of the operator's | base + hire |
price_infant |
Pillion — rides behind another rider | ~70% of base |
Never hardcode "Adults"/"Children"/"Infants" in UI copy — import RIDER_TIERS instead.
Departure windows
units.start_date / start_time and units.end_date / end_time define each batch's window. end_date is optional: leave it blank on a single-day ride and the quote falls back to the tour's duration_nights. When set, it always wins — so a batch can run longer or shorter than the tour's nominal duration.
Master data ships tuned for this: motorcycle models (Royal Enfield Classic 350, Bullet 350, Meteor 350, Himalayan 411/450, Scram 411, Interceptor 650, KTM Adventure 390…), brands, engine capacity, riding-gear sizes, terrain (high-altitude pass, ghat roads, off-road trail, desert sand, water crossing…), difficulty up to Extreme, riding gear & equipment, and India-appropriate safety features (backup vehicle, mechanic on ride, oxygen cylinder, road captain & sweeper) and rider requirements (valid motorcycle licence, inner line permit, medical fitness). Manage it all under Admin → Master Data.
What You Need
- Node.js 20+ (LTS recommended) and npm 10+
- A PostgreSQL database — Neon is recommended, since Bike Tours uses the
@neondatabase/serverlessdriver (local PostgreSQL works for development) - About 15 minutes
Confirm your Node version first:
node -v # must report v20 or higher
Install in 4 Steps
# 1. Install dependencies
npm install
# 2. Create your environment file
# Create .env with at least DATABASE_URL. JWT_SECRET and CRON_SECRET are
# auto-generated by the install wizard's database step if they are unset.
# 3. Initialise the database (schema + baseline data)
npm run db:init
# 4. Start the dev server
npm run dev
Open http://localhost:3000. On a fresh install the app redirects to the install wizard at /install, which walks you through the database check, license, admin account, and site settings. You can let the wizard create the schema for you and skip step 3 entirely.
Load the Demo Marketplace (optional)
To see the product with real content — operators, rides, bookings, reviews and photography — run the seeders in this order:
npm run db:seed:currencies # currency table + sets INR as the site default
npm run db:sync:master # motorcycle master data (models, terrain, gear, permits…)
npm run db:seed:demo # 5 operators, 30 expeditions with dated batches, bookings, reviews
npm run db:seed:classifications # attach models / terrain / themes to each expedition
npm run db:seed:notifications # email / SMS / WhatsApp templates
npm run media:pexels # real motorcycle-touring photos + video → your own storage
A few things worth knowing:
db:seed:currenciesmatters more than it looks. Every price on the site resolves against the row flaggedis_defaultin thecurrenciestable —getDefaultCurrency()on the server,useDefaultCurrency()/defaultCurrencyCode()on the client. With the table empty, formatters fall through to a hard-coded fallback. Change the default any time under Admin → Settings → Currencies; the whole storefront, admin, operator and invoice output follows it. Pass--default USDto ship a different one.db:sync:masterreconciles,db:seed:masteronly inserts. Sync adds new registry values, re-applies ordering, and retires values you have removed — deleting them when nothing references them and deactivating them when something does. Run it with--dry-runfirst to see the plan.db:seed:democreates the batches itself. Each expedition gets 2–4 dated batches with real from/to windows; day rides get weekly ones. (npm run db:seed:departuresstill exists for generating plain weekly dates on tours that have none.)db:seed:classificationsis not optional if you want the fleet and terrain shown on tour pages — the demo seed creates the expeditions but not their master-data links.media:pexelsneeds a storage channel. It downloads motorcycle-touring imagery from Pexels and re-uploads it to your bucket (Admin → Settings → Channels → Storage), so nothing is hot-linked. RequiresPEXELS_API_KEY. Each expedition is matched to a theme — Himalayan, cross-country, coastal, desert, off-road, wildlife, pilgrimage — from its name, so a Ladakh run never gets a beach-cruiser photo. Already-enriched tours are skipped; pass--forceto redo them.
Core Environment Variables
Bike Tours reads a small, fixed set of environment variables. These are the ones you care about on day one:
| Variable | Purpose |
|---|---|
DATABASE_URL |
PostgreSQL connection string (Neon in production, local in dev). |
JWT_SECRET |
Signs admin and customer session tokens. Auto-generated if missing. |
SECRET_KEY |
AES-256-GCM key that encrypts stored integration secrets in the DB. |
CRON_SECRET |
Authenticates scheduled-job endpoints. Auto-generated if missing. |
LICENSE_SERVER_URL |
License server — defaults to https://creative-cape.com. |
PEXELS_API_KEY |
Optional. Only needed for the media:pexels imagery pipeline. |
Storage, payment, email, SMS and WhatsApp credentials do not live in .env — they are stored encrypted in the database and managed under Admin → Settings → Channels.
See the Installation Guide for the full environment-variable reference, and the License Guide for purchase-code activation.
Verify It Works
Once the dev server is up and you have finished the wizard:
Visit http://localhost:3000 — the storefront should render with seeded content.
Sign in to the admin at
/admin/loginwith the account you created in the wizard.Open a demo expedition under Admin → Tours → Pricing & Departures — each batch shows its From / To date and Start / End time.
Check your notification wiring — this audits every template the booking flow fires, renders each one with sample booking data, and flags any unresolved
{{token}}:npm run test:notifications npm run test:notifications -- --send you@example.com # also delivers a real testType-check the project any time you edit code:
npm run type-check # runs tsc --noEmit
On a local or LAN host (localhost,
*.test, private10.x/192.168.xranges) Bike Tours runs in dev mode — the license check is bypassed and every add-on is unlocked, so you can explore the whole product before activating on your live domain.
Where to Go Next
- Installation Guide — detailed setup, the install wizard, and the full env reference.
- Deployment Guide — build, configure, and ship to production.
- Hosting Guide — pick between Vercel, a Node VPS, and other hosts.
- Admin Guide — run your Bike Tours marketplace day-to-day.
- Add-on Development Guide — extend Bike Tours with your own add-ons.
© CreativeCape Solutions · creative-cape.com · support@creative-cape.com