kyle 42bab25766 feat: allow admins and coordinators to also be drivers
Add a "Driver" checkbox column to the User Management page. Checking it
creates a linked Driver record so the user appears in the drivers list,
can be assigned events, and enrolled for GPS tracking — without changing
their primary role. The DRIVER role checkbox is auto-checked and disabled
since being a driver is inherent to that role. Promoting a user from
DRIVER to Admin/Coordinator preserves their driver record.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 21:19:08 +01:00

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


🏗️ 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 deletedAt field for audit trail preservation
  • RBAC with CASL: Role-based access control with isomorphic permission checking
  • API Prefix: All endpoints use /api/v1 namespace

📋 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

  1. 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
  2. Configure Backend (backend/.env)

    AUTH0_DOMAIN=your-tenant.auth0.com
    AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/
    
  3. 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:

  1. User registers via Auth0
  2. User account created with isApproved: false
  3. Administrator manually approves user
  4. 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 filteredEvents useMemo 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:

  1. Update callback URLs: http://your-domain/callback
  2. Update allowed web origins: http://your-domain
  3. 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

  1. Backend

    cd backend
    nest g module feature-name
    nest g service feature-name
    nest g controller feature-name
    
  2. Update Prisma Schema (if needed)

    model NewEntity {
      id        String   @id @default(uuid())
      createdAt DateTime @default(now())
      updatedAt DateTime @updatedAt
      deletedAt DateTime? // Soft delete
    }
    
  3. Create Migration

    npx prisma migrate dev --name add_new_entity
    
  4. 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

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Write/update tests if applicable
  5. Commit with descriptive messages
  6. Push to your branch
  7. 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: vipIdvipIds[] 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:

  1. Check this README's troubleshooting section
  2. Review logs: docker-compose logs -f
  3. Check CLAUDE.md for detailed context
  4. 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 /api endpoint
  • Review Playwright test examples in frontend/e2e/

Built for BSA Jamboree Operations 🏕️

Description
VIP Coordinator - Event management system
Readme 9.9 MiB
Languages
TypeScript 96.4%
JavaScript 1.2%
Shell 1.2%
CSS 0.5%
Dockerfile 0.3%
Other 0.3%