import type { RowDataPacket } from "mysql2/promise"; import { getPool } from "./db"; import { normalizePhone } from "./phone"; import { sqlDateToIso } from "./time"; import { NO_BIKE, pickWorkshopJob, stageLabel, type BikeStatus, type StatusResult } from "./workshop"; export async function lookupBikes(rawPhone: string): Promise { const phone = normalizePhone(rawPhone); if (!phone) return { message: NO_BIKE, error: null, bikes: [] }; const pool = getPool(); const [customers] = await pool.query( `SELECT id FROM customers WHERE phone = ? AND deleted_at IS NULL`, [phone], ); if (customers.length === 0) return { message: NO_BIKE, error: null, bikes: [] }; const customerIds = customers.map((row) => String(row.id)); const [vehicles] = await pool.query( `SELECT id, registration, make, model_name FROM vehicles WHERE customer_id IN (${customerIds.map(() => "?").join(", ")}) AND deleted_at IS NULL ORDER BY registration ASC, id ASC`, customerIds, ); if (vehicles.length === 0) return { message: NO_BIKE, error: null, bikes: [] }; const bikes: BikeStatus[] = []; for (const vehicle of vehicles) { const [jobs] = await pool.query( `SELECT id, stage, created_at FROM job_cards WHERE vehicle_id = ? AND deleted_at IS NULL`, [vehicle.id], ); const picked = pickWorkshopJob( jobs.map((job) => ({ id: String(job.id), stage: String(job.stage), createdAt: sqlDateToIso(job.created_at) ?? "", })), ); const registration = String(vehicle.registration ?? ""); const make = String(vehicle.make ?? ""); const model = String(vehicle.model_name ?? ""); if (!picked) { bikes.push({ registration, make, model, inWorkshop: false, stageLabel: null, stageAt: null, }); continue; } const [events] = await pool.query( "SELECT `at` FROM job_card_events WHERE job_card_id = ? AND deleted_at IS NULL ORDER BY `at` DESC, id DESC LIMIT 1", [picked.id], ); bikes.push({ registration, make, model, inWorkshop: true, stageLabel: stageLabel(picked.stage), stageAt: events[0] ? sqlDateToIso(events[0].at) : null, }); } return { message: null, error: null, bikes }; }