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/serverless driver (local PostgreSQL works for development)
  • About 15 minutes

Confirm your Node version first:

Terminal
node -v   # must report v20 or higher

Install in 4 Steps

Terminal
# 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:

Terminal
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:currencies matters more than it looks. Every price on the site resolves against the row flagged is_default in the currencies table — 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 USD to ship a different one.
  • db:sync:master reconciles, db:seed:master only 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-run first to see the plan.
  • db:seed:demo creates the batches itself. Each expedition gets 2–4 dated batches with real from/to windows; day rides get weekly ones. (npm run db:seed:departures still exists for generating plain weekly dates on tours that have none.)
  • db:seed:classifications is 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:pexels needs 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. Requires PEXELS_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 --force to 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:

  1. Visit http://localhost:3000 — the storefront should render with seeded content.

  2. Sign in to the admin at /admin/login with the account you created in the wizard.

  3. Open a demo expedition under Admin → Tours → Pricing & Departures — each batch shows its From / To date and Start / End time.

  4. Check your notification wiring — this audits every template the booking flow fires, renders each one with sample booking data, and flags any unresolved {{token}}:

    Terminal
    npm run test:notifications
    npm run test:notifications -- --send you@example.com   # also delivers a real test
    
  5. Type-check the project any time you edit code:

    Terminal
    npm run type-check   # runs tsc --noEmit
    

On a local or LAN host (localhost, *.test, private 10.x / 192.168.x ranges) 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


© CreativeCape Solutions · creative-cape.com · support@creative-cape.com