# 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

```bash
# 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 `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**
```typescript
- auth0Sub: string (unique)
- email: string
- name: string
- role: ADMINISTRATOR | COORDINATOR | DRIVER
- isApproved: boolean (manual approval required)
- deletedAt: DateTime? (soft delete)
```

**VIP**
```typescript
- 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)
```typescript
- 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**
```typescript
- name: string
- phone: string
- department: OFFICE_OF_DEVELOPMENT | ADMIN
- userId: string? (optional link to User)
```

**Vehicle**
```typescript
- 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`)
   ```env
   AUTH0_DOMAIN=your-tenant.auth0.com
   AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/
   ```

3. **Configure Frontend** (`frontend/.env`)
   ```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

```bash
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"
```bash
# 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"
```bash
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

```bash
# 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

```bash
# 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

```bash
# 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

```bash
# 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`)
```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`)
```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

```bash
# 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**
   ```bash
   cd backend
   nest g module feature-name
   nest g service feature-name
   nest g controller feature-name
   ```

2. **Update Prisma Schema** (if needed)
   ```prisma
   model NewEntity {
     id        String   @id @default(uuid())
     createdAt DateTime @default(now())
     updatedAt DateTime @updatedAt
     deletedAt DateTime? // Soft delete
   }
   ```

3. **Create Migration**
   ```bash
   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: `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:**
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** 🏕️
