const db = require("../db"); const { parseWeekdaysValue, checkBusConflict } = require("../lib/schedule"); const { reportError } = require("../lib/report-error"); // Fleet repository methods (PostgreSQL mode). async function listFleetBuses(req) { try { const result = await db.query(` SELECT id, name, seat_capacity, license_plate FROM fleet.bus ORDER BY id ASC `); // Get all schedules to check for conflicts const schedulesResult = await db.query( `SELECT * FROM schedules WHERE status IN ('planned', 'active')`, ); const schedules = schedulesResult.rows.map((row) => ({ ...row, weekdays: parseWeekdaysValue(row.weekdays), })); return { statusCode: 200, body: { buses: result.rows.map((row) => { const busId = row.id; const now = new Date(); const tomorrow = new Date(now); tomorrow.setDate(tomorrow.getDate() + 1); const isAvailable = !checkBusConflict( busId, now.toISOString(), tomorrow.toISOString(), [], schedules, ); return { id: row.id, name: row.name, seatCapacity: row.seat_capacity, licensePlate: row.license_plate, available: isAvailable, }; }), }, }; } catch (err) { console.error(err); reportError({ partofservice: `${req.method} ${req.originalUrl}`, error: err.stack || err.message }); return { statusCode: 500, body: { error: "internal_error", details: err.message } }; } } async function createFleetBus(req) { try { const { name, seatCapacity, licensePlate } = req.body; if (!name || seatCapacity === undefined || !licensePlate) { return { statusCode: 400, body: { error: "missing_required_fields" } }; } const result = await db.query( ` WITH next_id AS ( SELECT COALESCE(MAX(id), 0) + 1 AS id FROM fleet.bus ) INSERT INTO fleet.bus (id, name, seat_capacity, license_plate) SELECT next_id.id, $1, $2, $3 FROM next_id RETURNING id, name, seat_capacity, license_plate `, [name, seatCapacity, licensePlate], ); const bus = result.rows[0]; return { statusCode: 201, body: { bus: { id: bus.id, name: bus.name, seatCapacity: bus.seat_capacity, licensePlate: bus.license_plate, }, }, }; } catch (err) { console.error(err); reportError({ partofservice: `${req.method} ${req.originalUrl}`, error: err.stack || err.message }); return { statusCode: 500, body: { error: "internal_error", details: err.message } }; } } async function updateFleetBus(req) { try { const { busId } = req.params; const { name, seatCapacity, licensePlate } = req.body; if (!busId || !Number.isFinite(Number(busId))) { return { statusCode: 400, body: { error: "invalid_bus_id" } }; } const result = await db.query( ` UPDATE fleet.bus SET name = COALESCE($1, name), seat_capacity = COALESCE($2, seat_capacity), license_plate = COALESCE($3, license_plate), updated_at = NOW() WHERE id = $4 RETURNING id, name, seat_capacity, license_plate `, [name ?? null, seatCapacity ?? null, licensePlate ?? null, busId], ); if (!result.rows[0]) return { statusCode: 404, body: { error: "bus_not_found" } }; const bus = result.rows[0]; return { statusCode: 200, body: { bus: { id: bus.id, name: bus.name, seatCapacity: bus.seat_capacity, licensePlate: bus.license_plate, }, }, }; } catch (err) { console.error(err); reportError({ partofservice: `${req.method} ${req.originalUrl}`, error: err.stack || err.message }); return { statusCode: 500, body: { error: "internal_error", details: err.message } }; } } async function deleteFleetBus(req) { try { const { busId } = req.params; if (!busId || !Number.isFinite(Number(busId))) { return { statusCode: 400, body: { error: "invalid_bus_id" } }; } const result = await db.query( `DELETE FROM fleet.bus WHERE id = $1 RETURNING id, name`, [busId], ); if (result.rows.length === 0) return { statusCode: 404, body: { error: "bus_not_found" } }; return { statusCode: 200, body: { success: true, bus: result.rows[0] } }; } catch (err) { console.error(err); reportError({ partofservice: `${req.method} ${req.originalUrl}`, error: err.stack || err.message }); return { statusCode: 500, body: { error: "internal_error", details: err.message } }; } } module.exports = { listFleetBuses, createFleetBus, updateFleetBus, deleteFleetBus };