Tour logistics automation for performing artists. Optimize flight routing, generate riders, find hotels, and manage tour budgets.
- Framework: Next.js (App Router)
- Auth: Supabase Auth
- Database: Supabase Postgres
- ORM: Drizzle ORM (pgTable)
- Styling: Tailwind CSS
- Deployment: Vercel
- Node.js >= 18
- Bun >= 1.0 (for tests)
- A Supabase project (free or Pro)
- A Vercel account (for deployment)
├── app/
│ ├── dashboard/ # Protected dashboard routes
│ │ ├── layout.tsx # Dashboard layout with sidebar
│ │ ├── page.tsx # Dashboard overview
│ │ ├── tours/page.tsx # Tours page (tour + gig data)
│ │ ├── riders/page.tsx # Riders page (hospitality items)
│ │ └── settings/page.tsx # Settings page (user info)
│ ├── login/ # Login page (public)
│ ├── signup/ # Signup page (public)
│ ├── auth/callback/ # Supabase auth callback
│ ├── layout.tsx # Root layout
│ └── globals.css # Global styles
├── components/ # React components
│ ├── sidebar.tsx # Dashboard sidebar navigation
│ └── sign-out-button.tsx # Sign-out button
├── db/
│ ├── schema/ # Drizzle ORM schemas (pgTable)
│ ├── queries/ # Data access queries
│ ├── migrations/ # Drizzle migration files
│ ├── index.ts # Database client
│ └── seed.ts # Seed script
├── lib/
│ └── supabase/ # Supabase client helpers
│ ├── client.ts # Browser client
│ ├── server.ts # Server client
│ └── middleware.ts # Auth middleware
├── specs/ # Project specifications
├── tests/ # Test files
├── drizzle.config.ts # Drizzle config (Supabase Postgres)
├── middleware.ts # Next.js middleware (auth protection)
└── package.json
This project uses Doppler as the primary source of truth for all environment variables. Doppler eliminates the need for .env.local files and manual Vercel env var configuration.
| Doppler Config | Deployment Target |
|---|---|
dev |
Local development |
stg |
Vercel Preview |
prd |
Vercel Production |
-
Install the Doppler CLI
# macOS brew install dopplerhq/cli/doppler # Other platforms: https://docs.doppler.com/docs/install-cli
-
Authenticate
doppler login
-
Link this project (run from the
virtual-agentdirectory)doppler setup
Select the
virtual-agentproject anddevconfig when prompted (these defaults are declared indoppler.yaml). -
Run the dev server with Doppler
npm run dev:doppler
This runs
doppler run -- next dev, injecting all secrets from thedevconfig into the Next.js process. No.env.localfile is required.
For Vercel deployments, the Doppler–Vercel integration syncs secrets automatically:
- Production deploys receive env vars from the
prdconfig - Preview deploys receive env vars from the
stgconfig
Once configured, no environment variables need to be manually set in the Vercel dashboard. See Doppler's Vercel integration docs for setup instructions.
npm install- Create a Supabase project at supabase.com
- Copy your project URL and anon key from the project settings
Option A — Doppler (recommended): Follow the Secrets Management steps above. No .env.local file is needed.
Option B — Manual .env.local: If you prefer not to use Doppler, copy the example file and fill in your values:
cp .env.local.example .env.local# Generate migrations from schema
npm run db:generate
# Apply migrations to Supabase Postgres
npm run db:migrate
# Seed with sample data
npm run db:seed# With Doppler (recommended)
npm run dev:doppler
# Without Doppler (requires .env.local)
npm run devThe app starts at http://localhost:3000.
-
Connect the repository to Vercel
-
Set the Root Directory to
virtual-agent(if this is inside a parent repo) -
Configure environment variables using one of the following methods:
Preferred — Doppler sync: Configure the Doppler–Vercel integration to automatically sync secrets. The
prdconfig is used for Production andstgfor Preview deployments. Once active, no manual env var entry is needed in Vercel.Fallback — Manual entry: If not using Doppler, add environment variables in Vercel project settings:
NEXT_PUBLIC_SUPABASE_URL— Your Supabase project URL (from Supabase Dashboard > Settings > API)NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY— Your Supabase publishable key (from Supabase Dashboard > Settings > API)DATABASE_URL— Supabase Postgres connection string (use the connection pooler URL on port 6543 for Vercel Serverless Functions)
-
Deploy — Vercel will run
next buildand deploy automatically
Note: For production, use the Supabase connection pooler URL (port 6543) as your
DATABASE_URLinstead of the direct connection string. This avoids connection exhaustion in serverless environments.
| Variable | Description |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase project URL |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY |
Supabase publishable key |
DATABASE_URL |
Supabase Postgres connection string |
AMADEUS_API_KEY |
Amadeus flight API key |
AMADEUS_API_SECRET |
Amadeus flight API secret |
GOOGLE_MAPS_API_KEY |
Google Maps API key |
RESEND_API_KEY |
Resend email service API key |
- Unauthenticated users are redirected to
/login - Authentication is handled by Supabase Auth
- Protected routes are enforced via Next.js middleware
- Sign up creates a new Supabase user account
- Sign in uses email/password authentication
- Schema defined with Drizzle ORM using
pgTable(Postgres) - Tables: artists, tours, gigs, bookings, riders
- Migrations managed via
drizzle-kit - Seed data includes: 1 artist (Chic), 1 tour, 5 gigs, 2 bookings, 1 rider
# Run all tests
npm testTests use Bun's built-in test runner. Test files are located in tests/, db/__tests__/, and db/schema/__tests__/.