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
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:
137
backend/prisma/migrations/20260125085806_init/migration.sql
Normal file
137
backend/prisma/migrations/20260125085806_init/migration.sql
Normal 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;
|
||||
@@ -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;
|
||||
3
backend/prisma/migrations/migration_lock.toml
Normal file
3
backend/prisma/migrations/migration_lock.toml
Normal 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"
|
||||
Reference in New Issue
Block a user