* wip * update layoutHOC * wip * remove app router related code no longer used * remove more * await cookies, headers, params, serachparams * update yarn.lock * await cookies, headers, params, serachparams more * update yarn lock again * downgrade next-auth to 4.22.1 * update yarn lock * fix * update yarn lock * fix type checks * update yarn lock * await headers and cookies * restore pages folder * restore yarn.lock * update yarn.lock * await headers and cookies * remove * await params in API routes * updates * restore next.config.js * remove i18n from next.config.js * Fixed tests * Fixed types * Removed duplicate favicon.ico * Fixing more types * ImageResponse moved to next/og * Fixed prisma import issues * dynamic import for @ewsjs/xhr * remove deasync dep * dynamic import for @tryvital/vital-node * fix type checks * add back turbopack command * Type fix * Removed unneeded file * fix turbopack relative path errors * add comments * remove unneeded code * Fixed build errors * await apis * use Promise<Params> type in defaultResponderForAppDir util * refactor scim api route * fix type checks * separate app-routing.config into client-config and server-config * wip * refactor routing forms components * revert unneeded changes for easier review * fix * fix * use CustomTrans * fix type * fix unit tests * fix type error * fix build error * fix build error * fix build error * fix warnings * fix warnings * upgrade @tremor/react and tailwindcss * numCols -> numItems * fix forgot-password e2e test * fix 1 more e2e test * fix login e2e test * fix e2e tests * fix e2e tests * clean up * remove error * use tremor/react 2.11.0 * fix * rename CustomTrans to ServerTrans * address comment * fix test * fix ServerTrans * fix * fix type * fix ServerTrans usages 1 * fix translations * fix type checks * fix type checks * link styling * fix --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
213 lines
5.3 KiB
TypeScript
213 lines
5.3 KiB
TypeScript
import dayjs from "@calcom/dayjs";
|
|
import prisma from "@calcom/prisma";
|
|
import type { EventType, User, WorkflowReminder, WorkflowStep } from "@calcom/prisma/client";
|
|
import { Prisma } from "@calcom/prisma/client";
|
|
import { WorkflowMethods } from "@calcom/prisma/enums";
|
|
|
|
type PartialWorkflowStep =
|
|
| (Partial<WorkflowStep> & { workflow: { userId?: number; teamId?: number } })
|
|
| null;
|
|
|
|
type Booking = Prisma.BookingGetPayload<{
|
|
include: {
|
|
attendees: true;
|
|
};
|
|
}>;
|
|
|
|
type PartialBooking =
|
|
| (Pick<
|
|
Booking,
|
|
| "startTime"
|
|
| "endTime"
|
|
| "location"
|
|
| "description"
|
|
| "metadata"
|
|
| "customInputs"
|
|
| "responses"
|
|
| "uid"
|
|
| "attendees"
|
|
| "userPrimaryEmail"
|
|
| "smsReminderNumber"
|
|
| "title"
|
|
> & {
|
|
eventType:
|
|
| (Partial<EventType> & {
|
|
slug: string;
|
|
team: { parentId?: number; hideBranding: boolean };
|
|
hosts: { user: { email: string; destinationCalendar?: { primaryEmail: string } } }[] | undefined;
|
|
})
|
|
| null;
|
|
} & {
|
|
user: Partial<User> | null;
|
|
})
|
|
| null;
|
|
|
|
export type PartialWorkflowReminder = Pick<
|
|
WorkflowReminder,
|
|
"id" | "isMandatoryReminder" | "scheduledDate"
|
|
> & {
|
|
booking: PartialBooking | null;
|
|
} & { workflowStep: PartialWorkflowStep };
|
|
|
|
async function getWorkflowReminders<T extends Prisma.WorkflowReminderSelect>(
|
|
filter: Prisma.WorkflowReminderWhereInput,
|
|
select: T
|
|
): Promise<Array<Prisma.WorkflowReminderGetPayload<{ select: T }>>> {
|
|
const pageSize = 90;
|
|
let pageNumber = 0;
|
|
const filteredWorkflowReminders: Array<Prisma.WorkflowReminderGetPayload<{ select: T }>> = [];
|
|
|
|
while (true) {
|
|
const newFilteredWorkflowReminders = await prisma.workflowReminder.findMany({
|
|
where: filter,
|
|
select: select,
|
|
skip: pageNumber * pageSize,
|
|
take: pageSize,
|
|
});
|
|
|
|
if (newFilteredWorkflowReminders.length === 0) {
|
|
break;
|
|
}
|
|
|
|
filteredWorkflowReminders.push(
|
|
...(newFilteredWorkflowReminders as Array<Prisma.WorkflowReminderGetPayload<{ select: T }>>)
|
|
);
|
|
pageNumber++;
|
|
}
|
|
|
|
return filteredWorkflowReminders;
|
|
}
|
|
|
|
type RemindersToDeleteType = { referenceId: string | null };
|
|
|
|
export async function getAllRemindersToDelete(): Promise<RemindersToDeleteType[]> {
|
|
const whereFilter: Prisma.WorkflowReminderWhereInput = {
|
|
method: WorkflowMethods.EMAIL,
|
|
cancelled: true,
|
|
scheduledDate: {
|
|
lt: dayjs().toISOString(),
|
|
},
|
|
};
|
|
|
|
const select = Prisma.validator<Prisma.WorkflowReminderSelect>()({
|
|
referenceId: true,
|
|
});
|
|
|
|
const remindersToDelete = await getWorkflowReminders(whereFilter, select);
|
|
|
|
return remindersToDelete;
|
|
}
|
|
|
|
type RemindersToCancelType = { referenceId: string | null; id: number };
|
|
|
|
export async function getAllRemindersToCancel(): Promise<RemindersToCancelType[]> {
|
|
const whereFilter: Prisma.WorkflowReminderWhereInput = {
|
|
cancelled: true,
|
|
scheduled: true, //if it is false then they are already cancelled
|
|
scheduledDate: {
|
|
lte: dayjs().add(1, "hour").toISOString(),
|
|
},
|
|
};
|
|
|
|
const select = Prisma.validator<Prisma.WorkflowReminderSelect>()({
|
|
referenceId: true,
|
|
id: true,
|
|
});
|
|
|
|
const remindersToCancel = await getWorkflowReminders(whereFilter, select);
|
|
|
|
return remindersToCancel;
|
|
}
|
|
|
|
export const select = Prisma.validator<Prisma.WorkflowReminderSelect>()({
|
|
id: true,
|
|
scheduledDate: true,
|
|
isMandatoryReminder: true,
|
|
workflowStep: {
|
|
select: {
|
|
action: true,
|
|
sendTo: true,
|
|
reminderBody: true,
|
|
emailSubject: true,
|
|
template: true,
|
|
sender: true,
|
|
includeCalendarEvent: true,
|
|
workflow: {
|
|
select: {
|
|
userId: true,
|
|
teamId: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
booking: {
|
|
select: {
|
|
startTime: true,
|
|
endTime: true,
|
|
location: true,
|
|
description: true,
|
|
smsReminderNumber: true,
|
|
userPrimaryEmail: true,
|
|
user: {
|
|
select: {
|
|
email: true,
|
|
name: true,
|
|
timeZone: true,
|
|
locale: true,
|
|
username: true,
|
|
timeFormat: true,
|
|
hideBranding: true,
|
|
},
|
|
},
|
|
metadata: true,
|
|
uid: true,
|
|
customInputs: true,
|
|
responses: true,
|
|
attendees: true,
|
|
eventType: {
|
|
select: {
|
|
bookingFields: true,
|
|
title: true,
|
|
slug: true,
|
|
hosts: {
|
|
select: {
|
|
user: {
|
|
select: {
|
|
email: true,
|
|
destinationCalendar: {
|
|
select: {
|
|
primaryEmail: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
recurringEvent: true,
|
|
team: {
|
|
select: {
|
|
parentId: true,
|
|
hideBranding: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
export async function getAllUnscheduledReminders(): Promise<PartialWorkflowReminder[]> {
|
|
const whereFilter: Prisma.WorkflowReminderWhereInput = {
|
|
method: WorkflowMethods.EMAIL,
|
|
scheduled: false,
|
|
scheduledDate: {
|
|
lte: dayjs().add(2, "hour").toISOString(),
|
|
},
|
|
OR: [{ cancelled: false }, { cancelled: null }],
|
|
};
|
|
|
|
const unscheduledReminders = (await getWorkflowReminders(whereFilter, select)) as PartialWorkflowReminder[];
|
|
|
|
return unscheduledReminders;
|
|
}
|