Reverted Auth0-only approach since Traccar has openid.force=false and the token-based login was working. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
VIP Coordinator
Enterprise VIP & Transportation Management System for BSA Jamborees
A comprehensive full-stack application for coordinating VIP transportation, scheduling, and logistics at large-scale scouting events. Built with NestJS, React, PostgreSQL, and designed specifically for BSA (Boy Scouts of America) Jamboree operations.
🎯 Overview
VIP Coordinator streamlines the complex logistics of managing hundreds of VIPs during multi-day events. It handles:
- Multi-VIP Activity Scheduling - Coordinate transport and activities for multiple VIPs simultaneously
- Real-time Driver Assignment - Assign and reassign drivers on-the-fly with conflict detection
- Intelligent Search & Filtering - Find activities instantly by VIP name, location, or type
- Resource Optimization - Track vehicle capacity utilization (e.g., "3/6 seats used")
- Complete Itineraries - Generate detailed 3-day schedules per VIP with all activities
- Role-Based Access Control - Administrator, Coordinator, and Driver roles with granular permissions
🚀 Quick Start
Prerequisites
- Node.js 18+ and npm
- PostgreSQL 16+
- Redis 7+
- Auth0 Account (for authentication)
- Docker (optional, for containerized deployment)
Development Setup
# Clone the repository
git clone http://192.168.68.53:3000/kyle/vip-coordinator.git
cd vip-coordinator
# === Backend Setup ===
cd backend
npm install
# Configure environment variables
cp .env.example .env
# Edit .env with your Auth0 credentials and database URL
# Run database migrations
npx prisma migrate deploy
# Seed database with test data
npx prisma db seed
# Start backend server (port 3000)
npm run start:dev
# === Frontend Setup ===
cd ../frontend
npm install
# Configure environment variables
cp .env.example .env
# Edit .env with your backend API URL
# Start frontend dev server (port 5173)
npm run dev
Access the Application
- Frontend: http://localhost:5173
- Backend API: http://localhost:3000
- API Documentation: http://localhost:3000/api (Swagger UI)
🏗️ Architecture
Technology Stack
Backend
- Framework: NestJS 11 (TypeScript)
- Database: PostgreSQL 16 with Prisma ORM 7.3
- Cache: Redis 7
- Authentication: Auth0 + Passport.js (JWT strategy)
- API: REST with Swagger documentation
Frontend
- Framework: React 19 with TypeScript
- Build Tool: Vite 7.2
- UI Library: Material-UI (MUI) 7.3
- State Management: React Query 5.9 (server) + Zustand 5.0 (client)
- Routing: React Router 7.13
- Forms: React Hook Form (planned)
Infrastructure
- Containerization: Docker + Docker Compose
- Database Migrations: Prisma Migrate
- Testing: Playwright (E2E), Vitest (unit - planned)
Key Design Patterns
- Unified Activity Model: Single ScheduleEvent entity for all activity types (transport, meals, meetings, events)
- Multi-VIP Support: Activities can have multiple VIPs (
vipIds[]) for ridesharing and group events - Soft Deletes: All entities use
deletedAtfield for audit trail preservation - RBAC with CASL: Role-based access control with isomorphic permission checking
- API Prefix: All endpoints use
/api/v1namespace
📋 Features
Core Functionality
VIP Management
- Create and manage VIP profiles with arrival details
- Track arrival mode (FLIGHT, SELF_DRIVING, OTHER)
- Flight information integration
- Department assignment (OFFICE_OF_DEVELOPMENT for donors, ADMIN for BSA staff)
- Complete activity timeline per VIP
Activity Scheduling
- Unified model for all activity types:
- 🚗 TRANSPORT - Airport pickups, venue shuttles, rideshares
- 🍽️ MEAL - Breakfasts, lunches, dinners, receptions
- 📅 EVENT - Ceremonies, tours, campfires, presentations
- 🤝 MEETING - Donor meetings, briefings, private sessions
- 🏨 ACCOMMODATION - Check-ins, check-outs, room assignments
- Multi-VIP assignment (e.g., "3 VIPs sharing SUV to Campfire")
- Driver and vehicle assignment with capacity tracking
- Conflict detection and warnings
- Status tracking (SCHEDULED, IN_PROGRESS, COMPLETED, CANCELLED)
Search & Filtering
- Real-time Search: Instant filtering across title, location, description, VIP names, drivers, vehicles
- Type Filters: Quick filter tabs (All, Transport, Meals, Events, Meetings, Accommodation)
- Sortable Columns: Click to sort by Title, Type, VIPs, Start Time, or Status
- Combined Filtering: Search + filters work together seamlessly
Driver & Vehicle Management
- Driver profiles with contact info and department
- Vehicle tracking with type and seat capacity
- Real-time availability checking
- Inline driver assignment from activity list
Admin Tools
- One-click test data generation
- Realistic BSA Jamboree scenarios (20 VIPs, 8 drivers, 8 vehicles, 300+ activities)
- Balanced data: 50% OFFICE_OF_DEVELOPMENT, 50% ADMIN
- Complete 3-day itineraries with 15 activities per VIP
User Roles & Permissions
| Feature | Administrator | Coordinator | Driver |
|---|---|---|---|
| User Management | Full CRUD | View Only | None |
| VIP Management | Full CRUD | Full CRUD | View Only |
| Driver Management | Full CRUD | Full CRUD | View Only |
| Activity Scheduling | Full CRUD | Full CRUD | View + Update Status |
| Vehicle Management | Full CRUD | Full CRUD | View Only |
| Flight Tracking | Full Access | Full Access | None |
| Admin Tools | Full Access | Limited | None |
🗄️ Database Schema
Core Models
User
- auth0Sub: string (unique)
- email: string
- name: string
- role: ADMINISTRATOR | COORDINATOR | DRIVER
- isApproved: boolean (manual approval required)
- deletedAt: DateTime? (soft delete)
VIP
- name: string
- organization: string?
- department: OFFICE_OF_DEVELOPMENT | ADMIN
- arrivalMode: FLIGHT | SELF_DRIVING | OTHER
- expectedArrival: DateTime?
- airportPickup: boolean
- venueTransport: boolean
- notes: string?
- flights: Flight[] (relation)
ScheduleEvent (Unified Activity Model)
- title: string
- type: TRANSPORT | MEAL | EVENT | MEETING | ACCOMMODATION
- status: SCHEDULED | IN_PROGRESS | COMPLETED | CANCELLED
- startTime: DateTime
- endTime: DateTime
- location: string?
- pickupLocation: string? (transport only)
- dropoffLocation: string? (transport only)
- description: string?
- notes: string?
- vipIds: string[] (multi-VIP support)
- driverId: string?
- vehicleId: string?
Driver
- name: string
- phone: string
- department: OFFICE_OF_DEVELOPMENT | ADMIN
- userId: string? (optional link to User)
Vehicle
- name: string
- type: VAN | SUV | SEDAN | BUS | GOLF_CART | OTHER
- licensePlate: string
- seatCapacity: number
- status: AVAILABLE | IN_USE | MAINTENANCE
🔐 Authentication & Security
Auth0 Integration
-
Setup Auth0 Application
- Create Auth0 tenant at https://auth0.com
- Create a "Regular Web Application"
- Configure Allowed Callback URLs:
http://localhost:5173/callback - Configure Allowed Logout URLs:
http://localhost:5173 - Configure Allowed Web Origins:
http://localhost:5173
-
Configure Backend (
backend/.env)AUTH0_DOMAIN=your-tenant.auth0.com AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/ -
Configure Frontend (
frontend/.env)VITE_AUTH0_DOMAIN=your-tenant.auth0.com VITE_AUTH0_CLIENT_ID=your_client_id VITE_AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/
User Approval Workflow
New users must be manually approved:
- User registers via Auth0
- User account created with
isApproved: false - Administrator manually approves user
- User gains access to system
⚠️ First User Chicken-and-Egg Problem: Use database seed script or manually set isApproved: true for first admin.
Security Features
- JWT Authentication: Stateless token-based auth
- RBAC: Role-based access control at route and UI levels
- API Guards: NestJS guards enforce permissions on all endpoints
- Soft Deletes: Audit trail preservation
- Input Validation: DTO validation with class-validator
- SQL Injection Protection: Prisma ORM parameterized queries
📡 API Endpoints
Authentication
POST /api/v1/auth/login - Auth0 login
POST /api/v1/auth/logout - Logout
GET /api/v1/auth/me - Get current user
VIPs
GET /api/v1/vips - List all VIPs
POST /api/v1/vips - Create VIP (Admin/Coordinator)
GET /api/v1/vips/:id - Get VIP details
PATCH /api/v1/vips/:id - Update VIP (Admin/Coordinator)
DELETE /api/v1/vips/:id - Delete VIP (Admin/Coordinator)
GET /api/v1/vips/:id/schedule - Get VIP's complete itinerary
Activities (ScheduleEvents)
GET /api/v1/events - List all activities
POST /api/v1/events - Create activity (Admin/Coordinator)
GET /api/v1/events/:id - Get activity details
PATCH /api/v1/events/:id - Update activity (Admin/Coordinator/Driver)
DELETE /api/v1/events/:id - Delete activity (Admin/Coordinator)
PATCH /api/v1/events/:id/status - Update activity status (Driver allowed)
POST /api/v1/events/:id/vips - Add VIPs to activity
Drivers
GET /api/v1/drivers - List all drivers
POST /api/v1/drivers - Create driver (Admin/Coordinator)
GET /api/v1/drivers/:id - Get driver details
PATCH /api/v1/drivers/:id - Update driver (Admin/Coordinator)
DELETE /api/v1/drivers/:id - Delete driver (Admin/Coordinator)
Vehicles
GET /api/v1/vehicles - List all vehicles
POST /api/v1/vehicles - Create vehicle (Admin/Coordinator)
GET /api/v1/vehicles/:id - Get vehicle details
PATCH /api/v1/vehicles/:id - Update vehicle (Admin/Coordinator)
DELETE /api/v1/vehicles/:id - Delete vehicle (Admin/Coordinator)
Users
GET /api/v1/users - List all users (Admin only)
PATCH /api/v1/users/:id/approve - Approve user (Admin only)
PATCH /api/v1/users/:id/role - Update user role (Admin only)
DELETE /api/v1/users/:id - Delete user (Admin only)
🧪 Testing
E2E Testing with Playwright
cd frontend
# Install Playwright browsers (first time only)
npx playwright install
# Run all E2E tests
npx playwright test
# Run specific test file
npx playwright test e2e/multi-vip-events.spec.ts
# Run tests in UI mode (interactive)
npx playwright test --ui
# View test report
npx playwright show-report
Test Coverage
- ✅ Multi-VIP event creation and management
- ✅ Search and filtering functionality
- ✅ Driver assignment workflows
- ✅ Authentication flows
- ✅ Navigation and routing
- ✅ API integration
- ✅ Accessibility compliance
- ✅ iPad/tablet UI responsiveness
🐛 Common Issues & Solutions
Database Issues
Problem: "Can't reach database server at localhost:5432"
# Start PostgreSQL (if using Docker)
docker-compose up -d postgres
# Or check if PostgreSQL is running locally
sudo service postgresql status
Problem: "Migration failed" or "Schema drift detected"
cd backend
npx prisma migrate reset # ⚠️ Deletes all data
npx prisma migrate deploy
npx prisma db seed
Authentication Issues
Problem: "401 Unauthorized" on all API calls
- Verify Auth0 domain and audience are correct in both backend and frontend
.env - Check browser console for Auth0 errors
- Verify JWT token is being sent in request headers
- Ensure user is approved (
isApproved: true)
Problem: Redirect loop on login
- Check Auth0 callback URLs match frontend URL exactly
- Clear browser cookies and local storage
- Verify Auth0 client ID is correct
Frontend Issues
Problem: "Cannot read property 'map' of undefined"
- Data not loaded yet - add loading states
- Check React Query cache invalidation
- Verify API endpoint returns expected data structure
Problem: Search/sorting not working
- Clear browser cache
- Check console for JavaScript errors
- Verify
filteredEventsuseMemo dependencies
🚀 Deployment
Production Checklist
- Set
NODE_ENV=production - Use strong database passwords
- Configure Auth0 for production domain
- Enable HTTPS/SSL certificates
- Set up automated database backups
- Configure Redis persistence
- Set up monitoring (e.g., Sentry, DataDog)
- Configure CORS for production domain
- Review and adjust rate limiting
- Set up log aggregation
- Configure CDN for frontend assets (optional)
Docker Deployment (Production-Ready)
Complete containerization with multi-stage builds, Nginx, and automated migrations.
Quick Start
# 1. Create production environment file
cp .env.production.example .env.production
# 2. Edit .env.production with your values
# - Set strong POSTGRES_PASSWORD
# - Configure Auth0 credentials
# - Set AUTH0_CLIENT_ID for frontend
# 3. Build and start all services
docker-compose -f docker-compose.prod.yml up -d
# 4. Check service health
docker-compose -f docker-compose.prod.yml ps
# 5. View logs
docker-compose -f docker-compose.prod.yml logs -f
What Gets Deployed
- PostgreSQL 16 - Database with persistent volume
- Redis 7 - Caching layer with persistent volume
- Backend (NestJS) - Optimized production build (~200MB)
- Runs database migrations automatically on startup
- Non-root user for security
- Health checks enabled
- Frontend (Nginx) - Static files served with Nginx (~45MB)
- SPA routing configured
- API requests proxied to backend
- Gzip compression enabled
- Security headers configured
First-Time Setup
Auth0 Configuration:
- Update callback URLs:
http://your-domain/callback - Update allowed web origins:
http://your-domain - Update logout URLs:
http://your-domain
Access Application:
- Frontend:
http://localhost(or your domain) - Backend health:
http://localhost/api/v1/health
Updating the Application
# Pull latest code
git pull
# Rebuild and restart
docker-compose -f docker-compose.prod.yml down
docker-compose -f docker-compose.prod.yml build --no-cache
docker-compose -f docker-compose.prod.yml up -d
Database Management
# View migration status
docker-compose -f docker-compose.prod.yml exec backend npx prisma migrate status
# Manually run migrations (not needed, runs automatically)
docker-compose -f docker-compose.prod.yml exec backend npx prisma migrate deploy
# Seed database with test data (optional)
docker-compose -f docker-compose.prod.yml exec backend npx prisma db seed
Troubleshooting
# Check container status
docker-compose -f docker-compose.prod.yml ps
# View specific service logs
docker-compose -f docker-compose.prod.yml logs backend
docker-compose -f docker-compose.prod.yml logs frontend
# Restart specific service
docker-compose -f docker-compose.prod.yml restart backend
# Complete reset (⚠️ DELETES ALL DATA)
docker-compose -f docker-compose.prod.yml down -v
docker volume rm vip-coordinator-postgres-data vip-coordinator-redis-data
Production Enhancements
For production deployment, add:
- Reverse Proxy (Caddy/Traefik) for SSL/TLS
- Automated Backups for PostgreSQL volumes
- Monitoring (Prometheus/Grafana)
- Log Aggregation (ELK/Loki)
Image Sizes
- Backend: ~200-250MB (multi-stage build)
- Frontend: ~45-50MB (nginx alpine)
- Total deployment: <300MB (excluding database volumes)
Environment Variables
Backend (backend/.env)
DATABASE_URL=postgresql://user:password@localhost:5432/vip_coordinator
REDIS_URL=redis://localhost:6379
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/
NODE_ENV=production
PORT=3000
Frontend (frontend/.env)
VITE_API_URL=https://api.yourdomain.com
VITE_AUTH0_DOMAIN=your-tenant.auth0.com
VITE_AUTH0_CLIENT_ID=your_client_id
VITE_AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/
📚 Development Guide
Project Structure
vip-coordinator/
├── backend/ # NestJS Backend
│ ├── prisma/
│ │ ├── schema.prisma # Database schema
│ │ ├── migrations/ # Database migrations
│ │ └── seed.ts # Test data seeding
│ ├── src/
│ │ ├── auth/ # Auth0 + JWT authentication
│ │ ├── users/ # User management
│ │ ├── vips/ # VIP management
│ │ ├── drivers/ # Driver management
│ │ ├── vehicles/ # Vehicle management
│ │ ├── events/ # Activity scheduling (ScheduleEvent)
│ │ ├── flights/ # Flight tracking
│ │ └── common/ # Shared utilities, guards, decorators
│ ├── Dockerfile # Multi-stage production build
│ ├── docker-entrypoint.sh # Migration automation script
│ ├── .dockerignore # Docker build exclusions
│ └── package.json
│
├── frontend/ # React Frontend
│ ├── e2e/ # Playwright E2E tests
│ ├── src/
│ │ ├── pages/ # Page components
│ │ ├── components/ # Reusable UI components
│ │ ├── contexts/ # React contexts (Auth)
│ │ ├── hooks/ # Custom React hooks
│ │ ├── lib/ # Utilities, API client
│ │ └── types/ # TypeScript types
│ ├── Dockerfile # Multi-stage build with Nginx
│ ├── nginx.conf # Nginx server configuration
│ ├── .dockerignore # Docker build exclusions
│ ├── playwright.config.ts # Playwright configuration
│ └── package.json
│
├── docker-compose.yml # Development environment (DB only)
├── docker-compose.prod.yml # Production deployment (full stack)
├── .env.production.example # Production environment template
└── README.md # This file
Database Migrations
# Create a new migration
cd backend
npx prisma migrate dev --name description_of_change
# Apply migrations to production
npx prisma migrate deploy
# Reset database (⚠️ deletes all data)
npx prisma migrate reset
# View migration status
npx prisma migrate status
Adding a New Feature
-
Backend
cd backend nest g module feature-name nest g service feature-name nest g controller feature-name -
Update Prisma Schema (if needed)
model NewEntity { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt deletedAt DateTime? // Soft delete } -
Create Migration
npx prisma migrate dev --name add_new_entity -
Frontend
- Create page in
frontend/src/pages/ - Add route in
frontend/src/App.tsx - Create API service methods in
frontend/src/lib/api.ts - Add navigation link in
frontend/src/components/Layout.tsx
- Create page in
🤝 Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Write/update tests if applicable
- Commit with descriptive messages
- Push to your branch
- Create a Pull Request
Commit Message Format
<type>: <subject>
<body>
Co-Authored-By: Your Name <your.email@example.com>
Types: feat, fix, docs, style, refactor, test, chore
📖 Additional Documentation
- CLAUDE.md - Comprehensive project context for AI assistants
- PLAYWRIGHT_GUIDE.md - E2E testing guide
- NAVIGATION_UX_IMPROVEMENTS.md - UI/UX enhancement notes
- KEYCLOAK_SETUP.md - Alternative auth setup (archived)
🔄 Changelog
Latest (v2.0.0) - 2026-01-31
Major Changes
- ✨ Unified activity system (merged Event/EventTemplate → ScheduleEvent)
- ✨ Multi-VIP support (
vipIds[]array for ridesharing) - ✨ Advanced search with real-time filtering
- ✨ Sortable data tables (Title, Type, VIPs, Start Time, Status)
- ✨ Balanced BSA-relevant test data
- 🔧 Renamed "Schedule" → "Activities" throughout app
- 🗄️ Database schema overhaul (3 new migrations)
- 🧪 Playwright E2E test suite added
- 📚 Complete documentation rewrite
Breaking Changes
- API:
vipId→vipIds[]in all event endpoints - Database: Event/EventTemplate tables dropped
- Migration required:
npx prisma migrate deploy
📄 License
This project is proprietary software developed for BSA Jamboree operations.
🆘 Support
For Issues:
- Check this README's troubleshooting section
- Review logs:
docker-compose logs -f - Check CLAUDE.md for detailed context
- Create an issue in Gitea with:
- Steps to reproduce
- Error messages/logs
- Environment details
- Screenshots if applicable
For Questions:
- Review documentation files in repository root
- Check API documentation at
/apiendpoint - Review Playwright test examples in
frontend/e2e/
Built for BSA Jamboree Operations 🏕️