Code Review Bench PR #24159 - chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow#3
Conversation
| @@ -98,7 +98,6 @@ const userSelect = { | |||
| createdDate: true, | |||
| trialEndsAt: true, | |||
| completedOnboarding: true, | |||
There was a problem hiding this comment.
🚨 Bug: Removing locale from userSelect breaks organizer translation
The locale field was removed from userSelect in UserRepository.ts, but organizer.locale is still accessed in handleCancelBooking.ts at lines 337 and 395. Since findByIdOrThrow uses userSelect to determine which fields to fetch, locale will no longer be returned by Prisma. This means organizer.locale will be undefined, and the translation will always fall back to "en", breaking localized cancellation emails for non-English users.
This is a data regression — every cancellation notification will now be sent in English regardless of the organizer's locale preference.
Was this helpful? React with 👍 / 👎
| completedOnboarding: true, | |
| completedOnboarding: true, | |
| locale: true, | |
| timeFormat: true, |
- Apply suggested fix
| }); | ||
| } | ||
|
|
||
| async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) { |
There was a problem hiding this comment.
⚠️ Bug: updateMany return type mismatch with IBookingRepository
The IBookingRepository interface declares updateMany as returning Promise<{ count: number }>, but the implementation in BookingRepository.updateMany (line 1502) uses await without return, making it effectively return Promise<void>.
Prisma's updateMany returns Prisma.BatchPayload (which has a count field), but since the result is discarded with await (no return), any consumer relying on the interface contract to get the count back will get undefined at runtime.
While the current callers in handleCancelBooking don't use the return value, this violates the interface contract and will break any future consumer that does.
Was this helpful? React with 👍 / 👎
| async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) { | |
| async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) { | |
| return await this.prismaClient.booking.updateMany({ | |
| where: where, | |
| data, | |
| }); | |
| } |
- Apply suggested fix
| uid: string; | ||
| } | ||
|
|
||
| export interface IBookingRepository { |
There was a problem hiding this comment.
⚠️ Bug: updateIncludeWorkflowRemindersAndReferences missing from interface
The handleCancelBooking.ts handler calls bookingRepository.updateIncludeWorkflowRemindersAndReferences() (line 546), and BookingRepository implements it (line 1520), but this method is not declared in the IBookingRepository interface.
This means:
- The interface is incomplete — anyone implementing
IBookingRepositoryfor testing or alternative backends won't know they need this method. - If the
Dependenciestype orBookingCancelServiceis ever updated to useIBookingRepositoryinstead of the concreteBookingRepository, TypeScript won't catch the missing method, and it will fail at runtime.
The method should be added to IBookingRepository to maintain the interface contract.
Was this helpful? React with 👍 / 👎
- Apply suggested fix
| externalCalendarId: true, | ||
| credentialId: true, | ||
| }, | ||
| gte: bookingToDelete.startTime, |
There was a problem hiding this comment.
⚠️ Bug: Behavioral change: findMany gte filter uses wrong date
In the recurring booking cancellation path, the findManyIncludeWorkflowRemindersAndReferences query now uses gte: bookingToDelete.startTime (line 517) instead of the original gte: new Date().
For the allRemainingBookings case (not cancelSubsequentBookings), the updateMany correctly cancels bookings with gte: new Date(), but the subsequent findMany uses gte: bookingToDelete.startTime, which could be in the past. This means the findMany will also fetch bookings that have already occurred (between bookingToDelete.startTime and now) and were NOT cancelled by the updateMany. This will cause workflow reminder cleanup to run on bookings that shouldn't have been touched, potentially deleting reminders for already-completed bookings.
The original code correctly used new Date() for both the updateMany and the findMany in the allRemainingBookings path.
Was this helpful? React with 👍 / 👎
| gte: bookingToDelete.startTime, | |
| const allUpdatedBookings = await bookingRepository.findManyIncludeWorkflowRemindersAndReferences({ | |
| where: { | |
| recurringEventId: bookingToDelete.recurringEventId, | |
| startTime: { | |
| gte, | |
| }, | |
| }, | |
| }); |
- Apply suggested fix
There was a problem hiding this comment.
Configure merge blocking · Maintainers can dismiss this review. Gitar never approves changes.
Code Review 🚫 Blocked 0 resolved / 5 findingsRepository pattern refactor has a critical bug (removing 🚨 Bug: Removing
|
| Auto-apply | Compact |
|
|
Was this helpful? React with 👍 / 👎 | Gitar
Benchmark Evaluation ResultsGround Truth Bugs (Recall: 4/6 = 66.7%)
Extra Gitar Findings
Summary
|
Code Review Bench PR calcom#24159 - chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow
Benchmark PR for Gitar evaluation
Original PR: agentic-review-benchmarks#3
chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow
Summary by Gitar
IUserRepository,IBookingRepository,IProfileRepository,IBookingReferenceRepository,IBookingAttendeeRepository) to replace direct Prisma client access in the booking cancellation flowBookingCancelServiceconstructor to accept repository dependencies instead of raw Prisma client, enabling better testability through dependency injection while maintaining backward compatibility via optional injectionpackages/features/di/,apps/api/v2/src/lib/modules/, andapps/api/v2/src/lib/repositories/This will update automatically on new commits.