"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const database_1 = __importDefault(require("../config/database")); // Simplified, unified data service that replaces the three redundant services class UnifiedDataService { constructor() { this.pool = database_1.default; } // Helper to convert snake_case to camelCase toCamelCase(obj) { if (!obj) return obj; if (Array.isArray(obj)) return obj.map(item => this.toCamelCase(item)); if (typeof obj !== 'object') return obj; return Object.keys(obj).reduce((result, key) => { const camelKey = key.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()); result[camelKey] = this.toCamelCase(obj[key]); return result; }, {}); } // VIP Operations async getVips() { const query = ` SELECT v.*, COALESCE( JSON_AGG( JSON_BUILD_OBJECT( 'flightNumber', f.flight_number, 'airline', f.airline, 'scheduledArrival', f.scheduled_arrival, 'scheduledDeparture', f.scheduled_departure, 'status', f.status ) ORDER BY f.scheduled_arrival ) FILTER (WHERE f.id IS NOT NULL), '[]' ) as flights FROM vips v LEFT JOIN flights f ON v.id = f.vip_id GROUP BY v.id ORDER BY v.created_at DESC`; const result = await this.pool.query(query); return this.toCamelCase(result.rows); } async getVipById(id) { const query = ` SELECT v.*, COALESCE( JSON_AGG( JSON_BUILD_OBJECT( 'flightNumber', f.flight_number, 'airline', f.airline, 'scheduledArrival', f.scheduled_arrival, 'scheduledDeparture', f.scheduled_departure, 'status', f.status ) ORDER BY f.scheduled_arrival ) FILTER (WHERE f.id IS NOT NULL), '[]' ) as flights FROM vips v LEFT JOIN flights f ON v.id = f.vip_id WHERE v.id = $1 GROUP BY v.id`; const result = await this.pool.query(query, [id]); return this.toCamelCase(result.rows[0]); } async createVip(vipData) { const { name, organization, department, transportMode, flights, expectedArrival, needsAirportPickup, needsVenueTransport, notes } = vipData; const client = await this.pool.connect(); try { await client.query('BEGIN'); // Insert VIP const vipQuery = ` INSERT INTO vips (name, organization, department, transport_mode, expected_arrival, needs_airport_pickup, needs_venue_transport, notes) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *`; const vipResult = await client.query(vipQuery, [ name, organization, department || 'Office of Development', transportMode || 'flight', expectedArrival, needsAirportPickup !== false, needsVenueTransport !== false, notes || '' ]); const vip = vipResult.rows[0]; // Insert flights if any if (transportMode === 'flight' && flights?.length > 0) { for (const flight of flights) { await client.query(`INSERT INTO flights (vip_id, flight_number, airline, scheduled_arrival, scheduled_departure) VALUES ($1, $2, $3, $4, $5)`, [vip.id, flight.flightNumber, flight.airline, flight.scheduledArrival, flight.scheduledDeparture]); } } await client.query('COMMIT'); return this.getVipById(vip.id); } catch (error) { await client.query('ROLLBACK'); throw error; } finally { client.release(); } } async updateVip(id, vipData) { const { name, organization, department, transportMode, flights, expectedArrival, needsAirportPickup, needsVenueTransport, notes } = vipData; const client = await this.pool.connect(); try { await client.query('BEGIN'); // Update VIP const updateQuery = ` UPDATE vips SET name = $2, organization = $3, department = $4, transport_mode = $5, expected_arrival = $6, needs_airport_pickup = $7, needs_venue_transport = $8, notes = $9, updated_at = NOW() WHERE id = $1 RETURNING *`; const result = await client.query(updateQuery, [ id, name, organization, department, transportMode, expectedArrival, needsAirportPickup, needsVenueTransport, notes ]); if (result.rows.length === 0) { await client.query('ROLLBACK'); return null; } // Update flights await client.query('DELETE FROM flights WHERE vip_id = $1', [id]); if (transportMode === 'flight' && flights?.length > 0) { for (const flight of flights) { await client.query(`INSERT INTO flights (vip_id, flight_number, airline, scheduled_arrival, scheduled_departure) VALUES ($1, $2, $3, $4, $5)`, [id, flight.flightNumber, flight.airline, flight.scheduledArrival, flight.scheduledDeparture]); } } await client.query('COMMIT'); return this.getVipById(id); } catch (error) { await client.query('ROLLBACK'); throw error; } finally { client.release(); } } async deleteVip(id) { const result = await this.pool.query('DELETE FROM vips WHERE id = $1 RETURNING *', [id]); return this.toCamelCase(result.rows[0]); } // Driver Operations async getDrivers() { const result = await this.pool.query('SELECT * FROM drivers ORDER BY name ASC'); return this.toCamelCase(result.rows); } async getDriverById(id) { const result = await this.pool.query('SELECT * FROM drivers WHERE id = $1', [id]); return this.toCamelCase(result.rows[0]); } async createDriver(driverData) { const { name, email, phone, vehicleInfo, status } = driverData; const result = await this.pool.query(`INSERT INTO drivers (name, email, phone, vehicle_info, status) VALUES ($1, $2, $3, $4, $5) RETURNING *`, [name, email, phone, vehicleInfo, status || 'available']); return this.toCamelCase(result.rows[0]); } async updateDriver(id, driverData) { const { name, email, phone, vehicleInfo, status } = driverData; const result = await this.pool.query(`UPDATE drivers SET name = $2, email = $3, phone = $4, vehicle_info = $5, status = $6, updated_at = NOW() WHERE id = $1 RETURNING *`, [id, name, email, phone, vehicleInfo, status]); return this.toCamelCase(result.rows[0]); } async deleteDriver(id) { const result = await this.pool.query('DELETE FROM drivers WHERE id = $1 RETURNING *', [id]); return this.toCamelCase(result.rows[0]); } // Schedule Operations async getScheduleByVipId(vipId) { const result = await this.pool.query(`SELECT se.*, d.name as driver_name FROM schedule_events se LEFT JOIN drivers d ON se.driver_id = d.id WHERE se.vip_id = $1 ORDER BY se.event_time ASC`, [vipId]); return this.toCamelCase(result.rows); } async createScheduleEvent(vipId, eventData) { const { driverId, eventTime, eventType, location, notes } = eventData; const result = await this.pool.query(`INSERT INTO schedule_events (vip_id, driver_id, event_time, event_type, location, notes) VALUES ($1, $2, $3, $4, $5, $6) RETURNING *`, [vipId, driverId, eventTime, eventType, location, notes]); return this.toCamelCase(result.rows[0]); } async updateScheduleEvent(id, eventData) { const { driverId, eventTime, eventType, location, notes, status } = eventData; const result = await this.pool.query(`UPDATE schedule_events SET driver_id = $2, event_time = $3, event_type = $4, location = $5, notes = $6, status = $7, updated_at = NOW() WHERE id = $1 RETURNING *`, [id, driverId, eventTime, eventType, location, notes, status]); return this.toCamelCase(result.rows[0]); } async deleteScheduleEvent(id) { const result = await this.pool.query('DELETE FROM schedule_events WHERE id = $1 RETURNING *', [id]); return this.toCamelCase(result.rows[0]); } async getAllSchedules() { const result = await this.pool.query(`SELECT se.*, d.name as driver_name, v.name as vip_name FROM schedule_events se LEFT JOIN drivers d ON se.driver_id = d.id LEFT JOIN vips v ON se.vip_id = v.id ORDER BY se.event_time ASC`); // Group by VIP ID const schedules = {}; result.rows.forEach((row) => { const event = this.toCamelCase(row); if (!schedules[event.vipId]) { schedules[event.vipId] = []; } schedules[event.vipId].push(event); }); return schedules; } // User Operations (simplified) async getUserByEmail(email) { const result = await this.pool.query('SELECT * FROM users WHERE email = $1', [email]); return this.toCamelCase(result.rows[0]); } async getUserById(id) { const result = await this.pool.query('SELECT * FROM users WHERE id = $1', [id]); return this.toCamelCase(result.rows[0]); } async createUser(userData) { const { email, name, role, department, googleId } = userData; const result = await this.pool.query(`INSERT INTO users (email, name, role, department, google_id) VALUES ($1, $2, $3, $4, $5) RETURNING *`, [email, name, role || 'coordinator', department || 'Office of Development', googleId]); return this.toCamelCase(result.rows[0]); } async updateUserRole(email, role) { const result = await this.pool.query(`UPDATE users SET role = $2, updated_at = NOW() WHERE email = $1 RETURNING *`, [email, role]); return this.toCamelCase(result.rows[0]); } async getUserCount() { const result = await this.pool.query('SELECT COUNT(*) FROM users'); return parseInt(result.rows[0].count, 10); } // Admin Settings (simplified) async getAdminSettings() { const result = await this.pool.query('SELECT key, value FROM admin_settings'); return result.rows.reduce((settings, row) => { settings[row.key] = row.value; return settings; }, {}); } async updateAdminSetting(key, value) { await this.pool.query(`INSERT INTO admin_settings (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = $2, updated_at = NOW()`, [key, value]); } } exports.default = new UnifiedDataService(); //# sourceMappingURL=unifiedDataService.js.map