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>
137 lines
4.8 KiB
JavaScript
137 lines
4.8 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
class MockDatabase {
|
|
constructor() {
|
|
this.users = new Map();
|
|
this.vips = new Map();
|
|
this.drivers = new Map();
|
|
this.scheduleEvents = new Map();
|
|
this.adminSettings = new Map();
|
|
// Add a test admin user
|
|
const adminId = '1';
|
|
this.users.set(adminId, {
|
|
id: adminId,
|
|
email: 'admin@example.com',
|
|
name: 'Test Admin',
|
|
role: 'admin',
|
|
created_at: new Date(),
|
|
updated_at: new Date()
|
|
});
|
|
// Add some test VIPs
|
|
this.vips.set('1', {
|
|
id: '1',
|
|
name: 'John Doe',
|
|
organization: 'Test Org',
|
|
department: 'Office of Development',
|
|
transport_mode: 'flight',
|
|
expected_arrival: '2025-07-25 14:00',
|
|
needs_airport_pickup: true,
|
|
needs_venue_transport: true,
|
|
notes: 'Test VIP',
|
|
created_at: new Date(),
|
|
updated_at: new Date()
|
|
});
|
|
}
|
|
async query(text, params) {
|
|
console.log('Mock DB Query:', text.substring(0, 50) + '...');
|
|
// Handle user queries
|
|
if (text.includes('COUNT(*) FROM users')) {
|
|
return { rows: [{ count: this.users.size.toString() }] };
|
|
}
|
|
if (text.includes('SELECT * FROM users WHERE email')) {
|
|
const email = params?.[0];
|
|
const user = Array.from(this.users.values()).find(u => u.email === email);
|
|
return { rows: user ? [user] : [] };
|
|
}
|
|
if (text.includes('SELECT * FROM users WHERE id')) {
|
|
const id = params?.[0];
|
|
const user = this.users.get(id);
|
|
return { rows: user ? [user] : [] };
|
|
}
|
|
if (text.includes('SELECT * FROM users WHERE google_id')) {
|
|
const google_id = params?.[0];
|
|
const user = Array.from(this.users.values()).find(u => u.google_id === google_id);
|
|
return { rows: user ? [user] : [] };
|
|
}
|
|
if (text.includes('INSERT INTO users')) {
|
|
const id = Date.now().toString();
|
|
const user = {
|
|
id,
|
|
email: params?.[0],
|
|
name: params?.[1],
|
|
role: params?.[2] || 'coordinator',
|
|
google_id: params?.[4],
|
|
created_at: new Date(),
|
|
updated_at: new Date()
|
|
};
|
|
this.users.set(id, user);
|
|
return { rows: [user] };
|
|
}
|
|
// Handle VIP queries
|
|
if (text.includes('SELECT v.*') && text.includes('FROM vips')) {
|
|
const vips = Array.from(this.vips.values());
|
|
return {
|
|
rows: vips.map(v => ({
|
|
...v,
|
|
flights: []
|
|
}))
|
|
};
|
|
}
|
|
// Handle admin settings queries
|
|
if (text.includes('SELECT * FROM admin_settings')) {
|
|
const settings = Array.from(this.adminSettings.entries()).map(([key, value]) => ({
|
|
key,
|
|
value
|
|
}));
|
|
return { rows: settings };
|
|
}
|
|
// Handle drivers queries
|
|
if (text.includes('SELECT * FROM drivers')) {
|
|
const drivers = Array.from(this.drivers.values());
|
|
return { rows: drivers };
|
|
}
|
|
// Handle schedule events queries
|
|
if (text.includes('SELECT * FROM schedule_events')) {
|
|
const events = Array.from(this.scheduleEvents.values());
|
|
return { rows: events };
|
|
}
|
|
if (text.includes('INSERT INTO vips')) {
|
|
const id = Date.now().toString();
|
|
const vip = {
|
|
id,
|
|
name: params?.[0],
|
|
organization: params?.[1],
|
|
department: params?.[2] || 'Office of Development',
|
|
transport_mode: params?.[3] || 'flight',
|
|
expected_arrival: params?.[4],
|
|
needs_airport_pickup: params?.[5] !== false,
|
|
needs_venue_transport: params?.[6] !== false,
|
|
notes: params?.[7] || '',
|
|
created_at: new Date(),
|
|
updated_at: new Date()
|
|
};
|
|
this.vips.set(id, vip);
|
|
return { rows: [vip] };
|
|
}
|
|
// Default empty result
|
|
console.log('Unhandled query:', text);
|
|
return { rows: [] };
|
|
}
|
|
async connect() {
|
|
return {
|
|
query: this.query.bind(this),
|
|
release: () => { }
|
|
};
|
|
}
|
|
// Make compatible with pg Pool interface
|
|
async end() {
|
|
console.log('Mock database connection closed');
|
|
}
|
|
on(event, callback) {
|
|
if (event === 'connect') {
|
|
setTimeout(() => callback(), 100);
|
|
}
|
|
}
|
|
}
|
|
exports.default = MockDatabase;
|
|
//# sourceMappingURL=mockDatabase.js.map
|