archetecture security fix
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getVehicleAvailabilitySummary = getVehicleAvailabilitySummary;
|
||||
const prisma_1 = require("../lib/prisma");
|
||||
const BLOCKING_RESERVATION_STATUSES = ['DRAFT', 'CONFIRMED', 'ACTIVE'];
|
||||
function startOfTodayUtc() {
|
||||
const now = new Date();
|
||||
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
|
||||
}
|
||||
function overlaps(range, source) {
|
||||
return source.startDate < range.endDate && source.endDate > range.startDate;
|
||||
}
|
||||
function getNextAvailableAt(anchor, sources) {
|
||||
const sorted = sources
|
||||
.filter((source) => source.endDate > anchor)
|
||||
.sort((a, b) => {
|
||||
const startDelta = a.startDate.getTime() - b.startDate.getTime();
|
||||
if (startDelta !== 0)
|
||||
return startDelta;
|
||||
return a.endDate.getTime() - b.endDate.getTime();
|
||||
});
|
||||
let candidate = anchor;
|
||||
let advanced = false;
|
||||
for (const source of sorted) {
|
||||
if (source.endDate <= candidate)
|
||||
continue;
|
||||
if (source.startDate > candidate)
|
||||
break;
|
||||
candidate = new Date(Math.max(candidate.getTime(), source.endDate.getTime()));
|
||||
advanced = true;
|
||||
}
|
||||
return advanced ? candidate : null;
|
||||
}
|
||||
async function getVehicleAvailabilitySummary(vehicleId, { range, includeDraftReservations = true, companyId, } = {}) {
|
||||
const vehicle = await prisma_1.prisma.vehicle.findFirstOrThrow({
|
||||
where: { id: vehicleId, ...(companyId ? { companyId } : {}) },
|
||||
select: { status: true },
|
||||
});
|
||||
if (vehicle.status === 'OUT_OF_SERVICE') {
|
||||
return {
|
||||
available: false,
|
||||
status: 'UNAVAILABLE',
|
||||
nextAvailableAt: null,
|
||||
blockingReason: 'STATUS',
|
||||
};
|
||||
}
|
||||
const anchor = range?.startDate ?? startOfTodayUtc();
|
||||
const reservationStatuses = includeDraftReservations
|
||||
? [...BLOCKING_RESERVATION_STATUSES]
|
||||
: BLOCKING_RESERVATION_STATUSES.filter((status) => status !== 'DRAFT');
|
||||
const [reservations, blocks] = await Promise.all([
|
||||
prisma_1.prisma.reservation.findMany({
|
||||
where: {
|
||||
vehicleId,
|
||||
status: { in: reservationStatuses },
|
||||
endDate: { gt: anchor },
|
||||
},
|
||||
select: { startDate: true, endDate: true },
|
||||
orderBy: { startDate: 'asc' },
|
||||
}),
|
||||
prisma_1.prisma.vehicleCalendarBlock.findMany({
|
||||
where: {
|
||||
vehicleId,
|
||||
endDate: { gt: anchor },
|
||||
},
|
||||
select: { startDate: true, endDate: true, type: true },
|
||||
orderBy: { startDate: 'asc' },
|
||||
}),
|
||||
]);
|
||||
const sources = [
|
||||
...reservations.map((reservation) => ({
|
||||
startDate: reservation.startDate,
|
||||
endDate: reservation.endDate,
|
||||
kind: 'RESERVATION',
|
||||
})),
|
||||
...blocks.map((block) => ({
|
||||
startDate: block.startDate,
|
||||
endDate: block.endDate,
|
||||
kind: block.type === 'MAINTENANCE' ? 'MAINTENANCE' : 'BLOCK',
|
||||
})),
|
||||
];
|
||||
const overlappingSources = range ? sources.filter((source) => overlaps(range, source)) : sources.filter((source) => source.startDate <= anchor && source.endDate > anchor);
|
||||
const currentSource = overlappingSources.sort((a, b) => {
|
||||
const priority = { MAINTENANCE: 0, BLOCK: 1, RESERVATION: 2 };
|
||||
return priority[a.kind] - priority[b.kind];
|
||||
})[0];
|
||||
if (vehicle.status === 'MAINTENANCE') {
|
||||
return {
|
||||
available: false,
|
||||
status: 'MAINTENANCE',
|
||||
nextAvailableAt: getNextAvailableAt(anchor, sources) ?? null,
|
||||
blockingReason: currentSource?.kind ?? 'STATUS',
|
||||
};
|
||||
}
|
||||
if (!currentSource) {
|
||||
return {
|
||||
available: true,
|
||||
status: 'AVAILABLE',
|
||||
nextAvailableAt: null,
|
||||
blockingReason: null,
|
||||
};
|
||||
}
|
||||
const nextAvailableAnchor = currentSource.startDate > anchor ? currentSource.startDate : anchor;
|
||||
return {
|
||||
available: false,
|
||||
status: currentSource.kind === 'RESERVATION' ? 'RESERVED' : currentSource.kind === 'MAINTENANCE' ? 'MAINTENANCE' : 'UNAVAILABLE',
|
||||
nextAvailableAt: getNextAvailableAt(nextAvailableAnchor, sources),
|
||||
blockingReason: currentSource.kind,
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=vehicleAvailabilityService.js.map
|
||||
Reference in New Issue
Block a user