diff --git a/apps/edr-passenger-api/src/modules/seats/seats.service.ts b/apps/edr-passenger-api/src/modules/seats/seats.service.ts index 708f57792..c85b49bbf 100644 --- a/apps/edr-passenger-api/src/modules/seats/seats.service.ts +++ b/apps/edr-passenger-api/src/modules/seats/seats.service.ts @@ -280,7 +280,15 @@ export class SeatsService { throw new NotFoundException(`Seat(s) not found: ${missing.join(', ')}`); } - const blocked = seats.filter(s => s.status === 'BLOCKED' || s.status === 'BOOKED'); + // Only the raw BLOCKED status (seat pulled out of service — a genuine + // cross-schedule flag) is trusted here. BOOKED is intentionally NOT checked + // against this raw column: the same physical Seat row is reused across every + // recurring date a coach runs, and Seat.status only resets to AVAILABLE via a + // trip-completion event that isn't guaranteed to fire, so a stale BOOKED value + // here would wrongly block a seat that's actually free for this schedule/leg. + // The schedule- and leg-scoped SeatHold/JourneySegment checks below are the + // authoritative source for whether a seat is actually taken. + const blocked = seats.filter(s => s.status === 'BLOCKED'); if (blocked.length > 0) throw new ConflictException(`Seat(s) ${blocked.map(s => s.seatNumber).join(', ')} are already taken`);