Skip to content

chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow#30

Open
tomerqodo wants to merge 2 commits intocoderabbit_full_base_chore_booking_cancellation_refactor_-_2_inject_repositories_and_use_them_instead_of_prisma_in_cancellation_flow_pr3from
coderabbit_full_head_chore_booking_cancellation_refactor_-_2_inject_repositories_and_use_them_instead_of_prisma_in_cancellation_flow_pr3
Open

chore: [Booking Cancellation Refactor - 2] Inject repositories and use them instead of Prisma in cancellation flow#30
tomerqodo wants to merge 2 commits intocoderabbit_full_base_chore_booking_cancellation_refactor_-_2_inject_repositories_and_use_them_instead_of_prisma_in_cancellation_flow_pr3from
coderabbit_full_head_chore_booking_cancellation_refactor_-_2_inject_repositories_and_use_them_instead_of_prisma_in_cancellation_flow_pr3

Conversation

@tomerqodo
Copy link

@tomerqodo tomerqodo commented Jan 29, 2026

Benchmark PR from agentic-review-benchmarks#3

Summary by CodeRabbit

  • Refactor

    • Restructured booking cancellation workflow to improve data handling and reliability.
    • Enhanced attendee, reference, and booking management during cancellations.
  • Tests

    • Added comprehensive test coverage for seated events cancellation.
    • Added tests for recurring and subsequent booking cancellations.
    • Added tests for booking reference cleanup during cancellation.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

Walkthrough

This PR refactors the booking cancellation system by implementing the repository pattern with dependency injection. Five new repository classes are created (BookingAttendee, BookingReference, Profile in API v2 and base packages), corresponding DI modules and tokens are established, and BookingCancelService is updated to accept repository dependencies instead of direct Prisma client usage. The handleCancelBooking handler is modified to accept injected repository dependencies and use them for data access.

Changes

Cohort / File(s) Change Summary
API v2 Repository Implementations
apps/api/v2/src/lib/repositories/prisma-booking-attendee.repository.ts, prisma-booking-reference.repository.ts, prisma-profile.repository.ts
Three new injectable repository classes created, each extending base repositories and accepting PrismaWriteService via constructor for Prisma client access.
API v2 Module & Service Configuration
apps/api/v2/src/lib/modules/booking-cancel.module.ts, services/booking-cancel.service.ts
Module now registers five repository providers; service constructor refactored from single PrismaWriteService to five specific repository dependencies with updated super() call.
DI Module Definitions
packages/features/bookings/di/BookingAttendeeRepository.module.ts, BookingCancelService.module.ts, BookingReferenceRepository.module.ts
packages/features/users/di/Profile.module.ts
Four new DI module files created, each defining module creation, dependency wiring via prismaModuleLoader, and exported moduleLoader objects for runtime initialization.
DI Token Additions
packages/features/bookings/di/tokens.ts, packages/features/di/tokens.ts
New DI tokens added: BOOKING_REFERENCE_REPOSITORY, BOOKING_REFERENCE_REPOSITORY_MODULE, BOOKING_ATTENDEE_REPOSITORY, BOOKING_ATTENDEE_REPOSITORY_MODULE, PROFILE_REPOSITORY, PROFILE_REPOSITORY_MODULE.
Repository Interface Definitions
packages/features/bookings/lib/dto/IBookingAttendeeRepository.ts
packages/lib/server/repository/dto/IBookingReferenceRepository.ts, IBookingRepository.ts, IProfileRepository.ts
Four new DTO/interface files defining repository contracts: IBookingAttendeeRepository with deleteManyByBookingId, IBookingReferenceRepository with updateManyByBookingId, IBookingRepository with bulk/single update and query methods, IProfileRepository with findFirstByUserId.
Core Repository Implementations
packages/features/bookingReference/repositories/BookingReferenceRepository.ts
packages/features/bookings/repositories/BookingRepository.ts
packages/features/bookings/repositories/PrismaBookingAttendeeRepository.ts
packages/features/profile/repositories/ProfileRepository.ts
Repositories refactored to implement their interfaces, accept PrismaClient via constructor, and expose new methods: BookingRepository adds updateMany, update, updateIncludeWorkflowRemindersAndReferences, findManyIncludeWorkflowRemindersAndReferences; BookingReferenceRepository adds updateManyByBookingId; ProfileRepository adds findFirstByUserId; new PrismaBookingAttendeeRepository adds deleteManyByBookingId.
Core Logic & Handler
packages/features/bookings/lib/handleCancelBooking.ts
Handler signature expanded to accept optional injected Dependencies object containing five repositories; all direct Prisma calls replaced with repository method calls; workflowReminders data structure changed from WorkflowReminder[] to typed array with id, referenceId, method fields.
Handler Test Suite
packages/features/bookings/lib/handleCancelBooking/test/handleCancelBooking.test.ts
Extensive new test cases added covering seated events, recurring bookings, and reference cleanup scenarios (461+ lines).
User Repository & Public Exports
packages/features/users/repositories/UserRepository.ts
packages/platform/libraries/repositories.ts
UserRepository removes locale field from selection; three repositories exported from platform libraries as PrismaBookingReferenceRepository, PrismaBookingAttendeeRepository, PrismaProfileRepository.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Repositories bloom where Prisma once stood alone,
Five new dancers join the dependency injection throne,
Bookings now cancel through patterns so clean,
With modules and tokens—the best DI scene!
Hop along, dear code, toward reusable grace! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly summarizes the main change: refactoring the booking cancellation flow to use dependency-injected repositories instead of direct Prisma calls, which is the primary focus of all file modifications in this changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/features/bookings/lib/handleCancelBooking.ts (1)

500-520: Align the post‑update fetch range with the cancellation range.
updateMany uses gte (now vs booking start), but the follow‑up fetch always uses bookingToDelete.startTime. When allRemainingBookings is true and the cancelled occurrence isn’t the earliest upcoming one, some cancelled bookings won’t be included in updatedBookings, so reminders/webhooks can be left behind.

💡 Suggested fix
-    const allUpdatedBookings = await bookingRepository.findManyIncludeWorkflowRemindersAndReferences({
-      where: {
-        recurringEventId: bookingToDelete.recurringEventId,
-        startTime: {
-          gte: bookingToDelete.startTime,
-        },
-      },
-    });
+    const allUpdatedBookings = await bookingRepository.findManyIncludeWorkflowRemindersAndReferences({
+      where: {
+        recurringEventId,
+        startTime: {
+          gte,
+        },
+      },
+    });
🤖 Fix all issues with AI agents
In `@packages/features/bookings/repositories/BookingRepository.ts`:
- Around line 1502-1507: The updateMany implementation in BookingRepository
currently awaits but does not return the Prisma result, violating
IBookingRepository.updateMany's Promise<{ count: number }> contract; modify
BookingRepository.updateMany so it returns the result of
this.prismaClient.booking.updateMany(...) (i.e., replace the lone await with a
return of prismaClient.booking.updateMany) so callers can receive the { count }
response consistent with the IBookingRepository interface.
🧹 Nitpick comments (2)
packages/lib/server/repository/dto/IBookingReferenceRepository.ts (1)

6-8: Remove the placeholder comment in the public interface.

The TODO-style comment can go stale; either replace it with concrete methods or remove it.

🧹 Proposed cleanup
 export interface IBookingReferenceRepository {
-  // ... Add existing methods as well here
   /**
    * Update all booking references associated with a booking
    * Used during booking cancellation cleanup to soft-delete references
    */
packages/features/bookings/lib/handleCancelBooking/test/handleCancelBooking.test.ts (1)

1057-1516: Add assertions for the behaviors named in these tests.
These new tests mostly assert success and IDs but don’t verify attendee deletion, recurring booking status updates, or reference cleanup. Consider asserting the underlying state (attendee count, booking statuses, references marked deleted) to make the tests meaningful.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8a6463 and e5d60b2.

📒 Files selected for processing (23)
  • apps/api/v2/src/lib/modules/booking-cancel.module.ts
  • apps/api/v2/src/lib/repositories/prisma-booking-attendee.repository.ts
  • apps/api/v2/src/lib/repositories/prisma-booking-reference.repository.ts
  • apps/api/v2/src/lib/repositories/prisma-profile.repository.ts
  • apps/api/v2/src/lib/services/booking-cancel.service.ts
  • packages/features/bookingReference/repositories/BookingReferenceRepository.ts
  • packages/features/bookings/di/BookingAttendeeRepository.module.ts
  • packages/features/bookings/di/BookingCancelService.module.ts
  • packages/features/bookings/di/BookingReferenceRepository.module.ts
  • packages/features/bookings/di/tokens.ts
  • packages/features/bookings/lib/dto/IBookingAttendeeRepository.ts
  • packages/features/bookings/lib/handleCancelBooking.ts
  • packages/features/bookings/lib/handleCancelBooking/test/handleCancelBooking.test.ts
  • packages/features/bookings/repositories/BookingRepository.ts
  • packages/features/bookings/repositories/PrismaBookingAttendeeRepository.ts
  • packages/features/di/tokens.ts
  • packages/features/profile/repositories/ProfileRepository.ts
  • packages/features/users/di/Profile.module.ts
  • packages/features/users/repositories/UserRepository.ts
  • packages/lib/server/repository/dto/IBookingReferenceRepository.ts
  • packages/lib/server/repository/dto/IBookingRepository.ts
  • packages/lib/server/repository/dto/IProfileRepository.ts
  • packages/platform/libraries/repositories.ts
💤 Files with no reviewable changes (1)
  • packages/features/users/repositories/UserRepository.ts
🧰 Additional context used
🧬 Code graph analysis (4)
packages/features/bookings/di/BookingAttendeeRepository.module.ts (5)
packages/features/di/tokens.ts (1)
  • DI_TOKENS (10-84)
packages/features/bookings/repositories/PrismaBookingAttendeeRepository.ts (1)
  • PrismaBookingAttendeeRepository (5-15)
packages/features/bookings/di/BookingCancelService.module.ts (1)
  • moduleLoader (28-31)
packages/features/bookings/di/BookingReferenceRepository.module.ts (1)
  • moduleLoader (19-22)
packages/features/users/di/Profile.module.ts (1)
  • moduleLoader (19-22)
apps/api/v2/src/lib/repositories/prisma-booking-reference.repository.ts (3)
apps/api/v2/src/lib/repositories/prisma-booking-attendee.repository.ts (1)
  • Injectable (6-11)
apps/api/v2/src/lib/repositories/prisma-profile.repository.ts (1)
  • Injectable (6-11)
apps/api/v2/src/lib/services/booking-cancel.service.ts (1)
  • Injectable (10-27)
packages/features/bookings/repositories/BookingRepository.ts (2)
packages/platform/libraries/repositories.ts (1)
  • BookingRepository (5-5)
packages/lib/server/repository/dto/IBookingRepository.ts (4)
  • IBookingRepository (46-55)
  • BookingWhereInput (4-11)
  • BookingUpdateData (21-26)
  • BookingWhereUniqueInput (13-19)
packages/features/bookings/lib/handleCancelBooking.ts (5)
packages/features/users/repositories/UserRepository.ts (1)
  • UserRepository (124-1372)
packages/features/bookings/repositories/BookingRepository.ts (1)
  • BookingRepository (347-2017)
packages/features/profile/repositories/ProfileRepository.ts (1)
  • ProfileRepository (100-1042)
packages/features/bookingReference/repositories/BookingReferenceRepository.ts (1)
  • BookingReferenceRepository (18-79)
packages/features/bookings/repositories/PrismaBookingAttendeeRepository.ts (1)
  • PrismaBookingAttendeeRepository (5-15)
🔇 Additional comments (34)
packages/features/bookings/lib/dto/IBookingAttendeeRepository.ts (1)

1-3: Clear repository contract.

Looks good as a minimal interface for the cancellation flow.

packages/features/di/tokens.ts (1)

65-66: Token additions look consistent.

No issues with the new DI tokens.

packages/lib/server/repository/dto/IProfileRepository.ts (1)

1-13: Interface definitions are clear.

No concerns with these additions.

packages/features/bookings/repositories/PrismaBookingAttendeeRepository.ts (1)

5-14: Implementation aligns with the interface.

Looks good.

apps/api/v2/src/lib/repositories/prisma-booking-reference.repository.ts (1)

6-10: DI wiring looks correct.

No issues spotted.

packages/features/bookingReference/repositories/BookingReferenceRepository.ts (2)

7-22: DI-ready repository wiring looks good.

Constructor injection + interface implementation are clear, and the expanded select matches the richer reference needs.


68-78: Update helper is straightforward.

packages/lib/server/repository/dto/IBookingRepository.ts (1)

1-55: Repository contract additions look coherent.

packages/features/profile/repositories/ProfileRepository.ts (4)

100-105: DI constructor + interface adoption look good.


216-223: Formatting-only change.


1019-1029: Formatting-only change.


1034-1041: Instance lookup method fits the DI use case.

apps/api/v2/src/lib/repositories/prisma-profile.repository.ts (1)

1-10: DI wrapper for the profile repository looks solid.

packages/features/users/di/Profile.module.ts (1)

1-22: ProfileRepository module binding is clean.

packages/features/bookings/repositories/BookingRepository.ts (5)

13-31: Select helpers align with the new repository contract.


347-349: Interface implementation is clear.


1509-1514: Update-by-unique wrapper looks good.


1520-1543: Enriched update + select shape is clear.


1549-1565: Bulk fetch with reminders/references looks good.

packages/features/bookings/lib/handleCancelBooking.ts (7)

21-51: Repository and enum imports look consistent.


89-153: Dependency injection fallback is clear.
Optional dependencies with a default repository construction keeps the handler usable in non-DI contexts.


299-393: Repository lookups integrated cleanly.
Organizer/profile fetches are now routed through repositories and the team payload stays consistent.


470-477: Workflow reminder typing is now explicit.
The narrowed shape aligns with the reminder cleanup usage.


542-558: Seat attendee cleanup and booking update look good.


639-639: Reference cleanup via repository is clear.


703-725: Service wiring to pass dependencies is solid.

packages/features/bookings/di/BookingAttendeeRepository.module.ts (1)

1-20: DI module wiring looks good.

packages/features/bookings/di/BookingReferenceRepository.module.ts (1)

1-22: DI module wiring looks good.

apps/api/v2/src/lib/modules/booking-cancel.module.ts (1)

1-19: Provider registration aligns with the repository-based service.

packages/platform/libraries/repositories.ts (1)

14-16: Repository re‑exports are consistent.

packages/features/bookings/di/BookingCancelService.module.ts (1)

1-33: LGTM! Clean repository DI wiring.

The module correctly replaces the single prismaClient dependency with granular repository module loaders. The dependency names in depsMap align with the constructor parameters expected by BookingCancelService, and the module loader pattern is consistent with the codebase conventions.

packages/features/bookings/di/tokens.ts (1)

10-13: LGTM! New DI tokens follow established naming conventions.

The new BOOKING_REFERENCE_REPOSITORY and BOOKING_ATTENDEE_REPOSITORY tokens (with their module counterparts) follow the existing pattern in this file. The distinction from the existing ATTENDEE_REPOSITORY token appears intentional for booking-specific attendee operations.

apps/api/v2/src/lib/repositories/prisma-booking-attendee.repository.ts (1)

1-11: LGTM! Clean repository wrapper implementation.

This thin wrapper correctly bridges NestJS dependency injection with the platform-libraries base repository. The pattern of injecting PrismaWriteService and passing dbWrite.prisma to the base class is consistent with other Prisma repositories in the codebase.

apps/api/v2/src/lib/services/booking-cancel.service.ts (1)

12-26: LGTM! Repository injection follows DI best practices.

The constructor now correctly injects five granular repositories instead of a single PrismaWriteService, improving testability and separation of concerns. All five repository classes (PrismaUserRepository, PrismaBookingRepository, PrismaProfileRepository, PrismaBookingReferenceRepository, PrismaBookingAttendeeRepository) are properly registered as providers in BookingCancelModule, and the repository instances are correctly forwarded to the base class.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +1502 to +1507
async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) {
await this.prismaClient.booking.updateMany({
where: where,
data,
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd -t f "IBookingRepository" packages/features/bookings

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 68


🏁 Script executed:

rg "interface IBookingRepository" -A 30 packages/features/bookings/

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 68


🏁 Script executed:

rg "IBookingRepository\|export interface.*BookingRepository" packages/features/bookings/ -A 20

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 68


🏁 Script executed:

cat -n packages/features/bookings/repositories/BookingRepository.ts | sed -n '1490,1520p'

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 1116


🏁 Script executed:

rg "updateMany" packages/features/bookings/repositories/ -B 2 -A 2

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 628


🏁 Script executed:

rg "class BookingRepository" packages/features/bookings/repositories/ -A 5

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 698


🏁 Script executed:

rg "interface IBookingRepository|type IBookingRepository" packages/features/bookings/ -A 50

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 68


🏁 Script executed:

head -50 packages/features/bookings/repositories/BookingRepository.ts

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 1452


🏁 Script executed:

fd "IBookingRepository" -type f

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 256


🏁 Script executed:

fd "IBookingRepository" -t f

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 142


🏁 Script executed:

cat -n packages/lib/server/repository/dto/IBookingRepository.ts

Repository: qodo-benchmark/cal.com-combined-coderabbit

Length of output: 1761


Return the updateMany result to honor the interface contract.

The IBookingRepository interface (line 48 of packages/lib/server/repository/dto/IBookingRepository.ts) specifies that updateMany must return Promise<{ count: number }>, but the current implementation discards the Prisma result. Change await to return to match the interface contract and allow callers to access the count.

🛠️ Suggested fix
-  async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) {
-    await this.prismaClient.booking.updateMany({
-      where: where,
-      data,
-    });
-  }
+  async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) {
+    return this.prismaClient.booking.updateMany({
+      where,
+      data,
+    });
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) {
await this.prismaClient.booking.updateMany({
where: where,
data,
});
}
async updateMany({ where, data }: { where: BookingWhereInput; data: BookingUpdateData }) {
return this.prismaClient.booking.updateMany({
where,
data,
});
}
🤖 Prompt for AI Agents
In `@packages/features/bookings/repositories/BookingRepository.ts` around lines
1502 - 1507, The updateMany implementation in BookingRepository currently awaits
but does not return the Prisma result, violating IBookingRepository.updateMany's
Promise<{ count: number }> contract; modify BookingRepository.updateMany so it
returns the result of this.prismaClient.booking.updateMany(...) (i.e., replace
the lone await with a return of prismaClient.booking.updateMany) so callers can
receive the { count } response consistent with the IBookingRepository interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant