chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow#82
chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow#82
Conversation
Code Review by Qodo
1. API repo filenames noncompliant
|
| @Injectable() | ||
| export class PrismaBookingAttendeeRepository extends BasePrismaBookingAttendeeRepository { | ||
| constructor(private readonly dbWrite: PrismaWriteService) { | ||
| super(dbWrite.prisma); | ||
| } | ||
| } |
There was a problem hiding this comment.
1. Api repo filenames noncompliant 📘 Rule violation ✓ Correctness
• The new Nest repositories are stored in kebab-case files with a .repository.ts suffix, instead of the required Prisma<Entity>Repository.ts PascalCase pattern. • This breaks the mandated repository naming/filename convention and makes repository classes harder to discover consistently.
Agent prompt
## Issue description
New Nest repository files under `apps/api/v2/src/lib/repositories/` use kebab-case and a `.repository.ts` suffix, which violates the required `Prisma<Entity>Repository.ts` naming pattern with filename/class-name match.
## Issue Context
Compliance requires repository files to be named exactly `Prisma<Entity>Repository.ts` (PascalCase) and match the exported class name.
## Fix Focus Areas
- apps/api/v2/src/lib/repositories/prisma-booking-attendee.repository.ts[1-11]
- apps/api/v2/src/lib/repositories/prisma-booking-reference.repository.ts[1-11]
- apps/api/v2/src/lib/repositories/prisma-profile.repository.ts[1-11]
- apps/api/v2/src/lib/repositories/prisma-booking.repository.ts[1-999999]
- apps/api/v2/src/lib/repositories/prisma-user.repository.ts[1-999999]
- apps/api/v2/src/lib/services/booking-cancel.service.ts[1-27]
- apps/api/v2/src/lib/modules/booking-cancel.module.ts[1-22]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| @Injectable() | ||
| export class BookingCancelService extends BaseBookingCancelService { | ||
| constructor(prismaWriteService: PrismaWriteService) { | ||
| constructor( | ||
| userRepository: PrismaUserRepository, | ||
| bookingRepository: PrismaBookingRepository, | ||
| profileRepository: PrismaProfileRepository, | ||
| bookingReferenceRepository: PrismaBookingReferenceRepository, | ||
| attendeeRepository: PrismaBookingAttendeeRepository | ||
| ) { | ||
| super({ |
There was a problem hiding this comment.
2. Api service filename noncompliant 📘 Rule violation ✓ Correctness
• The Nest service is implemented in booking-cancel.service.ts, which uses a dot-suffix and kebab-case instead of the required <Entity>Service.ts PascalCase filename. • This violates the mandated service naming/filename convention and reduces consistency across service discovery/imports.
Agent prompt
## Issue description
`BookingCancelService` is defined in `booking-cancel.service.ts`, which does not match the required `<Entity>Service.ts` PascalCase naming convention.
## Issue Context
Compliance requires service filenames to match the exported class name exactly in PascalCase.
## Fix Focus Areas
- apps/api/v2/src/lib/services/booking-cancel.service.ts[1-27]
- apps/api/v2/src/lib/modules/booking-cancel.module.ts[1-22]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| export class BookingRepository implements IBookingRepository { | ||
| constructor(private prismaClient: PrismaClient) {} | ||
|
|
There was a problem hiding this comment.
3. Repositories missing prisma prefix 📘 Rule violation ✓ Correctness
• Several updated repository classes are named without the required Prisma<Entity>Repository convention (e.g., BookingRepository, BookingReferenceRepository, ProfileRepository). • This violates the repository naming rule and undermines consistent DI bindings and codebase discoverability.
Agent prompt
## Issue description
Updated repository implementations do not follow the required `Prisma<Entity>Repository` class/filename naming convention.
## Issue Context
Compliance requires repository classes and filenames to match the `Prisma<Entity>Repository.ts` pattern with an exported class of the same name.
## Fix Focus Areas
- packages/features/bookings/repositories/BookingRepository.ts[347-349]
- packages/features/bookingReference/repositories/BookingReferenceRepository.ts[18-23]
- packages/features/profile/repositories/ProfileRepository.ts[100-106]
- packages/platform/libraries/repositories.ts[11-18]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| import type { PrismaClient } from '@calcom/prisma/client' | ||
|
|
||
| import type { IBookingAttendeeRepository } from '../lib/dto/IBookingAttendeeRepository' | ||
|
|
||
| export class PrismaBookingAttendeeRepository implements IBookingAttendeeRepository { | ||
| constructor(private prismaClient: PrismaClient) {} | ||
|
|
||
| async deleteManyByBookingId(bookingId: number): Promise<void> { | ||
| await this.prismaClient.attendee.deleteMany({ | ||
| where: { | ||
| bookingId, | ||
| }, | ||
| }) | ||
| } |
There was a problem hiding this comment.
4. Missing semicolons in repository 📘 Rule violation ✓ Correctness
• The new PrismaBookingAttendeeRepository implementation omits required semicolons, which violates the mandated Biome formatting rules. • Formatting drift makes automated formatting/linting inconsistent across the codebase.
Agent prompt
## Issue description
The new TypeScript repository file does not conform to Biome formatting requirements (notably missing semicolons).
## Issue Context
Compliance requires semicolons and standardized formatting across TS/JS files.
## Fix Focus Areas
- packages/features/bookings/repositories/PrismaBookingAttendeeRepository.ts[1-15]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| const gte = cancelSubsequentBookings ? bookingToDelete.startTime : new Date(); | ||
| // Proceed to mark as cancelled all remaining recurring events instances (greater than or equal to right now) | ||
| await prisma.booking.updateMany({ | ||
| await bookingRepository.updateMany({ | ||
| where: { | ||
| recurringEventId, | ||
| startTime: { |
There was a problem hiding this comment.
5. Recurring gte mismatch 🐞 Bug ✓ Correctness
• Bulk recurring cancellation updates bookings using a computed gte (either new Date() or bookingToDelete.startTime) but then fetches updated bookings using bookingToDelete.startTime unconditionally. • This can cause the follow-up audit/cleanup to process bookings that were not actually updated/cancelled (e.g., if cancelling from a past instance where gte was new Date()). • Downstream onBulkBookingsCancelled uses the fetched list, so audit logs/events can become inconsistent with persisted booking status.
Agent prompt
### Issue description
Recurring cancellation uses different `gte` constraints for the bulk update vs. the subsequent fetch used for audit/cleanup, which can cause processing of bookings that were not actually cancelled.
### Issue Context
The code computes `gte` based on `cancelSubsequentBookings` but fetches with `bookingToDelete.startTime` regardless.
### Fix Focus Areas
- packages/features/bookings/lib/handleCancelBooking.ts[497-520]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) { | ||
| await this.prismaClient.booking.updateMany({ | ||
| where: where, | ||
| data, | ||
| }); | ||
| } |
There was a problem hiding this comment.
6. Updatemany drops count 🐞 Bug ✓ Correctness
• BookingRepository declares implements IBookingRepository, but updateMany currently returns
void instead of { count: number }.
• This violates the interface contract and should fail TypeScript compilation (or break any caller
expecting the count).
• Fix is to return the Prisma updateMany(...) result (or adjust the interface/implementation
consistently).
Agent prompt
### Issue description
`BookingRepository.updateMany` returns void but must return `{ count: number }` per `IBookingRepository`, violating the interface.
### Issue Context
`BookingRepository` explicitly implements `IBookingRepository`, so method signatures must align.
### Fix Focus Areas
- packages/features/bookings/repositories/BookingRepository.ts[1502-1507]
- packages/lib/server/repository/dto/IBookingRepository.ts[46-55]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| createdDate: true, | ||
| trialEndsAt: true, | ||
| completedOnboarding: true, | ||
| locale: true, | ||
| timeFormat: true, | ||
| twoFactorSecret: true, | ||
| twoFactorEnabled: true, |
There was a problem hiding this comment.
7. Locale not selected 🐞 Bug ✓ Correctness
• Booking cancellation builds translations using organizer.locale, but UserRepository.findByIdOrThrow() ultimately selects userSelect, which no longer includes locale. • This is either a TypeScript type error (property doesn’t exist) or a runtime behavior change (locale becomes undefined, forcing fallback to "en"). • Result: cancellations/emails may be sent in the wrong language for non-English organizers.
Agent prompt
### Issue description
Cancellation logic depends on `organizer.locale`, but `UserRepository.findById` no longer selects `locale`, causing type/runtime regressions and wrong-language notifications.
### Issue Context
`handleCancelBooking` calls `userRepository.findByIdOrThrow` and then reads `organizer.locale`.
### Fix Focus Areas
- packages/features/users/repositories/UserRepository.ts[83-123]
- packages/features/bookings/lib/handleCancelBooking.ts[299-371]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| import { bindModuleToClassOnToken, createModule } from "@calcom/features/di/di"; | ||
| import { DI_TOKENS } from "@calcom/features/di/tokens"; | ||
| import { BookingReferenceRepository } from "@calcom/lib/server/repository/bookingReference"; | ||
| import { moduleLoader as prismaModuleLoader } from "@calcom/prisma/prisma.module"; | ||
|
|
There was a problem hiding this comment.
8. Di imports nonresolving 🐞 Bug ⛯ Reliability
• New DI modules import moduleLoader from @calcom/prisma/prisma.module, but the @calcom/prisma package does not expose that subpath (package main is index.ts and no prisma.module file is shipped). • BookingReferenceRepository.module.ts also imports BookingReferenceRepository from @calcom/lib/server/repository/bookingReference, but the booking reference repository implementation lives under @calcom/features/bookingReference/.... • These mismatched imports are likely to break builds/module loading for the booking cancellation DI wiring.
Agent prompt
### Issue description
New DI modules reference `@calcom/prisma/prisma.module` and `@calcom/lib/server/repository/bookingReference`, which do not align with the package layout in this repo and are likely to fail module resolution.
### Issue Context
The repo already provides a Prisma DI module loader in `packages/features/di/modules/Prisma.ts`, and `BookingReferenceRepository` is implemented in `packages/features/bookingReference/...`.
### Fix Focus Areas
- packages/features/bookings/di/BookingReferenceRepository.module.ts[1-16]
- packages/features/bookings/di/BookingAttendeeRepository.module.ts[1-15]
- packages/features/users/di/Profile.module.ts[1-17]
- packages/features/di/modules/Prisma.ts[1-18]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Benchmark PR from qodo-benchmark#682