* feat: Don't allow unavailable slot's booking form to be visible - Send back to slots listing * Improvements * feat: Add env variables and strategies to prevent booking failures - Added new environment variables for configuring slot reservation and availability checks - Implemented strategies to handle concurrent bookings and slot availability - Updated Booker component and related files to support new reservation and slot checking mechanisms - Added README with detailed explanation of booking prevention strategies - Configured dynamic intervals for slot and reservation queries * docs: Update Booker README with detailed slot reservation and availability explanation - Clarified slot reservation behavior when multiple users access the same booking page - Added details about `getSchedule` refetching strategies and timing - Explained how slot availability is detected and communicated to users * Support for skip confirmation form flow * feat: Enhance slot availability and reservation mechanism - Refactored slot availability checking to support multiple slots - Added tentative selected timeslots to improve booking UX - Updated trpc handler to check availability for multiple slots - Introduced new store methods for managing tentative slot selections - Improved slot reservation and availability status tracking * refactor: Improve slot availability quick check mechanism - Renamed and restructured slot availability check parameters - Extracted quick availability checks into a separate hook - Updated type definitions for slot status and availability checks - Simplified slot availability logic in Booker and related components - Maintained cached state for quick availability checks * Support minimu booking check too * change data-testid * Rneame * Fix race condition with uid cookie not set * fix tests * Remove unsded variable --------- Co-authored-by: Hariom Balhara <hariombalhara@gmgmail.com> Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
74 lines
1.6 KiB
TypeScript
74 lines
1.6 KiB
TypeScript
import type { Prisma } from "@prisma/client";
|
|
|
|
import { prisma } from "@calcom/prisma";
|
|
|
|
type WhereCondition = {
|
|
slotUtcStartDate?: Date | string;
|
|
slotUtcEndDate?: Date | string;
|
|
eventTypeId?: number;
|
|
uid?: string | { not: string };
|
|
releaseAt?: { gt: Date };
|
|
};
|
|
|
|
export type FindManyArgs = {
|
|
where?: WhereCondition & {
|
|
OR?: WhereCondition[];
|
|
};
|
|
select?: Prisma.SelectedSlotsSelect;
|
|
};
|
|
|
|
export type TimeSlot = {
|
|
utcStartIso: string;
|
|
utcEndIso: string;
|
|
};
|
|
|
|
export class SelectedSlotsRepository {
|
|
static async findMany({ where, select }: FindManyArgs) {
|
|
return await prisma.selectedSlots.findMany({ where, select });
|
|
}
|
|
|
|
static async findFirst({ where }: { where: Prisma.SelectedSlotsWhereInput }) {
|
|
return await prisma.selectedSlots.findFirst({
|
|
where,
|
|
});
|
|
}
|
|
|
|
static async findReservedByOthers({
|
|
slot,
|
|
eventTypeId,
|
|
uid,
|
|
}: {
|
|
slot: TimeSlot;
|
|
eventTypeId: number;
|
|
uid: string;
|
|
}) {
|
|
return await this.findFirst({
|
|
where: {
|
|
slotUtcStartDate: slot.utcStartIso,
|
|
slotUtcEndDate: slot.utcEndIso,
|
|
eventTypeId,
|
|
uid: { not: uid },
|
|
releaseAt: { gt: new Date() },
|
|
},
|
|
});
|
|
}
|
|
|
|
static async findManyReservedByOthers(slots: TimeSlot[], eventTypeId: number, uid: string) {
|
|
return await this.findMany({
|
|
where: {
|
|
OR: slots.map((slot) => ({
|
|
slotUtcStartDate: slot.utcStartIso,
|
|
slotUtcEndDate: slot.utcEndIso,
|
|
eventTypeId,
|
|
uid: { not: uid },
|
|
releaseAt: { gt: new Date() },
|
|
})),
|
|
},
|
|
select: {
|
|
slotUtcStartDate: true,
|
|
slotUtcEndDate: true,
|
|
},
|
|
});
|
|
}
|
|
}
|