mirror of
https://github.com/hanzoai/calendar.git
synced 2026-10-30 14:46:43 +00:00
2802310268
* feat: Add infrastructure for no-show audit integration - Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action - Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema - Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED - Update BookingAuditTaskConsumer and BookingAuditViewerService - Add AttendeeRepository methods for no-show queries - Update IAuditActionService interface with values array support - Update locales with no-show audit translation keys Co-Authored-By: [email protected] <[email protected]> * fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types Co-Authored-By: [email protected] <[email protected]> * fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema Co-Authored-By: [email protected] <[email protected]> * fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED Co-Authored-By: [email protected] <[email protected]> * refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService - Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService - Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit - Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit - Update BookingEventHandlerService.ts to use onNoShowUpdated - Add integration tests for NoShowUpdatedAuditActionService Co-Authored-By: [email protected] <[email protected]> * fix: Add data migration step for deprecated no-show enum values Addresses Cubic AI review feedback (confidence 9/10): The migration now includes an UPDATE statement to convert existing records using the deprecated 'host_no_show_updated' or 'attendee_no_show_updated' enum values to the new unified 'no_show_updated' value before the type cast. This prevents migration failures if any existing data uses the old values. Co-Authored-By: unknown <> * fix: Use CASE expression in USING clause for enum migration Fixes PostgreSQL error 'unsafe use of new value of enum type' by avoiding the ADD VALUE statement and instead using a CASE expression in the ALTER TABLE USING clause to convert deprecated enum values (host_no_show_updated, attendee_no_show_updated) to the new unified value (no_show_updated) during the type conversion. Co-Authored-By: unknown <> * fix: Replace hardcoded color with semantic text-success class Co-Authored-By: [email protected] <[email protected]> * fix: Remove color class completely from display fields Co-Authored-By: [email protected] <[email protected]> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
144 lines
3.4 KiB
TypeScript
144 lines
3.4 KiB
TypeScript
import type { PrismaClient } from "@calcom/prisma";
|
|
import type { IAttendeeRepository } from "./IAttendeeRepository";
|
|
|
|
const safeSelect = {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
locale: true,
|
|
timeZone: true,
|
|
phoneNumber: true,
|
|
bookingId: true,
|
|
noShow: true,
|
|
};
|
|
|
|
/**
|
|
* Prisma-based implementation of IAttendeeRepository
|
|
*
|
|
* This repository provides methods for looking up attendee information.
|
|
*/
|
|
export class AttendeeRepository implements IAttendeeRepository {
|
|
constructor(private prismaClient: PrismaClient) {}
|
|
|
|
async findById(id: number): Promise<{ name: string; email: string } | null> {
|
|
const attendee = await this.prismaClient.attendee.findUnique({
|
|
where: { id },
|
|
select: {
|
|
name: true,
|
|
email: true,
|
|
},
|
|
});
|
|
|
|
return attendee;
|
|
}
|
|
|
|
async findByIds({ ids }: { ids: number[] }): Promise<{ id: number; name: string; email: string }[]> {
|
|
return this.prismaClient.attendee.findMany({
|
|
where: { id: { in: ids } },
|
|
select: {
|
|
id: true,
|
|
name: true,
|
|
email: true,
|
|
},
|
|
});
|
|
}
|
|
|
|
async findByBookingIdAndSeatReference({
|
|
bookingId,
|
|
seatReferenceUid,
|
|
}: {
|
|
bookingId: number;
|
|
seatReferenceUid: string;
|
|
}): Promise<{ email: string }[]> {
|
|
return this.prismaClient.attendee.findMany({
|
|
where: {
|
|
bookingId,
|
|
bookingSeat: {
|
|
referenceUid: seatReferenceUid,
|
|
},
|
|
},
|
|
select: { email: true },
|
|
});
|
|
}
|
|
|
|
async findByBookingUidAndEmails({
|
|
bookingUid,
|
|
emails,
|
|
}: {
|
|
bookingUid: string;
|
|
emails: string[];
|
|
}): Promise<{ id: number; email: string; noShow: boolean | null }[]> {
|
|
return this.prismaClient.attendee.findMany({
|
|
where: {
|
|
booking: { uid: bookingUid },
|
|
email: { in: emails },
|
|
},
|
|
select: { id: true, email: true, noShow: true },
|
|
});
|
|
}
|
|
|
|
async updateNoShow({
|
|
where: { attendeeId },
|
|
data: { noShow },
|
|
}: {
|
|
where: { attendeeId: number };
|
|
data: { noShow: boolean };
|
|
}): Promise<{ noShow: boolean | null; email: string }> {
|
|
return this.prismaClient.attendee.update({
|
|
where: { id: attendeeId },
|
|
data: { noShow },
|
|
select: { noShow: true, email: true },
|
|
});
|
|
}
|
|
|
|
async findByBookingId(bookingId: number): Promise<
|
|
{
|
|
id: number;
|
|
email: string;
|
|
name: string;
|
|
locale: string | null;
|
|
timeZone: string;
|
|
phoneNumber: string | null;
|
|
bookingId: number | null;
|
|
noShow: boolean | null;
|
|
}[]
|
|
> {
|
|
return this.prismaClient.attendee.findMany({
|
|
where: { bookingId },
|
|
select: safeSelect,
|
|
});
|
|
}
|
|
|
|
async updateManyNoShowByBookingIdAndEmails({
|
|
where: { bookingId, emails },
|
|
data: { noShow },
|
|
}: {
|
|
where: { bookingId: number; emails: string[] };
|
|
data: { noShow: boolean };
|
|
}): Promise<{ count: number }> {
|
|
return this.prismaClient.attendee.updateMany({
|
|
where: {
|
|
bookingId,
|
|
email: { in: emails },
|
|
},
|
|
data: { noShow },
|
|
});
|
|
}
|
|
|
|
async updateManyNoShowByBookingIdExcludingEmails({
|
|
where: { bookingId, excludeEmails },
|
|
data: { noShow },
|
|
}: {
|
|
where: { bookingId: number; excludeEmails: string[] };
|
|
data: { noShow: boolean };
|
|
}): Promise<{ count: number }> {
|
|
return this.prismaClient.attendee.updateMany({
|
|
where: {
|
|
bookingId,
|
|
email: { notIn: excludeEmails },
|
|
},
|
|
data: { noShow },
|
|
});
|
|
}
|
|
}
|