Skip to content

refactor: reserved slot and booking intercation#24670

Draft
supalarry wants to merge 88 commits intomainfrom
respect-reserved-slot-when-booking
Draft

refactor: reserved slot and booking intercation#24670
supalarry wants to merge 88 commits intomainfrom
respect-reserved-slot-when-booking

Conversation

@supalarry
Copy link
Contributor

@supalarry supalarry commented Oct 24, 2025

See Linear ticket for walkthrough CAL-6430

Fixes #23938


Summary by cubic

Adds reserved-slot validation to booking to prevent double bookings. Passes reservedSlotUid end-to-end, checks the earliest active reservation, consumes it on booking, and centralizes cookie/body extraction.

  • New Features

    • Regular bookings and reschedules check the earliest active reservation and delete it after booking; return 409 with a wait-time message when another reservation is ahead, allow booking when others are expired or none exist. Skips for team and seated events; instant bookings are unaffected.
    • Propagated reservedSlotUid from client store and request body into booking meta across API/TRPC; OpenAPI updated.
    • Recurring bookings pass reservedSlotUid for the first non-team occurrence.
  • Refactors

    • Centralized helpers: RESERVED_SLOT_UID_COOKIE_NAME, getReservedSlotUidFromCookies, getReservedSlotUidFromRequest; replaced direct cookie reads and set cookie via the constant.
    • Replaced useSlotReservationId with a Booker store reservedSlotUid; minor typing and error-handling cleanups.

Written for commit e600891. Summary will update automatically on new commits.

@keithwillcode keithwillcode added core area: core, team members only platform Anything related to our platform plan labels Oct 24, 2025
@vercel
Copy link

vercel bot commented Oct 27, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
cal-companion Ready Ready Preview, Comment Dec 17, 2025 9:03am
2 Skipped Deployments
Project Deployment Review Updated (UTC)
cal Ignored Ignored Dec 17, 2025 9:03am
cal-eu Ignored Ignored Dec 17, 2025 9:03am

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

5 issues found across 29 files

Prompt for AI agents (all 5 issues)

Understand the root cause of the following 5 issues and fix them.


<file name="packages/features/bookings/lib/service/InstantBookingCreateService.ts">

<violation number="1" location="packages/features/bookings/lib/service/InstantBookingCreateService.ts:171">
Rule violated: **Avoid Logging Sensitive Information**

This debug log prints the entire bookingMeta object, which per CreateBookingMeta includes sensitive identifiers (e.g., userId, reservedSlotUid). Logging this data violates our “Avoid Logging Sensitive Information” policy. Please remove the console statement.</violation>
</file>

<file name="docs/api-reference/v2/openapi.json">

<violation number="1" location="docs/api-reference/v2/openapi.json:25457">
The reservedSlotUid description is truncated, ending without the object it refers to. Please complete the sentence so the API docs clearly describe how the value is used.</violation>
</file>

<file name="packages/features/bookings/lib/service/RecurringBookingService.ts">

<violation number="1" location="packages/features/bookings/lib/service/RecurringBookingService.ts:107">
Setting `reservedSlotUid` to `undefined` here drops the reserved slot on the first (non-round-robin) booking, so the reserved slot cookie is never honored for recurring bookings that aren’t round robin. Use the passed-in UID when `key === 0` so the initial booking respects the reservation.</violation>
</file>

<file name="apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts">

<violation number="1" location="apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts:128">
Adding reservedSlotUid to the body alone leaves bookingRequest.reservedSlotUid undefined, so bookings.service ignores the reservation. Please also assign reservedSlotUid on the request object before returning.</violation>
</file>

<file name="packages/features/bookings/lib/handleNewBooking/createBookingWithReservedSlot.ts">

<violation number="1" location="packages/features/bookings/lib/handleNewBooking/createBookingWithReservedSlot.ts:25">
`dayjs(...).utc().format()` drops fractional seconds, so the Date you build loses millisecond precision. When the selected slot was saved with non-zero milliseconds (ISO strings from `Date.toISOString()` include them), the equality filter in `deleteMany` won’t match and the reserved slot record survives, blocking new reservations. Please preserve the original precision (e.g. use `.valueOf()` / `.toDate()` instead of `.format()` on both start and end conversions).</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 30, 2025

E2E results are ready!

Comment on lines +2796 to +2823
const eventType = await getEventType({
eventTypeId: input.bookingData.eventTypeId,
eventTypeSlug: input.bookingData.eventTypeSlug,
});

// note(Lauris): I know this function is called createBooking but it is called by web booker when rescheduling
await validateRescheduleRestrictions({
rescheduleUid: input.bookingData.rescheduleUid,
userId: input.bookingMeta?.userId ?? null,
eventType: eventType
? {
seatsPerTimeSlot: eventType.seatsPerTimeSlot,
minimumRescheduleNotice: eventType.minimumRescheduleNotice ?? null,
}
: null,
});

const reservedSlot = this.getReservedSlotIfNotTeamOrSeatedEvent(input, eventType);
if (reservedSlot) {
await this.checkReservedSlotIsEarliest(reservedSlot);
}

const res = await handler({ bookingData: input.bookingData, ...input.bookingMeta }, this.deps, eventType);

if (reservedSlot) {
await this.deleteReservedSlot(reservedSlot);
}
return res;
Copy link
Contributor

@ThyMinimalDev ThyMinimalDev Dec 16, 2025

Choose a reason for hiding this comment

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

looks great, aligned with our refactor initiative to make code more semantic

@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2026

Devin AI is resolving merge conflicts

This PR has merge conflicts with the main branch. A Devin session has been created to automatically resolve them.

View Devin Session

Devin will:

  1. Merge the latest main into this branch
  2. Resolve any conflicts intelligently
  3. Run lint/type checks to ensure validity
  4. Push the resolved changes

If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself.

@eunjae-lee eunjae-lee marked this pull request as draft January 21, 2026 09:26
@eunjae-lee
Copy link
Contributor

converting this to a draft. let us know when this is ready for review again.

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

Labels

core area: core, team members only devin-conflict-resolution platform Anything related to our platform plan ready-for-e2e size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Booking flow allows double-booking reserved slots

6 participants