Skip to content

feat: add 10 minute cooldown in instant meetings#24119

Merged
alishaz-polymath merged 5 commits intomainfrom
feat/instant-meeting-rate-limit
Sep 29, 2025
Merged

feat: add 10 minute cooldown in instant meetings#24119
alishaz-polymath merged 5 commits intomainfrom
feat/instant-meeting-rate-limit

Conversation

@Udit-takkar
Copy link
Contributor

@Udit-takkar Udit-takkar commented Sep 26, 2025

What does this PR do?

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)
Screen.Recording.2025-09-27.at.12.25.32.AM.mov

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • N/A 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.
  • N/A 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 org team event type
  2. Enable instant meetings
  3. Go to booking page and click on connect now
  4. Then go to the booking page again. "Connect Now" button should be disabled

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 26, 2025

Walkthrough

  • apps/web/pages/api/book/instant-event.ts: Switched checkRateLimitAndThrowError to use rateLimitingType "instantMeeting".
  • apps/web/public/static/locales/en/common.json: Added connect_now_unavailable_tooltip localization key.
  • packages/features/bookings/Booker/Booker.tsx: Removed setSelectedDate usage; read instantConnectCooldownMs from useBookings and pass it as cooldownMs to InstantBooking; simplified onSubmit handler.
  • packages/features/bookings/Booker/components/InstantBooking.tsx: Added optional cooldownMs?: number prop (default 0); disables Connect now when cooldownMs > 0 and wraps the button in a Tooltip showing connect_now_unavailable_tooltip.
  • packages/features/bookings/Booker/components/hooks/useBookings.ts: Implemented client-side instant-booking cooldown storage and logic (10-minute window), blocks instant booking during cooldown, and exposes instantConnectCooldownMs in the hook return.
  • packages/lib/rateLimit.ts: Added instantMeeting limiter configuration and extended RateLimitHelper rateLimitingType union to include "instantMeeting".

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately describes the primary change—adding a 10-minute cooldown for instant meetings—and follows conventional commit style without unnecessary detail.
Description Check ✅ Passed The description clearly relates to the changeset by summarizing the feature’s purpose, referencing relevant issue placeholders, and providing concrete testing steps for the new cooldown functionality.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/instant-meeting-rate-limit

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • 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 3b13975 and b420d9a.

📒 Files selected for processing (1)
  • packages/lib/rateLimit.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.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/lib/rateLimit.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/lib/rateLimit.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/lib/rateLimit.ts
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Tests / Unit
  • GitHub Check: Linters / lint
  • GitHub Check: Type check / check-types
🔇 Additional comments (2)
packages/lib/rateLimit.ts (2)

11-19: Type union updated correctly

Including "instantMeeting" in RateLimitHelper keeps the type-safe mapping in sync with the new limiter.


62-69: Limiter matches the 10 minute cooldown spec

Thanks for bumping the backend limiter to duration: "10m"—this aligns with the product requirement and prevents instant-meeting calls from bypassing the UI cooldown.


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

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

@graphite-app graphite-app bot requested a review from a team September 26, 2025 18:58
@keithwillcode keithwillcode added core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO labels Sep 26, 2025
@vercel
Copy link

vercel bot commented Sep 26, 2025

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

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal Ignored Ignored Sep 29, 2025 9:35am
cal-eu Ignored Ignored Sep 29, 2025 9:35am

@dosubot dosubot bot added bookings area: bookings, availability, timezones, double booking ✨ feature New feature or request labels Sep 26, 2025
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: 2

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/Booker/components/hooks/useBookings.ts (1)

218-226: Cooldown never expires without a timer

instantConnectCooldownMs is computed once per render. After we set the cooldown, nothing triggers further renders, so the button stays disabled indefinitely—even after the 10 min window. Add state + an interval (or requestAnimationFrame) to tick the remaining time down and re-enable the UI when it reaches zero.

Apply something like:

-  const instantConnectCooldownMs = getInstantCooldownRemainingMs(eventTypeId);
+  const [instantConnectCooldownMs, setInstantConnectCooldownMs] = useState(() =>
+    getInstantCooldownRemainingMs(eventTypeId)
+  );
+
+  useEffect(() => {
+    setInstantConnectCooldownMs(getInstantCooldownRemainingMs(eventTypeId));
+
+    if (!eventTypeId) return;
+    const intervalId = window.setInterval(() => {
+      const remaining = getInstantCooldownRemainingMs(eventTypeId);
+      setInstantConnectCooldownMs(remaining);
+      if (remaining <= 0) {
+        window.clearInterval(intervalId);
+      }
+    }, 1000);
+
+    return () => window.clearInterval(intervalId);
+  }, [eventTypeId]);
🧹 Nitpick comments (1)
packages/features/bookings/Booker/components/InstantBooking.tsx (1)

40-65: Defensive onClick guard when disabled.

Thanks for adding the cooldown tooltip. One micro-improvement I’d make is to skip wiring onConnectNow when the button is disabled. Our <Button> wrapper already no-ops the handler, but avoiding the assignment keeps intent clearer and prevents surprises if the button implementation ever changes.

-        {disabled ? (
-          <Tooltip content={t("connect_now_unavailable_tooltip") || "Connect now is not available right now."}>
-            <span className="inline-flex">
-              <Button
-                disabled={disabled}
-                color="primary"
-                onClick={() => {
-                  onConnectNow();
-                }}
+        {disabled ? (
+          <Tooltip content={t("connect_now_unavailable_tooltip") || "Connect now is not available right now."}>
+            <span className="inline-flex">
+              <Button
+                disabled
+                color="primary"
                 size="sm"
                 className="w-full justify-center rounded-lg sm:w-auto">
                 {t("connect_now")}
               </Button>
             </span>
           </Tooltip>
         ) : (
           <Button
             color="primary"
             onClick={() => {
               onConnectNow();
             }}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • 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 6c9ac76 and 3b13975.

📒 Files selected for processing (6)
  • apps/web/pages/api/book/instant-event.ts (1 hunks)
  • apps/web/public/static/locales/en/common.json (1 hunks)
  • packages/features/bookings/Booker/Booker.tsx (3 hunks)
  • packages/features/bookings/Booker/components/InstantBooking.tsx (2 hunks)
  • packages/features/bookings/Booker/components/hooks/useBookings.ts (6 hunks)
  • packages/lib/rateLimit.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.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:

  • apps/web/pages/api/book/instant-event.ts
  • packages/lib/rateLimit.ts
  • packages/features/bookings/Booker/components/hooks/useBookings.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:

  • apps/web/pages/api/book/instant-event.ts
  • packages/features/bookings/Booker/components/InstantBooking.tsx
  • packages/lib/rateLimit.ts
  • packages/features/bookings/Booker/Booker.tsx
  • packages/features/bookings/Booker/components/hooks/useBookings.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • apps/web/pages/api/book/instant-event.ts
  • packages/features/bookings/Booker/components/InstantBooking.tsx
  • packages/lib/rateLimit.ts
  • packages/features/bookings/Booker/Booker.tsx
  • packages/features/bookings/Booker/components/hooks/useBookings.ts
**/*.tsx

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

Always use t() for text localization in frontend code; direct text embedding should trigger a warning

Files:

  • packages/features/bookings/Booker/components/InstantBooking.tsx
  • packages/features/bookings/Booker/Booker.tsx
🧠 Learnings (2)
📚 Learning: 2025-07-15T12:59:34.389Z
Learnt from: eunjae-lee
PR: calcom/cal.com#22106
File: packages/features/insights/components/FailedBookingsByField.tsx:65-71
Timestamp: 2025-07-15T12:59:34.389Z
Learning: In the FailedBookingsByField component (packages/features/insights/components/FailedBookingsByField.tsx), although routingFormId is typed as optional in useInsightsParameters, the system automatically enforces a routing form filter, so routingFormId is always present in practice. This means the data always contains only one entry, making the single-entry destructuring approach safe.

Applied to files:

  • packages/features/bookings/Booker/Booker.tsx
  • packages/features/bookings/Booker/components/hooks/useBookings.ts
📚 Learning: 2025-08-28T10:48:03.862Z
Learnt from: anglerfishlyy
PR: calcom/cal.com#0
File: :0-0
Timestamp: 2025-08-28T10:48:03.862Z
Learning: In Cal.com booking pipeline, loadUsersByEventType must return a plain array of user objects, not host-wrapped objects; returning { user, ... } causes downstream watchlist/validation to throw (e.g., reading 'split').

Applied to files:

  • packages/features/bookings/Booker/components/hooks/useBookings.ts
🧬 Code graph analysis (2)
packages/features/bookings/Booker/components/InstantBooking.tsx (2)
packages/features/bookings/types.ts (1)
  • BookerEvent (34-69)
packages/ui/components/button/Button.tsx (1)
  • Button (221-349)
packages/features/bookings/Booker/components/hooks/useBookings.ts (1)
packages/lib/webstorage.ts (1)
  • localStorage (6-36)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Tests / Unit
  • GitHub Check: Type check / check-types
  • GitHub Check: Linters / lint
🔇 Additional comments (2)
apps/web/public/static/locales/en/common.json (1)

2304-2304: Localized tooltip copy looks good.

Text is localized via connect_now_unavailable_tooltip, so the new tooltip message can be translated downstream. No issues here.

packages/features/bookings/Booker/Booker.tsx (1)

540-555: LGTM – cooldown is plumbed through.

instantConnectCooldownMs now flows into InstantBooking, so the “Connect now” button respects the client-side cooldown. Looks solid to me.

Copy link
Member

@sean-brydon sean-brydon left a comment

Choose a reason for hiding this comment

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

LGTM from a ratelimit implementation side. Havent tested

hashedLink,
bookingForm,
metadata,
teamMemberEmail,
Copy link
Member

Choose a reason for hiding this comment

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

Why did we remove it, was it unused?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes

"locked_by_team_admin": "Locked by team admin",
"app_not_connected": "You have not connected a {{appName}} account.",
"connect_now": "Connect now",
"connect_now_unavailable_tooltip": "Connect now is unavailable right now. Please book from above slots or try again later.",
Copy link
Member

Choose a reason for hiding this comment

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

NIT:
"Connect now is unavailable right now" sounds off. perhaps "Connect now is currently unavailable"?

@github-actions
Copy link
Contributor

E2E results are ready!

@alishaz-polymath alishaz-polymath merged commit 022f08c into main Sep 29, 2025
44 checks passed
@alishaz-polymath alishaz-polymath deleted the feat/instant-meeting-rate-limit branch September 29, 2025 12:03
@Udit-takkar Udit-takkar mentioned this pull request Sep 29, 2025
3 tasks
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 core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO ✨ feature New feature or request ready-for-e2e size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants