Previously TraccarClientService was trying to authenticate with default credentials (admin/admin) before GpsService could load the actual credentials from the database. This caused 401 errors on driver enrollment. Now GpsService sets credentials on TraccarClientService during onModuleInit() after loading them from the gps_settings table. 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 🏕️