Major Enhancement: NestJS Migration + CASL Authorization + Error Handling
Some checks failed
CI/CD Pipeline / Backend Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Tests (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled

Complete rewrite from Express to NestJS with enterprise-grade features:

## Backend Improvements
- Migrated from Express to NestJS 11.0.1 with TypeScript
- Implemented Prisma ORM 7.3.0 for type-safe database access
- Added CASL authorization system replacing role-based guards
- Created global exception filters with structured logging
- Implemented Auth0 JWT authentication with Passport.js
- Added vehicle management with conflict detection
- Enhanced event scheduling with driver/vehicle assignment
- Comprehensive error handling and logging

## Frontend Improvements
- Upgraded to React 19.2.0 with Vite 7.2.4
- Implemented CASL-based permission system
- Added AbilityContext for declarative permissions
- Created ErrorHandler utility for consistent error messages
- Enhanced API client with request/response logging
- Added War Room (Command Center) dashboard
- Created VIP Schedule view with complete itineraries
- Implemented Vehicle Management UI
- Added mock data generators for testing (288 events across 20 VIPs)

## New Features
- Vehicle fleet management (types, capacity, status tracking)
- Complete 3-day Jamboree schedule generation
- Individual VIP schedule pages with PDF export (planned)
- Real-time War Room dashboard with auto-refresh
- Permission-based navigation filtering
- First user auto-approval as administrator

## Documentation
- Created CASL_AUTHORIZATION.md (comprehensive guide)
- Created ERROR_HANDLING.md (error handling patterns)
- Updated CLAUDE.md with new architecture
- Added migration guides and best practices

## Technical Debt Resolved
- Removed custom authentication in favor of Auth0
- Replaced role checks with CASL abilities
- Standardized error responses across API
- Implemented proper TypeScript typing
- Added comprehensive logging

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 08:50:25 +01:00
parent 8ace1ab2c1
commit 868f7efc23
351 changed files with 44997 additions and 6276 deletions

View File

@@ -0,0 +1,137 @@
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('ADMINISTRATOR', 'COORDINATOR', 'DRIVER');
-- CreateEnum
CREATE TYPE "Department" AS ENUM ('OFFICE_OF_DEVELOPMENT', 'ADMIN');
-- CreateEnum
CREATE TYPE "ArrivalMode" AS ENUM ('FLIGHT', 'SELF_DRIVING');
-- CreateEnum
CREATE TYPE "EventType" AS ENUM ('TRANSPORT', 'MEETING', 'EVENT', 'MEAL', 'ACCOMMODATION');
-- CreateEnum
CREATE TYPE "EventStatus" AS ENUM ('SCHEDULED', 'IN_PROGRESS', 'COMPLETED', 'CANCELLED');
-- CreateTable
CREATE TABLE "users" (
"id" TEXT NOT NULL,
"auth0Id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"name" TEXT,
"picture" TEXT,
"role" "Role" NOT NULL DEFAULT 'COORDINATOR',
"isApproved" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"deletedAt" TIMESTAMP(3),
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "vips" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"organization" TEXT,
"department" "Department" NOT NULL,
"arrivalMode" "ArrivalMode" NOT NULL,
"expectedArrival" TIMESTAMP(3),
"airportPickup" BOOLEAN NOT NULL DEFAULT false,
"venueTransport" BOOLEAN NOT NULL DEFAULT false,
"notes" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"deletedAt" TIMESTAMP(3),
CONSTRAINT "vips_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "flights" (
"id" TEXT NOT NULL,
"vipId" TEXT NOT NULL,
"flightNumber" TEXT NOT NULL,
"flightDate" TIMESTAMP(3) NOT NULL,
"segment" INTEGER NOT NULL DEFAULT 1,
"departureAirport" TEXT NOT NULL,
"arrivalAirport" TEXT NOT NULL,
"scheduledDeparture" TIMESTAMP(3),
"scheduledArrival" TIMESTAMP(3),
"actualDeparture" TIMESTAMP(3),
"actualArrival" TIMESTAMP(3),
"status" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "flights_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "drivers" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"phone" TEXT NOT NULL,
"department" "Department",
"userId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"deletedAt" TIMESTAMP(3),
CONSTRAINT "drivers_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "schedule_events" (
"id" TEXT NOT NULL,
"vipId" TEXT NOT NULL,
"title" TEXT NOT NULL,
"location" TEXT,
"startTime" TIMESTAMP(3) NOT NULL,
"endTime" TIMESTAMP(3) NOT NULL,
"description" TEXT,
"type" "EventType" NOT NULL DEFAULT 'TRANSPORT',
"status" "EventStatus" NOT NULL DEFAULT 'SCHEDULED',
"driverId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"deletedAt" TIMESTAMP(3),
CONSTRAINT "schedule_events_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "users_auth0Id_key" ON "users"("auth0Id");
-- CreateIndex
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
-- CreateIndex
CREATE INDEX "flights_vipId_idx" ON "flights"("vipId");
-- CreateIndex
CREATE INDEX "flights_flightNumber_flightDate_idx" ON "flights"("flightNumber", "flightDate");
-- CreateIndex
CREATE UNIQUE INDEX "drivers_userId_key" ON "drivers"("userId");
-- CreateIndex
CREATE INDEX "schedule_events_vipId_idx" ON "schedule_events"("vipId");
-- CreateIndex
CREATE INDEX "schedule_events_driverId_idx" ON "schedule_events"("driverId");
-- CreateIndex
CREATE INDEX "schedule_events_startTime_endTime_idx" ON "schedule_events"("startTime", "endTime");
-- AddForeignKey
ALTER TABLE "flights" ADD CONSTRAINT "flights_vipId_fkey" FOREIGN KEY ("vipId") REFERENCES "vips"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "drivers" ADD CONSTRAINT "drivers_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "schedule_events" ADD CONSTRAINT "schedule_events_vipId_fkey" FOREIGN KEY ("vipId") REFERENCES "vips"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "schedule_events" ADD CONSTRAINT "schedule_events_driverId_fkey" FOREIGN KEY ("driverId") REFERENCES "drivers"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -0,0 +1,50 @@
-- CreateEnum
CREATE TYPE "VehicleType" AS ENUM ('VAN', 'SUV', 'SEDAN', 'BUS', 'GOLF_CART', 'TRUCK');
-- CreateEnum
CREATE TYPE "VehicleStatus" AS ENUM ('AVAILABLE', 'IN_USE', 'MAINTENANCE', 'RESERVED');
-- AlterTable
ALTER TABLE "drivers" ADD COLUMN "isAvailable" BOOLEAN NOT NULL DEFAULT true,
ADD COLUMN "shiftEndTime" TIMESTAMP(3),
ADD COLUMN "shiftStartTime" TIMESTAMP(3);
-- AlterTable
ALTER TABLE "schedule_events" ADD COLUMN "actualEndTime" TIMESTAMP(3),
ADD COLUMN "actualStartTime" TIMESTAMP(3),
ADD COLUMN "dropoffLocation" TEXT,
ADD COLUMN "notes" TEXT,
ADD COLUMN "pickupLocation" TEXT,
ADD COLUMN "vehicleId" TEXT;
-- CreateTable
CREATE TABLE "vehicles" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"type" "VehicleType" NOT NULL DEFAULT 'VAN',
"licensePlate" TEXT,
"seatCapacity" INTEGER NOT NULL,
"status" "VehicleStatus" NOT NULL DEFAULT 'AVAILABLE',
"currentDriverId" TEXT,
"notes" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"deletedAt" TIMESTAMP(3),
CONSTRAINT "vehicles_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "vehicles_currentDriverId_key" ON "vehicles"("currentDriverId");
-- CreateIndex
CREATE INDEX "schedule_events_vehicleId_idx" ON "schedule_events"("vehicleId");
-- CreateIndex
CREATE INDEX "schedule_events_status_idx" ON "schedule_events"("status");
-- AddForeignKey
ALTER TABLE "vehicles" ADD CONSTRAINT "vehicles_currentDriverId_fkey" FOREIGN KEY ("currentDriverId") REFERENCES "drivers"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "schedule_events" ADD CONSTRAINT "schedule_events_vehicleId_fkey" FOREIGN KEY ("vehicleId") REFERENCES "vehicles"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"