Files
calendar/packages/lib/intervalLimits/server/checkDurationLimits.ts
T
devin-ai-integration[bot]GitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>morgan@cal.com <morgan@cal.com>Morgan
cfda4757e4 refactor: move getTotalBookingDuration to BookingRepository (#22931)
* refactor: move getTotalBookingDuration to BookingRepository

- Move getTotalBookingDuration function from standalone file to BookingRepository class
- Update all usage sites to call method through repository instance
- Remove standalone function file packages/lib/server/queries/booking/index.ts
- Add prisma import to util.ts for BookingRepository instantiation
- Maintain exact same method signature and functionality

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fix: remove eslint-config-next to resolve TypeScript ESLint conflicts

- Remove eslint-config-next dependency that was causing version conflicts
- Resolves 'Class extends value undefined is not a constructor or null' errors
- ESLint 'next' config issue appears to be pre-existing in main branch

Co-Authored-By: morgan@cal.com <morgan@cal.com>

* fixup! Merge branch 'main' into devin/move-getTotalBookingDuration-1754460208

* chore: bump platform libs

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: morgan@cal.com <morgan@cal.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
2025-08-07 10:53:18 +03:00

75 lines
2.0 KiB
TypeScript

import dayjs from "@calcom/dayjs";
import { getErrorFromUnknown } from "@calcom/lib/errors";
import { HttpError } from "@calcom/lib/http-error";
import { BookingRepository } from "@calcom/lib/server/repository/booking";
import prisma from "@calcom/prisma";
import { ascendingLimitKeys, intervalLimitKeyToUnit } from "../intervalLimit";
import type { IntervalLimit, IntervalLimitKey } from "../intervalLimitSchema";
import { parseDurationLimit } from "../isDurationLimits";
export async function checkDurationLimits(
durationLimits: IntervalLimit,
eventStartDate: Date,
eventId: number,
rescheduleUid?: string
) {
const parsedDurationLimits = parseDurationLimit(durationLimits);
if (!parsedDurationLimits) return false;
// not iterating entries to preserve types
const limitCalculations = ascendingLimitKeys.map((key) =>
checkDurationLimit({
key,
limitingNumber: parsedDurationLimits[key],
eventStartDate,
eventId,
rescheduleUid,
})
);
try {
return !!(await Promise.all(limitCalculations));
} catch (error) {
throw new HttpError({ message: getErrorFromUnknown(error).message, statusCode: 401 });
}
}
export async function checkDurationLimit({
eventStartDate,
eventId,
key,
limitingNumber,
rescheduleUid,
}: {
eventStartDate: Date;
eventId: number;
key: IntervalLimitKey;
limitingNumber: number | undefined;
rescheduleUid?: string;
}) {
{
if (!limitingNumber) return;
const unit = intervalLimitKeyToUnit(key);
const startDate = dayjs(eventStartDate).startOf(unit).toDate();
const endDate = dayjs(eventStartDate).endOf(unit).toDate();
const bookingRepo = new BookingRepository(prisma);
const totalBookingDuration = await bookingRepo.getTotalBookingDuration({
eventId,
startDate,
endDate,
rescheduleUid,
});
if (totalBookingDuration < limitingNumber) return;
throw new HttpError({
message: `duration_limit_reached`,
statusCode: 403,
});
}
}