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-old-20260125/dist/config/mockDatabase.js
vendored
Normal file
137
backend-old-20260125/dist/config/mockDatabase.js
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
"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
|
||||
Reference in New Issue
Block a user