This commit is contained in:
natib21
2026-07-03 15:37:24 +00:00
parent e893af8133
commit f2f6c89c0e
2 changed files with 32 additions and 7 deletions

View File

@@ -58,6 +58,23 @@ export class LastMileService {
}
}
/** Human booking reference for a last-mile record, for the history timeline.
* Uses the already-loaded relation when present, else looks it up. */
private async resolveBookingRef(
record: LastMile,
): Promise<string | null> {
const loaded = (record as LastMile & { booking?: { reference?: string } })
.booking?.reference;
if (loaded) return loaded;
if (!record.bookingId) return null;
try {
const booking = await this.bookingsRepository.findById(record.bookingId);
return (booking as { reference?: string } | null)?.reference ?? null;
} catch {
return null;
}
}
async acceptBooking(bookingReference: string): Promise<LastMile | null> {
const booking = await this.bookingsRepository.findByReference(bookingReference);
@@ -165,7 +182,7 @@ export class LastMileService {
lastMileId: record.id,
driverId: await this.resolveDriverId(dto.vehicleId),
label: record.status,
metadata: { mile: 'LAST' },
metadata: { mile: 'LAST', bookingRef: await this.resolveBookingRef(record) },
});
}
@@ -209,6 +226,7 @@ export class LastMileService {
}
// Audit the mile↔vehicle (re)assignment on both vehicle and driver lines.
const bookingRef = await this.resolveBookingRef(existing);
if (dto.vehicleId !== undefined && dto.vehicleId !== existing.vehicleId) {
if (existing.vehicleId) {
await this.history.record({
@@ -216,7 +234,7 @@ export class LastMileService {
vehicleId: existing.vehicleId,
lastMileId: id,
driverId: await this.resolveDriverId(existing.vehicleId),
metadata: { mile: 'LAST' },
metadata: { mile: 'LAST', bookingRef },
});
}
if (dto.vehicleId) {
@@ -226,7 +244,7 @@ export class LastMileService {
lastMileId: id,
driverId: await this.resolveDriverId(dto.vehicleId),
label: updated.status,
metadata: { mile: 'LAST' },
metadata: { mile: 'LAST', bookingRef },
});
}
}
@@ -240,7 +258,7 @@ export class LastMileService {
driverId: await this.resolveDriverId(vehicleId),
fromValue: existing.status,
toValue: dto.status,
metadata: { mile: 'LAST' },
metadata: { mile: 'LAST', bookingRef },
});
}

View File

@@ -42,6 +42,13 @@ const arrow = (from?: string | null, to?: string | null) =>
`${from ?? "—"}${to ?? "—"}`;
function describe(e: FleetHistoryEvent, entity: "driver" | "vehicle") {
const bookingRef =
typeof e.metadata?.bookingRef === "string" ? e.metadata.bookingRef : null;
const withBooking = (rest?: string) =>
[bookingRef ? `Booking ${bookingRef}` : "", rest ?? ""]
.filter(Boolean)
.join(" · ");
switch (e.eventType) {
case "DRIVER_REGISTERED":
return {
@@ -89,19 +96,19 @@ function describe(e: FleetHistoryEvent, entity: "driver" | "vehicle") {
return {
icon: <Route size={14} />,
title: `${mileLabel(e)}: vehicle assigned`,
text: e.label ? `Status: ${e.label}` : "",
text: withBooking(e.label ? `Status: ${e.label}` : ""),
};
case "MILE_VEHICLE_RELEASED":
return {
icon: <Route size={14} />,
title: `${mileLabel(e)}: vehicle released`,
text: "",
text: withBooking(),
};
case "MILE_STATUS_CHANGED":
return {
icon: <Route size={14} />,
title: `${mileLabel(e)} status`,
text: arrow(e.fromValue, e.toValue),
text: withBooking(arrow(e.fromValue, e.toValue)),
};
default:
return { icon: <CircleDot size={14} />, title: e.eventType, text: "" };