Async scalars & less queries due to grouping (#14904)

This commit is contained in:
Alex van Andel
2024-05-07 15:18:07 +01:00
committed by GitHub
parent bc0c40d260
commit 7cf840723b
3 changed files with 76 additions and 206 deletions
+9 -34
View File
@@ -110,43 +110,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
teamId: null,
},
],
createdAt: {
gte: dayjs(firstDateOfMonth).toISOString(),
lte: dayjs(new Date()).toISOString(),
},
};
const promisesResult = await Promise.all([
EventsInsights.getCreatedEventsInTimeRange(
{
start: dayjs(firstDateOfMonth),
end: dayjs(new Date()),
},
whereConditional
),
EventsInsights.getCompletedEventsInTimeRange(
{
start: dayjs(firstDateOfMonth),
end: dayjs(new Date()),
},
whereConditional
),
EventsInsights.getRescheduledEventsInTimeRange(
{
start: dayjs(firstDateOfMonth),
end: dayjs(new Date()),
},
whereConditional
),
EventsInsights.getCancelledEventsInTimeRange(
{
start: dayjs(firstDateOfMonth),
end: dayjs(new Date()),
},
whereConditional
),
]);
const countGroupedByStatus = await EventsInsights.countGroupedByStatus(whereConditional);
EventData["Created"] = promisesResult[0];
EventData["Completed"] = promisesResult[1];
EventData["Rescheduled"] = promisesResult[2];
EventData["Cancelled"] = promisesResult[3];
EventData["Created"] = countGroupedByStatus["_all"];
EventData["Completed"] = countGroupedByStatus["completed"];
EventData["Rescheduled"] = countGroupedByStatus["rescheduled"];
EventData["Cancelled"] = countGroupedByStatus["cancelled"];
// Most Booked Event Type
const bookingWhere: Prisma.BookingTimeStatusWhereInput = {
+19 -105
View File
@@ -13,115 +13,29 @@ interface ITimeRange {
type TimeViewType = "week" | "month" | "year" | "day";
class EventsInsights {
static getBookingsInTimeRange = async (
timeRange: ITimeRange,
where: Prisma.BookingTimeStatusWhereInput
) => {
const { start, end } = timeRange;
const events = await prisma.bookingTimeStatus.count({
where: {
...where,
createdAt: {
gte: start.toISOString(),
lte: end.toISOString(),
},
},
});
return events;
};
static getCreatedEventsInTimeRange = async (
timeRange: ITimeRange,
where: Prisma.BookingTimeStatusWhereInput
) => {
const result = await this.getBookingsInTimeRange(timeRange, where);
return result;
};
static getCancelledEventsInTimeRange = async (
timeRange: ITimeRange,
where: Prisma.BookingTimeStatusWhereInput
) => {
const result = await this.getBookingsInTimeRange(timeRange, {
...where,
timeStatus: "cancelled",
});
return result;
};
static getCompletedEventsInTimeRange = async (
timeRange: ITimeRange,
where: Prisma.BookingTimeStatusWhereInput
) => {
const result = await this.getBookingsInTimeRange(timeRange, {
...where,
timeStatus: "completed",
});
return result;
};
static getRescheduledEventsInTimeRange = async (
timeRange: ITimeRange,
where: Prisma.BookingTimeStatusWhereInput
) => {
const result = await this.getBookingsInTimeRange(timeRange, {
...where,
timeStatus: "rescheduled",
});
return result;
};
static getNoShowHostsInTimeRange = async (
timeRange: ITimeRange,
where: Prisma.BookingTimeStatusWhereInput
) => {
const result = await this.getBookingsInTimeRange(timeRange, {
...where,
noShowHost: true,
});
return result;
};
static getBaseBookingCountForEventStatus = async (where: Prisma.BookingTimeStatusWhereInput) => {
const baseBookings = await prisma.bookingTimeStatus.count({
static countGroupedByStatus = async (where: Prisma.BookingTimeStatusWhereInput) => {
const data = await prisma.bookingTimeStatus.groupBy({
where,
});
return baseBookings;
};
static getTotalCompletedEvents = async (whereConditional: Prisma.BookingTimeStatusWhereInput) => {
return await prisma.bookingTimeStatus.count({
where: {
...whereConditional,
timeStatus: "completed",
by: ["timeStatus"],
_count: {
_all: true,
},
});
};
static getTotalRescheduledEvents = async (whereConditional: Prisma.BookingTimeStatusWhereInput) => {
return await prisma.bookingTimeStatus.count({
where: {
...whereConditional,
timeStatus: "rescheduled",
return data.reduce(
(aggregate: { [x: string]: number }, item) => {
if (typeof item.timeStatus === "string") {
aggregate[item.timeStatus] = item._count._all;
aggregate["_all"] += item._count._all;
}
return aggregate;
},
});
};
static getTotalCancelledEvents = async (whereConditional: Prisma.BookingTimeStatusWhereInput) => {
return await prisma.bookingTimeStatus.count({
where: {
...whereConditional,
timeStatus: "cancelled",
},
});
{
completed: 0,
rescheduled: 0,
cancelled: 0,
_all: 0,
}
);
};
static getAverageRating = async (whereConditional: Prisma.BookingTimeStatusWhereInput) => {
@@ -259,24 +259,8 @@ export const insightsRouter = router({
},
};
const baseBookingsCount = await EventsInsights.getBaseBookingCountForEventStatus(baseWhereCondition);
const startTimeEndTimeDiff = dayjs(endDate).diff(dayjs(startDate), "day");
const totalCompleted = await EventsInsights.getTotalCompletedEvents(baseWhereCondition);
const totalRescheduled = await EventsInsights.getTotalRescheduledEvents(baseWhereCondition);
const totalCancelled = await EventsInsights.getTotalCancelledEvents(baseWhereCondition);
const totalRatingsAggregate = await EventsInsights.getAverageRating(baseWhereCondition);
const averageRating = totalRatingsAggregate._avg.rating
? parseFloat(totalRatingsAggregate._avg.rating.toFixed(1))
: 0;
const totalNoShow = await EventsInsights.getTotalNoShows(baseWhereCondition);
const totalCSAT = await EventsInsights.getTotalCSAT(baseWhereCondition);
const lastPeriodStartDate = dayjs(startDate).subtract(startTimeEndTimeDiff, "day");
const lastPeriodEndDate = dayjs(endDate).subtract(startTimeEndTimeDiff, "day");
@@ -289,23 +273,43 @@ export const insightsRouter = router({
teamId: teamId,
};
const lastPeriodBaseBookingsCount = await EventsInsights.getBaseBookingCountForEventStatus(
lastPeriodBaseCondition
);
const [
countGroupedByStatus,
totalRatingsAggregate,
totalNoShow,
totalCSAT,
lastPeriodCountGroupedByStatus,
lastPeriodTotalRatingsAggregate,
lastPeriodTotalNoShow,
lastPeriodTotalCSAT,
] = await Promise.all([
EventsInsights.countGroupedByStatus(baseWhereCondition),
EventsInsights.getAverageRating(baseWhereCondition),
EventsInsights.getTotalNoShows(baseWhereCondition),
EventsInsights.getTotalCSAT(baseWhereCondition),
EventsInsights.countGroupedByStatus(lastPeriodBaseCondition),
EventsInsights.getAverageRating(lastPeriodBaseCondition),
EventsInsights.getTotalNoShows(lastPeriodBaseCondition),
EventsInsights.getTotalCSAT(lastPeriodBaseCondition),
]);
const lastPeriodTotalRescheduled = await EventsInsights.getTotalRescheduledEvents(
lastPeriodBaseCondition
);
const baseBookingsCount = countGroupedByStatus["_all"];
const totalCompleted = countGroupedByStatus["completed"];
const totalRescheduled = countGroupedByStatus["rescheduled"];
const totalCancelled = countGroupedByStatus["cancelled"];
const averageRating = totalRatingsAggregate._avg.rating
? parseFloat(totalRatingsAggregate._avg.rating.toFixed(1))
: 0;
const lastPeriodBaseBookingsCount = lastPeriodCountGroupedByStatus["_all"];
const lastPeriodTotalRescheduled = lastPeriodCountGroupedByStatus["rescheduled"];
const lastPeriodTotalCancelled = lastPeriodCountGroupedByStatus["cancelled"];
const lastPeriodTotalCancelled = await EventsInsights.getTotalCancelledEvents(lastPeriodBaseCondition);
const lastPeriodTotalRatingsAggregate = await EventsInsights.getAverageRating(lastPeriodBaseCondition);
const lastPeriodAverageRating = lastPeriodTotalRatingsAggregate._avg.rating
? parseFloat(lastPeriodTotalRatingsAggregate._avg.rating.toFixed(1))
: 0;
const lastPeriodTotalNoShow = await EventsInsights.getTotalNoShows(lastPeriodBaseCondition);
const lastPeriodTotalCSAT = await EventsInsights.getTotalCSAT(lastPeriodBaseCondition);
const result = {
empty: false,
created: {
@@ -525,48 +529,25 @@ export const insightsRouter = router({
startDate = dayjs(date).startOf("day");
endDate = dayjs(date).add(6, "day").endOf("day");
}
whereConditional = {
...whereConditional,
createdAt: {
gte: startDate.toISOString(),
lte: endDate.toISOString(),
},
};
const promisesResult = await Promise.all([
EventsInsights.getCreatedEventsInTimeRange(
{
start: startDate,
end: endDate,
},
whereConditional
),
EventsInsights.getCompletedEventsInTimeRange(
{
start: startDate,
end: endDate,
},
whereConditional
),
EventsInsights.getRescheduledEventsInTimeRange(
{
start: startDate,
end: endDate,
},
whereConditional
),
EventsInsights.getCancelledEventsInTimeRange(
{
start: startDate,
end: endDate,
},
whereConditional
),
EventsInsights.getNoShowHostsInTimeRange(
{
start: startDate,
end: endDate,
},
whereConditional
),
EventsInsights.countGroupedByStatus(whereConditional),
EventsInsights.getTotalNoShows(whereConditional),
]);
EventData["Created"] = promisesResult[0];
EventData["Completed"] = promisesResult[1];
EventData["Rescheduled"] = promisesResult[2];
EventData["Cancelled"] = promisesResult[3];
EventData["No-Show (Host)"] = promisesResult[4];
EventData["Created"] = promisesResult[0]["_all"];
EventData["Completed"] = promisesResult[0]["completed"];
EventData["Rescheduled"] = promisesResult[0]["rescheduled"];
EventData["Cancelled"] = promisesResult[0]["cancelled"];
EventData["No-Show (Host)"] = promisesResult[1];
result.push(EventData);
}