Skip to content

feat: enable requires-confirmation with seats; per-seat confirmation for BookingSeat#27914

Draft
PeerRich wants to merge 4 commits intomainfrom
devin/1770931405-seats-requires-confirmation
Draft

feat: enable requires-confirmation with seats; per-seat confirmation for BookingSeat#27914
PeerRich wants to merge 4 commits intomainfrom
devin/1770931405-seats-requires-confirmation

Conversation

@PeerRich
Copy link
Member

@PeerRich PeerRich commented Feb 12, 2026

What does this PR do?

Enables the "Requires confirmation" feature to work with seated events. Previously, these two features were mutually exclusive. Now hosts can require confirmation for seated events and confirm/reject individual seat requests from the bookings page.

Key changes:

  • Added status field to BookingSeat model to track per-seat confirmation status
  • Removed API validation rules that blocked seats + requiresConfirmation combination
  • Removed UI restrictions in web app and companion app
  • Parent booking stays ACCEPTED for seated events; individual seats track their own PENDING/ACCEPTED/REJECTED status
  • Extended confirm handler to support per-seat confirmation via seatReferenceUid parameter
  • Added per-seat confirm/reject UI (PendingSeatsSection) on the bookings page showing each pending attendee with Accept/Reject buttons
  • Updated bookings query to include seat status and attendee name
  • Updated "Unconfirmed" tab filter to surface bookings with pending seats

Link to Devin run: https://app.devin.ai/sessions/39ca226d3ca84a278ea4ac469c74d753
Requested by: @PeerRich

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A - no docs changes needed
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  1. Create an event type with seats enabled (e.g., 4 seats per time slot)
  2. Enable "Requires confirmation" on the same event type — this should now be allowed
  3. Have multiple attendees book seats on the same time slot
  4. Go to /bookings → "Unconfirmed" tab — the booking should appear with a "Pending seats" section listing each attendee with their name/email
  5. Click Accept/Reject on individual seats and verify the seat status updates
  6. Verify that confirming/rejecting one seat does not affect other seats on the same booking

⚠️ Important items for human review

  1. Per-seat confirmation returns early without sending emails or calendar events — The new seat confirmation path in confirm.handler.ts (line ~260) returns { message, status } early without sending confirmation emails or creating calendar events. The onSuccess handler in useBookingConfirmation checks data?.status === BookingStatus.REJECTED which may not match since the confirm handler returns the raw enum string. Verify this interaction works correctly.

  2. Parent booking always ACCEPTED for seated events — In createBooking.ts, seated events now always get BookingStatus.ACCEPTED regardless of requiresConfirmation. Verify no downstream logic relies on checking booking.status to determine if confirmation is needed for the overall booking.

  3. Seat status case mismatch — The Kysely query returns lowercase DB enum values ("pending") while BookingStatus.PENDING is uppercase. The BookingListItem uses .toLowerCase() === "pending" as a workaround. The get.handler.ts unconfirmed filter uses the lowercase "pending" string directly. This inconsistency should be verified.

  4. No unit tests for PendingSeatsSection component — The new UI component for per-seat confirmation lacks dedicated test coverage.

Checklist

  • I have read the contributing guide
  • My code follows the style guidelines of this project
  • I have checked if my changes generate no new warnings

… and per-seat confirmation; update UI and tests

Co-Authored-By: peer@cal.com <peer@cal.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@github-actions github-actions bot added the ❗️ migrations contains migration files label Feb 12, 2026
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.

1 issue found across 14 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/trpc/server/routers/viewer/bookings/confirm.handler.ts">

<violation number="1" location="packages/trpc/server/routers/viewer/bookings/confirm.handler.ts:273">
P2: Per-seat confirmation returns before the existing confirmation/rejection workflows, so seat confirmations/rejections skip emails, calendar events, and webhook workflows. If seat-level confirmation is meant to mirror booking confirmation, this early return should trigger the same notification flows (or explicitly document that seats are silent).</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

});

const message = confirmed ? "Seat confirmed" : "Seat rejected";
return { message, status: newStatus };
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Feb 12, 2026

Choose a reason for hiding this comment

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

P2: Per-seat confirmation returns before the existing confirmation/rejection workflows, so seat confirmations/rejections skip emails, calendar events, and webhook workflows. If seat-level confirmation is meant to mirror booking confirmation, this early return should trigger the same notification flows (or explicitly document that seats are silent).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/trpc/server/routers/viewer/bookings/confirm.handler.ts, line 273:

<comment>Per-seat confirmation returns before the existing confirmation/rejection workflows, so seat confirmations/rejections skip emails, calendar events, and webhook workflows. If seat-level confirmation is meant to mirror booking confirmation, this early return should trigger the same notification flows (or explicitly document that seats are silent).</comment>

<file context>
@@ -238,12 +239,40 @@ export const confirmHandler = async ({ ctx, input }: ConfirmOptions) => {
+    });
+
+    const message = confirmed ? "Seat confirmed" : "Seat rejected";
+    return { message, status: newStatus };
+  }
+
</file context>
Fix with Cubic

devin-ai-integration bot and others added 3 commits February 12, 2026 22:35
Co-Authored-By: peer@cal.com <peer@cal.com>
Co-Authored-By: peer@cal.com <peer@cal.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

❗️ migrations contains migration files size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant