-
Notifications
You must be signed in to change notification settings - Fork 11.1k
feat: remove seats from booking #25233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: remove seats from booking #25233
Conversation
|
@dhairyashiil is attempting to deploy a commit to the cal Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
6 issues found across 19 files
Prompt for AI agents (all 6 issues)
Understand the root cause of the following 6 issues and fix them.
<file name="packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts">
<violation number="1" location="packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts:54">
Rule violated: **Enforce Singular Naming for Single-Item Functions**
`getAttendeeNames()` returns a single string but its plural name implies a collection, violating the singular-naming rule for single-value functions and making callers expect a list instead of the formatted string. Rename the method (and its call sites) to a singular name that reflects the single string return value.</violation>
<violation number="2" location="packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts:77">
Fallback attendee name is hardcoded as "Guest" instead of using the translation function, so the email ignores localization when no attendee name is available.</violation>
</file>
<file name="packages/emails/src/templates/OrganizerAttendeeCancelledSeatEmail.tsx">
<violation number="1" location="packages/emails/src/templates/OrganizerAttendeeCancelledSeatEmail.tsx:12">
Derive the translation function the same way as OrganizerScheduledEmail so subtitle text respects a provided team member’s locale.</violation>
<violation number="2" location="packages/emails/src/templates/OrganizerAttendeeCancelledSeatEmail.tsx:20">
Use the translation function for the “Guest” fallback so the attendee name placeholder remains localized.</violation>
</file>
<file name="apps/web/components/booking/actions/BookingActionsDropdown.tsx">
<violation number="1" location="apps/web/components/booking/actions/BookingActionsDropdown.tsx:246">
The new remove-seats action is never considered in `hasAnyAvailableActions()`, so if it is the only available action the dropdown is suppressed and the feature cannot be triggered. Update the availability check to include `removeSeatsAction`.
(Based on your team's feedback about ensuring all async operations have proper error handling.) [FEEDBACK_USED]</violation>
</file>
<file name="packages/emails/src/templates/AttendeeCancelledSeatEmail.tsx">
<violation number="1" location="packages/emails/src/templates/AttendeeCancelledSeatEmail.tsx:17">
Placing `{...props}` before the explicit `title/subject/subtitle/callToAction` forces the component to ignore any caller-supplied values for those props, even though the type still allows them. Move the spread back to the end so callers can override defaults as before.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts
Outdated
Show resolved
Hide resolved
packages/emails/src/templates/OrganizerAttendeeCancelledSeatEmail.tsx
Outdated
Show resolved
Hide resolved
packages/emails/src/templates/OrganizerAttendeeCancelledSeatEmail.tsx
Outdated
Show resolved
Hide resolved
packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts
Outdated
Show resolved
Hide resolved
|
Deployment failed with the following error: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 issues found across 19 files
Prompt for AI agents (all 4 issues)
Understand the root cause of the following 4 issues and fix them.
<file name="packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts">
<violation number="1" location="packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts:68">
`getTextBody` always uses the plural action keys (“were_removed”/“have_cancelled”), so the plain-text organizer email reads “Alice were removed/ have cancelled” when only one seat is removed. Mirror the HTML template and pick singular vs. plural keys based on attendeeCount for correct localization.</violation>
</file>
<file name="packages/features/bookings/lib/handleCancelBooking.ts">
<violation number="1" location="packages/features/bookings/lib/handleCancelBooking.ts:86">
Defaulting `seatReferenceUids` to an empty array and always invoking `cancelAttendeeSeat` makes every non-seat cancellation throw “At least one seat must be selected,” effectively blocking normal booking cancellations.</violation>
</file>
<file name="apps/web/components/booking/RemoveBookingSeatsDialog.tsx">
<violation number="1" location="apps/web/components/booking/RemoveBookingSeatsDialog.tsx:48">
Admins or owners who are also seated are misclassified as “just attendees”, so the dialog only ever exposes their own seat even though elevated roles should be able to remove any seat. Add an explicit permission check (role/team ownership) before entering the attendee-only branch so privileged users keep access to all seats.</violation>
<violation number="2" location="apps/web/components/booking/RemoveBookingSeatsDialog.tsx:89">
The fallback seat label is hard-coded as "Seat …" instead of being localized via t(), so it won’t translate. Wrap the fallback in t() with a dedicated key and pass the truncated reference as interpolation.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts
Outdated
Show resolved
Hide resolved
| skipCancellationReasonValidation = false, | ||
| } = bookingCancelInput.parse(body); | ||
|
|
||
| const seatReferenceUids = seatReferenceUid ? [seatReferenceUid] : rawSeatReferenceUids || []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defaulting seatReferenceUids to an empty array and always invoking cancelAttendeeSeat makes every non-seat cancellation throw “At least one seat must be selected,” effectively blocking normal booking cancellations.
Prompt for AI agents
Address the following comment on packages/features/bookings/lib/handleCancelBooking.ts at line 86:
<comment>Defaulting `seatReferenceUids` to an empty array and always invoking `cancelAttendeeSeat` makes every non-seat cancellation throw “At least one seat must be selected,” effectively blocking normal booking cancellations.</comment>
<file context>
@@ -76,11 +76,15 @@ async function handler(input: CancelBookingInput) {
skipCancellationReasonValidation = false,
} = bookingCancelInput.parse(body);
+
+ const seatReferenceUids = seatReferenceUid ? [seatReferenceUid] : rawSeatReferenceUids || [];
+
const bookingToDelete = await getBookingToDelete(id, uid);
</file context>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dhairyashiil unit tests are failing. Can you check please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 issues found across 19 files
Prompt for AI agents (all 4 issues)
Understand the root cause of the following 4 issues and fix them.
<file name="apps/web/components/booking/actions/BookingActionsDropdown.tsx">
<violation number="1" location="apps/web/components/booking/actions/BookingActionsDropdown.tsx:423">
`RemoveBookingSeatsDialog` already invalidates bookings and shows the success toast before invoking `onSuccess`, so this callback now fires the same toast/refetch twice, creating duplicate messaging and redundant work for every removal.</violation>
</file>
<file name="apps/web/components/booking/RemoveBookingSeatsDialog.tsx">
<violation number="1" location="apps/web/components/booking/RemoveBookingSeatsDialog.tsx:89">
Fallback seat labels are hard-coded in English ("Seat …") instead of going through t(), which breaks localization policy. Please wrap the fallback label in a translation key (e.g., t("seat_reference_fallback", { referenceUid: … })).</violation>
</file>
<file name="packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts">
<violation number="1" location="packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts:70">
The text body uses the translation key "attendees_cancelled_seats_text", but that key does not exist in any locale file, so the organizer will see the raw key string instead of a localized sentence.</violation>
</file>
<file name="packages/features/bookings/lib/handleCancelBooking.ts">
<violation number="1" location="packages/features/bookings/lib/handleCancelBooking.ts:86">
Omitting seatReferenceUids now lets any attendee cancel the entire booking: cancelAttendeeSeat returns early on an empty array, and without a host/admin guard the handler falls through to full booking cancellation. Reintroduce an authorization check that rejects non‑hosts whenever no seat references are provided.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
packages/emails/templates/organizer-multiple-attendees-cancelled-seat-email.ts
Outdated
Show resolved
Hide resolved
|
This PR has been marked as stale due to inactivity. If you're still working on it or need any help, please let us know or update the PR to keep it active. |
What does this PR do?
Host/Admin/Owner: (remove single attendee)
Screen.Recording.2025-11-18.at.7.02.58.AM.mov
Attendee:
Screen.Recording.2025-11-18.at.7.04.22.AM.mov
Host/Admin/Owner: (remove multiple attendee)
Screen.Recording.2025-11-18.at.7.15.35.AM.mov
Host/Admin/Owner: (remove all)
Screen.Recording.2025-11-18.at.7.18.06.AM.mov
Summary by cubic
Add seat removal to seated bookings with a simple UI and backend support for removing one or more attendees, with clear, localized emails. Addresses CAL-5058 by enabling organizers/admins/owners to remove seats while attendees can only remove their own.
New Features
Bug Fixes
Written for commit cec162e. Summary will update automatically on new commits.