Skip to content

Conversation

@Vansh5632
Copy link
Contributor

What does this PR do?

  • Fix issue where slots with remaining seats were blocked once booking limit was hit
  • Add seat-aware logic to booking limits checking in _getBusyTimesFromBookingLimits
  • Only mark slots as busy when both booking limit is reached AND no seats remain
  • Update getBusyTimesFromTeamLimits to pass eventType parameter for seat checking
  • Maintain backward compatibility for non-seated events
  • Apply the same logic to user-specific booking limits in slots utility

Resolves CAL-4553: Booking limits with seats not working

Video Demo (if applicable):

Screencast.from.2025-08-23.13-11-44.mp4

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. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

- Fix issue where slots with remaining seats were blocked once booking limit was hit
- Add seat-aware logic to booking limits checking in _getBusyTimesFromBookingLimits
- Only mark slots as busy when both booking limit is reached AND no seats remain
- Update getBusyTimesFromTeamLimits to pass eventType parameter for seat checking
- Maintain backward compatibility for non-seated events
- Apply the same logic to user-specific booking limits in slots utility

Resolves CAL-4553: Booking limits with seats not working
@Vansh5632 Vansh5632 requested a review from a team as a code owner August 23, 2025 07:52
@vercel
Copy link

vercel bot commented Aug 23, 2025

@Vansh5632 is attempting to deploy a commit to the cal Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions bot added Medium priority Created by Linear-GitHub Sync seats area: seats, guest meetings, multiple people 🐛 bug Something isn't working 📉 regressing This used to work. Now it doesn't anymore. labels Aug 23, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 23, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes thread an eventType parameter through availability and interval-limit functions, enabling seat-aware booking-limit checks. Logic now distinguishes seated events: when a booking limit period is reached, the code computes remaining seats per time slot and marks busy only if no seats remain. Non-seated behavior stays unchanged. Adjustments occur in getUserAvailability, getBusyTimesFromLimits (and related helpers), and viewer slots utilities. Internal type aliases were renamed to private variants. Function signatures for busy-time retrieval were updated to accept and propagate eventType.

Assessment against linked issues

Objective Addressed Explanation
Booking limits should not block remaining seats for seated events; enforce per-slot seat availability when limits are hit ([#17221], [CAL-4553])
Enable Self-Hosted self serve ([CAL-4453]) No code related to self-serve enablement or pricing logic present.

Possibly related PRs

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@graphite-app graphite-app bot added the community Created by Linear-GitHub Sync label Aug 23, 2025
@graphite-app graphite-app bot requested a review from a team August 23, 2025 07:52
@dosubot dosubot bot added the bookings area: bookings, availability, timezones, double booking label Aug 23, 2025
@dosubot dosubot bot added this to the v5.7 milestone Aug 23, 2025
@graphite-app
Copy link

graphite-app bot commented Aug 23, 2025

Graphite Automations

"Add consumer team as reviewer" took an action on this PR • (08/23/25)

1 reviewer was added to this PR based on Keith Williams's automation.

"Add community label" took an action on this PR • (08/23/25)

1 label was added to this PR based on Keith Williams's automation.

Copy link
Contributor

@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 (3)
packages/trpc/server/routers/viewer/slots/util.ts (1)

1191-1313: Thread eventType into the team‐limits path to enable seat‐aware blocking

The team‐level booking‐limits handler (_getBusyTimesFromTeamLimitsForUsers in packages/trpc/server/routers/viewer/slots/util.ts) currently ignores eventType.seatsPerTimeSlot, causing over‐blocking when seats are limited. You need to:

• Extend the function signature to accept eventType: EventType.
• Preserve eventTypeId on each busy‐time entry.
• In both the global and per‐user loops, when eventType.seatsPerTimeSlot is defined, count only bookings matching that eventType.id before marking the slot busy.
• Wire the new eventType argument through the call site at line 1416 of the same file.

Suggested diff (in packages/trpc/server/routers/viewer/slots/util.ts):

--- a/packages/trpc/server/routers/viewer/slots/util.ts
+++ b/packages/trpc/server/routers/viewer/slots/util.ts
@@ 1191,7c1191,8
-const _getBusyTimesFromTeamLimitsForUsers = async (
+const _getBusyTimesFromTeamLimitsForUsers = async (
   users: { id: number; email: string }[],
   bookingLimits: IntervalLimit,
+  eventType: NonNullable<EventType>,
   dateFrom: Dayjs,
   dateTo: Dayjs,
   teamId: number,
@@ 1202,7c1203,8
-  rescheduleUid?: string
+  rescheduleUid?: string,
+  // New param for seat limits
 ) => {
@@ 1210,7c1212,8
-  const busyTimes = bookings.map(({ id, startTime, endTime, eventTypeId, title, userId }) => ({
+  const busyTimes = bookings.map(({ id, startTime, endTime, eventTypeId, title, userId }) => ({
     start: dayjs(startTime).toDate(),
     end: dayjs(endTime).toDate(),
     title,
@@ 1217,7c1221,8
     userId,
-  }));
+    // Preserve for seat filtering
+    eventTypeId,
+  }));
@@ 1240,7c1242,21
-          globalLimitManager.addBusyTime(periodStart, unit, timeZone);
+          if (eventType.seatsPerTimeSlot) {
+            const slotCount = busyTimes.filter(
+              (b) =>
+                b.eventTypeId === eventType.id &&
+                dayjs(b.start).isSame(dayjs(booking.start)) &&
+                isBookingWithinPeriod(b, periodStart, periodEnd, timeZone)
+            ).length;
+            if (slotCount >= eventType.seatsPerTimeSlot) {
+              globalLimitManager.addBusyTime(periodStart, unit, timeZone);
+            }
+          } else {
+            globalLimitManager.addBusyTime(periodStart, unit, timeZone);
+          }
           break;
@@ 1290,7c1304,21
-            limitManager.addBusyTime(periodStart, unit, timeZone);
+            if (eventType.seatsPerTimeSlot) {
+              const slotCount = userBusyTimes.filter(
+                (b) =>
+                  b.eventTypeId === eventType.id &&
+                  dayjs(b.start).isSame(dayjs(booking.start)) &&
+                  isBookingWithinPeriod(b, periodStart, periodEnd, timeZone)
+              ).length;
+              if (slotCount >= eventType.seatsPerTimeSlot) {
+                limitManager.addBusyTime(periodStart, unit, timeZone);
+              }
+            } else {
+              limitManager.addBusyTime(periodStart, unit, timeZone);
+            }
             break;

And update the call at ~line 1416:

--- a/packages/trpc/server/routers/viewer/slots/util.ts:1414
+++ b/packages/trpc/server/routers/viewer/slots/util.ts:1414
-    teamBookingLimitsMap = await getBusyTimesFromTeamLimitsForUsers(
+    teamBookingLimitsMap = await getBusyTimesFromTeamLimitsForUsers(
       usersForTeamLimits,
       teamBookingLimits,
       startTime,
       endTime,
       teamForBookingLimits.id,
       teamForBookingLimits.includeManagedEventsInLimits,
       usersWithCredentials[0]?.timeZone || "UTC",
-      input.rescheduleUid || undefined
+      input.rescheduleUid || undefined,
+      eventType
     );

These changes ensure that team‐level limits respect per‐event‐type seat counts.

packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts (2)

110-112: Timezone mismatch: period boundaries should use the provided timeZone

periodStartDates are currently computed without passing timeZone, while isBookingWithinPeriod() uses timeZone. This can shift week/day boundaries and produce off-by-one-period bugs.

Apply timeZone consistently here and in duration limits:

-const periodStartDates = getPeriodStartDatesBetween(dateFrom, dateTo, unit);
+const periodStartDates = getPeriodStartDatesBetween(dateFrom, dateTo, unit, timeZone || "UTC");

And in _getBusyTimesFromDurationLimits:

-const periodStartDates = getPeriodStartDatesBetween(dateFrom, dateTo, unit);
+const periodStartDates = getPeriodStartDatesBetween(dateFrom, dateTo, unit, timeZone);

274-281: Keep eventTypeId on mapped items so downstream seat checks can filter correctly

Currently the mapper drops eventTypeId; retain it to enable per-eventType seat checks inside getBusyTimesFromBookingLimits.

-const busyTimes = bookings.map(({ id, startTime, endTime, eventTypeId, title, userId }) => ({
+const busyTimes = bookings.map(({ id, startTime, endTime, eventTypeId, title, userId }) => ({
   start: dayjs(startTime).toDate(),
   end: dayjs(endTime).toDate(),
   title,
   source: `eventType-${eventTypeId}-booking-${id}`,
   userId,
+  eventTypeId,
 }));
🧹 Nitpick comments (2)
packages/trpc/server/routers/viewer/slots/util.ts (2)

1022-1042: Seat-aware block: logic directionally correct; tighten slot filtering and avoid quadratic scans

  • Correctly defers marking periods busy for seated events until seats are exhausted.
  • Two improvements:
    • Restrict comparisons to exact instants without constructing Dayjs repeatedly in the inner loop to avoid O(N^2) overhead from filtering the entire array per booking.
    • Use a precomputed map keyed by slotStartMillis to count bookings per period for better perf.

Apply this refactor inside the period loop to pre-aggregate by slot start:

- for (const booking of busyTimesFromLimitsBookings) {
+ // Pre-aggregate by slot start (ms) for this period only
+ const periodBookings = busyTimesFromLimitsBookings.filter((b) =>
+   isBookingWithinPeriod(b, periodStart, periodEnd, timeZone)
+ );
+ const bySlot = new Map<number, number>();
+ for (const b of periodBookings) {
+   const k = new Date(b.start).getTime();
+   bySlot.set(k, (bySlot.get(k) ?? 0) + 1);
+ }
+ for (const booking of periodBookings) {
    ...
-   const slotBookings = busyTimesFromLimitsBookings.filter(
-     (b) =>
-       dayjs(b.start).isSame(dayjs(booking.start)) &&
-       isBookingWithinPeriod(b, periodStart, periodEnd, timeZone)
-   );
-   const totalAttendees = slotBookings.length;
+   const totalAttendees = bySlot.get(new Date(booking.start).getTime()) ?? 0;
    ...
  }

1099-1119: Duplicate seat-aware logic: extract helper or share pre-aggregation to reduce complexity

You’ve replicated the same seat-aware pattern in the per-user pass. Consider factoring a small helper or reusing the pre-aggregated map suggested above to keep the two loops consistent and cheaper.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d2f8076 and c415fdb.

📒 Files selected for processing (3)
  • packages/lib/getUserAvailability.ts (2 hunks)
  • packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts (6 hunks)
  • packages/trpc/server/routers/viewer/slots/util.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/trpc/server/routers/viewer/slots/util.ts
  • packages/lib/getUserAvailability.ts
  • packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/trpc/server/routers/viewer/slots/util.ts
  • packages/lib/getUserAvailability.ts
  • packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.784Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.
📚 Learning: 2025-08-21T13:44:06.784Z
Learnt from: supalarry
PR: calcom/cal.com#23217
File: apps/api/v2/src/ee/event-types/event-types_2024_06_14/services/output-event-types.service.ts:93-94
Timestamp: 2025-08-21T13:44:06.784Z
Learning: In apps/api/v2/src/ee/event-types/event-types_2024_06_14/event-types.repository.ts, repository functions that use explicit Prisma select clauses (like getEventTypeWithSeats) are used for specific purposes and don't need to include all EventType fields like bookingRequiresAuthentication. These methods don't feed into the general OutputEventTypesService_2024_06_14 flow.

Applied to files:

  • packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts
🧬 Code graph analysis (2)
packages/trpc/server/routers/viewer/slots/util.ts (2)
packages/lib/getUserAvailability.ts (1)
  • GetAvailabilityUser (193-193)
packages/lib/intervalLimits/utils.ts (1)
  • isBookingWithinPeriod (42-56)
packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts (2)
packages/lib/getUserAvailability.ts (1)
  • EventType (147-147)
packages/lib/event-types/getEventTypeById.ts (1)
  • EventType (34-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Install dependencies / Yarn install & cache
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (6)
packages/trpc/server/routers/viewer/slots/util.ts (1)

63-65: Type alias rename is fine

The underscore prefix clarifies internal scope and avoids accidental exports. No issues.

packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts (2)

46-47: Good: propagate eventType into booking-limits evaluation

This enables seated-event awareness down the stack.


248-258: Good: team limits now accept eventType for seat awareness

Signature change is correct and non-breaking for callers you updated.

packages/lib/getUserAvailability.ts (3)

269-269: Internal result type rename looks good

Underscoring avoids accidental exports and clarifies intent.


391-393: Great: pass eventType to team-limit checks

This makes yearly/period checks seat-aware in the per-user path.

Note: If initialData.teamBookingLimits is provided (from slots/util.ts), it takes precedence and can still be seat-unaware. After updating slots/util.ts as suggested, this precedence remains correct.


351-368: Timezone argument consistently propagated

I’ve verified that every call to getPeriodStartDatesBetween in packages/trpc/server/routers/viewer/slots/util.ts includes the timeZone parameter, ensuring parity with the fallback logic’s use of dateFrom.tz(timeZone)/dateTo.tz(timeZone) and preventing any off-by-one period issues. No further changes needed here.

Comment on lines 148 to 173
// For seated events, only mark slot as busy if there are no remaining seats
if (eventType?.seatsPerTimeSlot) {
// Get bookings for each specific time slot to check remaining seats
const slotBookings = bookings.filter(
(b) =>
dayjs(b.start).isSame(dayjs(booking.start)) &&
isBookingWithinPeriod(b, periodStart, periodEnd, timeZone || "UTC")
);

// Count attendees across all bookings for this time slot
const totalAttendees = slotBookings.reduce((sum, _b) => {
// Each booking represents one booking, but we need to account for actual attendees
// For the purpose of booking limits, each accepted booking counts as 1 booking
// regardless of how many attendees it has
return sum + 1;
}, 0);

// Only mark as busy if no seats remain AND booking limit is reached
const remainingSeats = eventType.seatsPerTimeSlot - totalAttendees;
if (remainingSeats <= 0) {
limitManager.addBusyTime(periodStart, unit);
}
} else {
// For non-seated events, mark as busy when limit is reached
limitManager.addBusyTime(periodStart, unit);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Seat-aware filter should only count bookings from the current eventType when invoked via team limits

When this helper is called by getBusyTimesFromTeamLimits, the bookings array can include multiple event types. Seats must only be decremented by bookings for the same eventType.

  • Preserve eventTypeId in the “bookings” you pass from the team path.
  • Narrow slotBookings to the current eventType when eventTypeId is present.
  • Also simplify attendee counting.
-const slotBookings = bookings.filter(
-  (b) =>
-    dayjs(b.start).isSame(dayjs(booking.start)) &&
-    isBookingWithinPeriod(b, periodStart, periodEnd, timeZone || "UTC")
-);
-const totalAttendees = slotBookings.reduce((sum, _b) => { return sum + 1; }, 0);
+type EBWithEvent = EventBusyDetails & { eventTypeId?: number };
+const enriched = bookings as EBWithEvent[];
+let slotBookings = enriched.filter(
+  (b) =>
+    dayjs(b.start).isSame(dayjs(booking.start)) &&
+    isBookingWithinPeriod(b, periodStart, periodEnd, timeZone || "UTC")
+);
+if (slotBookings.length && typeof (slotBookings[0] as EBWithEvent).eventTypeId === "number") {
+  slotBookings = slotBookings.filter((b) => b.eventTypeId === eventType?.id);
+}
+const totalAttendees = slotBookings.length;
📝 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
// For seated events, only mark slot as busy if there are no remaining seats
if (eventType?.seatsPerTimeSlot) {
// Get bookings for each specific time slot to check remaining seats
const slotBookings = bookings.filter(
(b) =>
dayjs(b.start).isSame(dayjs(booking.start)) &&
isBookingWithinPeriod(b, periodStart, periodEnd, timeZone || "UTC")
);
// Count attendees across all bookings for this time slot
const totalAttendees = slotBookings.reduce((sum, _b) => {
// Each booking represents one booking, but we need to account for actual attendees
// For the purpose of booking limits, each accepted booking counts as 1 booking
// regardless of how many attendees it has
return sum + 1;
}, 0);
// Only mark as busy if no seats remain AND booking limit is reached
const remainingSeats = eventType.seatsPerTimeSlot - totalAttendees;
if (remainingSeats <= 0) {
limitManager.addBusyTime(periodStart, unit);
}
} else {
// For non-seated events, mark as busy when limit is reached
limitManager.addBusyTime(periodStart, unit);
}
// For seated events, only mark slot as busy if there are no remaining seats
if (eventType?.seatsPerTimeSlot) {
// Get bookings for each specific time slot to check remaining seats
type EBWithEvent = EventBusyDetails & { eventTypeId?: number };
const enriched = bookings as EBWithEvent[];
let slotBookings = enriched.filter(
(b) =>
dayjs(b.start).isSame(dayjs(booking.start)) &&
isBookingWithinPeriod(b, periodStart, periodEnd, timeZone || "UTC")
);
if (slotBookings.length && typeof (slotBookings[0] as EBWithEvent).eventTypeId === "number") {
slotBookings = slotBookings.filter((b) => b.eventTypeId === eventType?.id);
}
const totalAttendees = slotBookings.length;
// Only mark as busy if no seats remain AND booking limit is reached
const remainingSeats = eventType.seatsPerTimeSlot - totalAttendees;
if (remainingSeats <= 0) {
limitManager.addBusyTime(periodStart, unit);
}
} else {
// For non-seated events, mark as busy when limit is reached
limitManager.addBusyTime(periodStart, unit);
}
🤖 Prompt for AI Agents
In packages/lib/intervalLimits/server/getBusyTimesFromLimits.ts around lines 148
to 173, the seat-aware logic currently counts bookings across all event types
which is wrong when invoked from the team-limits path; ensure the bookings
passed in include eventTypeId and then filter slotBookings to only those with
the same eventTypeId (when eventTypeId is present) in addition to the existing
start/period/timeZone checks, and replace the manual attendee reduce with a
simple slotBookings.length (each booking counts as one) before computing
remainingSeats and calling limitManager.addBusyTime.

Copy link
Contributor

@kart1ka kart1ka left a comment

Choose a reason for hiding this comment

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

Could you please resolve merge conflicts and address coderabbit suggestions?

@kart1ka kart1ka marked this pull request as draft August 27, 2025 14:29
@Vansh5632
Copy link
Contributor Author

@kart1ka okay working on them

Vansh5632 and others added 2 commits August 28, 2025 16:06
- Add eventTypeId to EventBusyDetails type to support event type filtering
- Include eventTypeId in team booking limits busyTimes mapping
- Filter slot bookings by eventTypeId when present (team-limits path)
- Replace manual attendee reduce with simple slotBookings.length count
- Ensure booking limits correctly isolate by event type instead of counting across all types

Fixes CAL-4553
@Vansh5632
Copy link
Contributor Author

@kart1ka i am not understanding why the type-check errors are coming can you give me little bit explanation about it

@Vansh5632 Vansh5632 marked this pull request as ready for review September 3, 2025 11:05
@kart1ka kart1ka marked this pull request as draft September 4, 2025 04:09
@dosubot dosubot bot modified the milestones: v5.7, v5.8 Sep 16, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 1, 2025

This PR is being marked as stale due to inactivity.

@github-actions github-actions bot added the Stale label Oct 1, 2025
@CarinaWolli CarinaWolli modified the milestones: v5.8, v5.9 Oct 16, 2025
@dosubot dosubot bot removed this from the v5.9 milestone Oct 16, 2025
@dosubot dosubot bot added this to the v5.9 milestone Oct 16, 2025
@CarinaWolli CarinaWolli modified the milestones: v5.9, v6.0 Nov 17, 2025
@CarinaWolli CarinaWolli modified the milestones: v6.0, v6.1 Dec 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bookings area: bookings, availability, timezones, double booking 🐛 bug Something isn't working community Created by Linear-GitHub Sync Medium priority Created by Linear-GitHub Sync 📉 regressing This used to work. Now it doesn't anymore. seats area: seats, guest meetings, multiple people Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CAL-4553] Booking limits with seats not working

4 participants