-
Notifications
You must be signed in to change notification settings - Fork 10.4k
feat: expired reservation webhook #21997
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: expired reservation webhook #21997
Conversation
- Add RESERVATION_EXPIRED enum - create one to many relationship between SelectedSlots and WebhookScheduledTriggers
…pired-reservation-webhook
@giripatel 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.
cubic found 1 issue across 48 files. Review it in cubic.dev
React with 👍 or 👎 to teach cubic. Tag @cubic-dev-ai
to give specific feedback.
packages/prisma/schema.prisma
Outdated
payload String | ||
startAfter DateTime | ||
retryCount Int @default(0) | ||
createdAt DateTime? @default(now()) |
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.
Rule violated: Prevent Direct NOW() Usage in Database Queries
Uses now() without explicit UTC conversion, violating rule against unspecific NOW() usage and risking non-UTC timestamps.
createdAt DateTime? @default(now()) | |
createdAt DateTime? @default(dbgenerated("(now() at time zone 'utc')")) |
Graphite Automations"Add consumer team as reviewer" took an action on this PR • (06/23/25)1 reviewer was added to this PR based on Keith Williams's automation. "Add community label" took an action on this PR • (06/23/25)1 label was added to this PR based on Keith Williams's automation. |
Hey @giripatel. Thanks for the PR. Could you please add a full loom video showing your feature? |
Hey @kart1ka , Please find the demo video for the PR linked below: Let me know if you need any further information or clarification regarding the PR. Thanks! |
Hey @kart1ka , Could you please take a moment to review it and let me know if any changes are needed from my side? Thank you! |
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.
Left few comments.
@giripatel Pls also resolve merge conflicts and fix unit test. |
Hey @kart1ka , I'm not encountering the test failure on my local setup. Could you help me investigate the issue? |
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.
Left a few comments
Pls also try to resolve the merge conflicts and add a loom video of the feature. |
- Revert SelectedSlots Relation with WebhookScheduledTrigger
WalkthroughThis change introduces support for tracking and handling expired reservations across the application. It adds a new "reservation_expired" localization string to all supported language resource files. The webhook system is extended to recognize a new trigger event, Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
packages/features/webhooks/components/WebhookForm.tsxOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the plugin "eslint-plugin-playwright". (The package "eslint-plugin-playwright" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
The plugin "eslint-plugin-playwright" was referenced from the config file in ".eslintrc.js". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. packages/features/webhooks/lib/constants.tsOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the plugin "eslint-plugin-playwright". (The package "eslint-plugin-playwright" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
The plugin "eslint-plugin-playwright" was referenced from the config file in ".eslintrc.js". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. packages/features/webhooks/lib/scheduleTrigger.tsOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the plugin "eslint-plugin-playwright". (The package "eslint-plugin-playwright" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
The plugin "eslint-plugin-playwright" was referenced from the config file in ".eslintrc.js". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.
Note ⚡️ Unit Test Generation - BetaCodeRabbit's unit test generation is now available in Beta! Automatically generate comprehensive unit tests for your code changes, ensuring better test coverage and catching edge cases you might miss. Our AI analyzes your code structure and creates tests that follow best practices and your project's testing patterns. Learn more here, or just try it under ✨ Finishing Touches. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Hey @kart1ka , Please find the loom video of the feature below. https://www.loom.com/share/af4a4c676c12435d96369c35c4815860?sid=5c595cc2-0752-417f-aa57-406f7ae24a72 |
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.
Actionable comments posted: 5
🔭 Outside diff range comments (3)
packages/features/webhooks/components/WebhookForm.tsx (1)
55-62
: Keep alphabetical order & add missing translation for “reservation_expired”The options array should remain sorted by label to minimize merge conflicts. I’ve reordered the three entries below. Additionally, our checks show that the Bengali locale is missing the new key—please add it to avoid fallback to raw text.
• Reorder snippet in packages/features/webhooks/components/WebhookForm.tsx:
- { value: WebhookTriggerEvents.OOO_CREATED, label: "ooo_created" }, - { value: WebhookTriggerEvents.RESERVATION_EXPIRED, label: "reservation_expired" }, - { value: WebhookTriggerEvents.RECORDING_READY, label: "recording_ready" }, + { value: WebhookTriggerEvents.OOO_CREATED, label: "ooo_created" }, + { value: WebhookTriggerEvents.RECORDING_READY, label: "recording_ready" }, + { value: WebhookTriggerEvents.RESERVATION_EXPIRED, label: "reservation_expired" },• Missing translation key:
- apps/web/public/static/locales/bn/common.json
Please add a
"reservation_expired": "your translated string"
entry in that file.docs/developing/guides/automation/webhooks.mdx (1)
24-37
: Missing bullet for the new trigger → documentation inconsistentThe numbered list under “Event triggers” still omits Reservation Expired, causing a discrepancy with the table below and with the product UI.
@@ You can choose which specific triggers to listen to. Currently available triggers include: - `Booking Cancelled` - `Booking Created` - `Booking Rescheduled` - `Booking Rejected` - `Booking Requested` - `Booking Payment Initiated` - `Booking Paid` - `Meeting Started` - `Recording Ready` - `Form Submitted` - `Meeting Ended` - `Instant Meeting Created` + - `Reservation Expired`
packages/trpc/server/routers/viewer/slots/reserveSlot.handler.ts (1)
150-155
: Fix misleading error message in catch block.The error message "Event type not found" is incorrect here since the event type existence was already validated at line 53. This catch block handles failures from slot reservation or webhook scheduling operations.
Apply this fix to provide a more accurate error message:
} catch { throw new TRPCError({ - message: "Event type not found", - code: "NOT_FOUND", + message: "Failed to reserve slot or schedule webhook", + code: "INTERNAL_SERVER_ERROR", }); }
♻️ Duplicate comments (1)
packages/features/webhooks/lib/scheduleTrigger.ts (1)
296-307
: Improve the fragile webhook trigger search logic.The current implementation using JSON string manipulation is unreliable because:
JSON.stringify
doesn't guarantee consistent property ordering- The
contains
search could match unrelated payloads- String slicing assumes specific JSON formatting
Regarding the past review comment about updating existing triggers: this is necessary to handle reservation time extensions or modifications while maintaining a single trigger per slot.
Consider using a more robust approach:
- const { id, releaseAt, isSeat, ...rest } = slot; - const restString = JSON.stringify(rest); - const searchString = restString.slice(1, -1); - - const isWebhookScheduledTriggerExists = await prisma.webhookScheduledTriggers.findFirst({ - where: { - payload: { - contains: searchString, - }, - }, - }); + const isWebhookScheduledTriggerExists = await prisma.webhookScheduledTriggers.findFirst({ + where: { + AND: [ + { payload: { contains: `"uid":"${slot.uid}"` } }, + { payload: { contains: `"eventTypeId":${slot.eventTypeId}` } }, + { payload: { contains: `"userId":${slot.userId}` } }, + { payload: { contains: `"triggerEvent":"${triggerEvent}"` } }, + ], + }, + });Alternatively, consider adding a unique identifier field to the webhook scheduled triggers table for more reliable lookups.
🧹 Nitpick comments (11)
apps/web/public/static/locales/fr/common.json (1)
3334-3334
: Consider keeping keys alphabetically grouped for maintainabilityThe French translation looks good, but the new key is appended far away from the existing
reservation_*
group (around lines 530-545). Moving it near related keys keeps the JSON easier to scan and reduces merge-conflict odds when other locales get updated.@@ "booking_paid": "Réservation payée", "reservation_expired": "Réservation expirée", "ooo_created": "Absence créée",apps/web/public/static/locales/ro/common.json (1)
3334-3334
: Translation tense likely wrong – use past tense like the other “expired” strings.Elsewhere in this locale file you translate “request_is_expired” as “Acea solicitare a expirat.”
For consistency and correctness,reservation_expired
should probably be"reservation_expired": "Rezervarea a expirat"Current “Rezervarea expiră” means “is expiring”, not “has expired”.
Please align with the past-tense pattern.apps/web/public/static/locales/ru/common.json (1)
3334-3334
: Confirm new key is present in all locale files
"reservation_expired": "Бронь истекла",
looks good and follows the existing style.
Please make sure the same key is added (with proper translations or a sensible fallback) to every other locale file to avoidi18n
fall-back warnings at runtime.apps/web/public/static/locales/eu/common.json (1)
3334-3334
: Duplicate-key / placement sanity-checkA new entry
"reservation_expired": "Erreserba iraungita",has been appended far down in the file.
Two quick things to verify before merging:
- Make sure the key name isn’t already present elsewhere in this JSON – duplicate keys silently override in most JS loaders and are painful to trace.
- Keep the roughly alphabetical grouping we follow in the other locale files so that translators don’t have to hunt; if this key belongs around the other reservation_ messages higher up, consider moving it there.
No functional changes required if the above points are confirmed.
apps/web/public/static/locales/he/common.json (1)
3334-3334
: Translation is understandable but sounds unnatural – consider using “הזמנה פקעה”“הזמנה פגה” is grammatically correct, yet native speakers usually phrase an expired reservation as “הזמנה פקעה” or the fuller “תוקף ההזמנה פג/פקע”.
Replacing the wording will feel more natural in the UI.- "reservation_expired": "הזמנה פגה" + "reservation_expired": "הזמנה פקעה"apps/web/public/static/locales/sv/common.json (1)
3334-3334
: Swedish phrasing feels off – suggest a more natural translation“Bokning utgången” reads awkwardly in Swedish (literally “booking expired”).
Common phrasing would be e.g."Bokningen har löpt ut"
or"Reservationen har löpt ut"
to include the verb.- "reservation_expired": "Bokning utgången", + "reservation_expired": "Bokningen har löpt ut",This keeps consistency with other keys that form complete sentences.
Double-check any UI where the string appears for length/truncation.packages/prisma/migrations/20250723210656_remove_selected_slots_realtion_with_webhook_triggers/migration.sql (1)
7-11
: Minor: misspelled directory name & defensive SQLThe migration folder is named
...remove_selected_slots_realtion...
– “relation” is misspelled. Consistency helps when scanning migration history.For idempotency in dev/provisional environments, consider adding
IF EXISTS
to theDROP CONSTRAINT
andDROP COLUMN
statements. It prevents the entire migration from failing when the previous migration never ran (common in fresh DB snapshots).Example:
-ALTER TABLE "WebhookScheduledTriggers" DROP CONSTRAINT "WebhookScheduledTriggers_selectedSlotId_fkey"; -ALTER TABLE "WebhookScheduledTriggers" DROP COLUMN "selectedSlotId"; +ALTER TABLE "WebhookScheduledTriggers" + DROP CONSTRAINT IF EXISTS "WebhookScheduledTriggers_selectedSlotId_fkey", + DROP COLUMN IF EXISTS "selectedSlotId";apps/web/public/static/locales/id/common.json (1)
168-169
: Use the standard Indonesian spelling “kedaluwarsa”.“Kedaluwarsa” is the KBBI-preferred form; “kadaluarsa” is colloquial. Updating it keeps terminology consistent with formal wording used in the rest of the locale file.
- "reservation_expired": "Reservasi kadaluarsa" + "reservation_expired": "Reservasi kedaluwarsa"apps/web/public/static/locales/az/common.json (1)
3334-3334
: Confirm translation & i18n consistency for the new “reservation_expired” string
Good to see the new key landed, but please double-check:
- Wording – does “Rezervasiyanın müddəti bitmişdir” match the tone/style used for similar past-tense system states (e.g. “booking_cancelled”)?
- Pluralisation – this message is singular; if any UI shows the state in bulk contexts you might later need plural forms.
- Alphabetical / grouped ordering – we usually keep new keys clustered with other “reservation_…” strings to minimise merge noise across locales.
If all three are intentional, no further action needed.
packages/features/webhooks/lib/constants.ts (1)
5-24
: Consider alphabetising / de-duplicating thecore
array for long-term maintainability
As this list keeps growing, manual ordering makes it easy to introduce duplicates or miss events when scanning the file. A simple alphabetical sort (or an automated utility that derives the list fromWebhookTriggerEvents
and filters by prefix) would make future reviews cheaper and errors less likely.packages/features/webhooks/lib/scheduleTrigger.ts (1)
334-334
: Use the logger instance instead of console.error.For consistency with the rest of the file and better error tracking, use the existing logger instance.
- console.error("Error scheduling webhook trigger (create/update)", error); + log.error("Error scheduling webhook trigger (create/update)", safeStringify(error));
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (51)
apps/web/public/static/locales/ar/common.json
(1 hunks)apps/web/public/static/locales/az/common.json
(1 hunks)apps/web/public/static/locales/bg/common.json
(1 hunks)apps/web/public/static/locales/ca/common.json
(2 hunks)apps/web/public/static/locales/cs/common.json
(1 hunks)apps/web/public/static/locales/da/common.json
(1 hunks)apps/web/public/static/locales/de/common.json
(1 hunks)apps/web/public/static/locales/el/common.json
(1 hunks)apps/web/public/static/locales/en/common.json
(1 hunks)apps/web/public/static/locales/es-419/common.json
(1 hunks)apps/web/public/static/locales/es/common.json
(1 hunks)apps/web/public/static/locales/et/common.json
(1 hunks)apps/web/public/static/locales/eu/common.json
(1 hunks)apps/web/public/static/locales/fi/common.json
(1 hunks)apps/web/public/static/locales/fr/common.json
(1 hunks)apps/web/public/static/locales/he/common.json
(1 hunks)apps/web/public/static/locales/hr/common.json
(1 hunks)apps/web/public/static/locales/hu/common.json
(1 hunks)apps/web/public/static/locales/id/common.json
(1 hunks)apps/web/public/static/locales/it/common.json
(1 hunks)apps/web/public/static/locales/ja/common.json
(1 hunks)apps/web/public/static/locales/km/common.json
(1 hunks)apps/web/public/static/locales/ko/common.json
(1 hunks)apps/web/public/static/locales/lv/common.json
(1 hunks)apps/web/public/static/locales/nl/common.json
(1 hunks)apps/web/public/static/locales/no/common.json
(1 hunks)apps/web/public/static/locales/pl/common.json
(1 hunks)apps/web/public/static/locales/pt-BR/common.json
(1 hunks)apps/web/public/static/locales/pt/common.json
(1 hunks)apps/web/public/static/locales/ro/common.json
(1 hunks)apps/web/public/static/locales/ru/common.json
(1 hunks)apps/web/public/static/locales/sk-SK/common.json
(1 hunks)apps/web/public/static/locales/sk/common.json
(1 hunks)apps/web/public/static/locales/sr/common.json
(1 hunks)apps/web/public/static/locales/sv/common.json
(1 hunks)apps/web/public/static/locales/ta/common.json
(1 hunks)apps/web/public/static/locales/tr/common.json
(1 hunks)apps/web/public/static/locales/uk/common.json
(1 hunks)apps/web/public/static/locales/vi/common.json
(1 hunks)apps/web/public/static/locales/zh-CN/common.json
(1 hunks)apps/web/public/static/locales/zh-TW/common.json
(1 hunks)docs/developing/guides/automation/webhooks.mdx
(1 hunks)packages/features/schedules/components/Schedule.tsx
(0 hunks)packages/features/webhooks/components/WebhookForm.tsx
(1 hunks)packages/features/webhooks/lib/constants.ts
(1 hunks)packages/features/webhooks/lib/scheduleTrigger.ts
(2 hunks)packages/prisma/migrations/20250623204508_add_reservation_expired_webhook/migration.sql
(1 hunks)packages/prisma/migrations/20250723210656_remove_selected_slots_realtion_with_webhook_triggers/migration.sql
(1 hunks)packages/prisma/schema.prisma
(1 hunks)packages/trpc/server/routers/viewer/slots/reserveSlot.handler.test.ts
(1 hunks)packages/trpc/server/routers/viewer/slots/reserveSlot.handler.ts
(4 hunks)
💤 Files with no reviewable changes (1)
- packages/features/schedules/components/Schedule.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/review.mdc)
Flag excessive Day.js use in performance-critical code. Functions like .add, .diff, .isBefore, and .isAfter are slow, especially in timezone mode. Prefer .utc() for better performance. Where possible, replace with native Date and direct .valueOf() comparisons for faster execution. Recommend using native methods or Day.js .utc() consistently in hot paths like loops.
Files:
packages/trpc/server/routers/viewer/slots/reserveSlot.handler.test.ts
packages/features/webhooks/components/WebhookForm.tsx
packages/features/webhooks/lib/constants.ts
packages/trpc/server/routers/viewer/slots/reserveSlot.handler.ts
packages/features/webhooks/lib/scheduleTrigger.ts
🧠 Learnings (23)
apps/web/public/static/locales/en/common.json (2)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
Learnt from: CR
PR: calcom/cal.com#0
File: .cursor/rules/review.mdc:0-0
Timestamp: 2025-07-21T13:54:11.770Z
Learning: Applies to docs/api-reference/v2/openapi.json : When docs changes are made in /docs/api-reference/v2/openapi.json, ensure the following: 'summary' fields are written in proper American english.
apps/web/public/static/locales/sr/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/zh-TW/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/bg/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/km/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
packages/trpc/server/routers/viewer/slots/reserveSlot.handler.test.ts (1)
Learnt from: vijayraghav-io
PR: #21072
File: packages/app-store/office365calendar/api/webhook.ts:120-123
Timestamp: 2025-07-18T17:57:16.395Z
Learning: The office365calendar webhook handler in packages/app-store/office365calendar/api/webhook.ts is specifically designed for Office365 calendar integration, not as a generic webhook handler. Therefore, it's safe to assume that fetchAvailabilityAndSetCache method will be implemented in the Office365CalendarService, making explicit validation checks unnecessary.
apps/web/public/static/locales/sk/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
packages/features/webhooks/lib/constants.ts (1)
Learnt from: vijayraghav-io
PR: #21072
File: packages/app-store/office365calendar/api/webhook.ts:120-123
Timestamp: 2025-07-18T17:57:16.395Z
Learning: The office365calendar webhook handler in packages/app-store/office365calendar/api/webhook.ts is specifically designed for Office365 calendar integration, not as a generic webhook handler. Therefore, it's safe to assume that fetchAvailabilityAndSetCache method will be implemented in the Office365CalendarService, making explicit validation checks unnecessary.
apps/web/public/static/locales/es/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/lv/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/sv/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/it/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/az/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/ar/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/ro/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/pt/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/es-419/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/cs/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/hr/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
apps/web/public/static/locales/pl/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
packages/trpc/server/routers/viewer/slots/reserveSlot.handler.ts (3)
Learnt from: vijayraghav-io
PR: #21072
File: packages/app-store/office365calendar/api/webhook.ts:120-123
Timestamp: 2025-07-18T17:57:16.395Z
Learning: The office365calendar webhook handler in packages/app-store/office365calendar/api/webhook.ts is specifically designed for Office365 calendar integration, not as a generic webhook handler. Therefore, it's safe to assume that fetchAvailabilityAndSetCache method will be implemented in the Office365CalendarService, making explicit validation checks unnecessary.
Learnt from: vijayraghav-io
PR: #21072
File: packages/prisma/schema.prisma:891-891
Timestamp: 2025-07-18T08:47:01.264Z
Learning: The Outlook Calendar integration in Cal.com intentionally reuses subscription IDs across multiple event types for efficiency. The upsertSelectedCalendarsForEventTypeIds
method creates separate SelectedCalendar records for each eventTypeId, all sharing the same outlookSubscriptionId. This subscription sharing pattern means that unique constraints like @@unique([outlookSubscriptionId, eventTypeId])
should not be applied as they would prevent this intended functionality.
Learnt from: vijayraghav-io
PR: #21072
File: packages/prisma/schema.prisma:891-891
Timestamp: 2025-07-18T08:47:01.264Z
Learning: In Cal.com's calendar integration, both Google Calendar and Outlook Calendar are designed to allow multiple eventTypeIds to share the same subscription ID (googleChannelId or outlookSubscriptionId). This is an intentional design pattern to reuse existing subscriptions for efficiency rather than creating separate subscriptions for each event type. Therefore, unique constraints like @@unique([outlookSubscriptionId, eventTypeId])
should not be added as they would break this subscription sharing functionality.
apps/web/public/static/locales/ca/common.json (1)
Learnt from: bandhan-majumder
PR: #22359
File: packages/lib/server/locales/en/common.json:1336-1339
Timestamp: 2025-07-14T16:31:45.233Z
Learning: When making localization changes for new features, it's often safer to add new strings rather than modify existing ones to avoid breaking existing functionality that depends on the original strings. This approach allows for feature-specific customization while maintaining backward compatibility.
packages/features/webhooks/lib/scheduleTrigger.ts (3)
Learnt from: vijayraghav-io
PR: #21072
File: packages/app-store/office365calendar/api/webhook.ts:120-123
Timestamp: 2025-07-18T17:57:16.395Z
Learning: The office365calendar webhook handler in packages/app-store/office365calendar/api/webhook.ts is specifically designed for Office365 calendar integration, not as a generic webhook handler. Therefore, it's safe to assume that fetchAvailabilityAndSetCache method will be implemented in the Office365CalendarService, making explicit validation checks unnecessary.
Learnt from: vijayraghav-io
PR: #21072
File: packages/app-store/office365calendar/api/webhook.ts:50-60
Timestamp: 2025-07-18T17:54:04.613Z
Learning: For Microsoft Graph webhook handlers, when dealing with internal configuration errors (like missing MICROSOFT_WEBHOOK_TOKEN), it's better to return 200 OK with errors tracked in the response body rather than throwing 5xx errors. This prevents retry storms from Microsoft Graph and maintains webhook subscription health, while still providing visibility through error logs and structured error responses.
Learnt from: vijayraghav-io
PR: #21072
File: packages/prisma/schema.prisma:891-891
Timestamp: 2025-07-18T08:47:01.264Z
Learning: In Cal.com's calendar integration, both Google Calendar and Outlook Calendar are designed to allow multiple eventTypeIds to share the same subscription ID (googleChannelId or outlookSubscriptionId). This is an intentional design pattern to reuse existing subscriptions for efficiency rather than creating separate subscriptions for each event type. Therefore, unique constraints like @@unique([outlookSubscriptionId, eventTypeId])
should not be added as they would break this subscription sharing functionality.
🧬 Code Graph Analysis (1)
packages/features/webhooks/lib/scheduleTrigger.ts (1)
apps/api/v2/src/lib/logger.bridge.ts (1)
error
(77-79)
🪛 GitHub Actions: PR Update
packages/trpc/server/routers/viewer/slots/reserveSlot.handler.test.ts
[error] TRPCError: Event type not found during reserveSlotHandler cookie settings tests.
packages/trpc/server/routers/viewer/slots/reserveSlot.handler.ts
[error] 151-151: TRPCError: Event type not found during 'reserveSlotHandler' step.
🔇 Additional comments (40)
apps/web/public/static/locales/bg/common.json (1)
3334-3334
: New locale key added correctly
The"reservation_expired"
entry is syntactically valid and the Bulgarian translation reads naturally. No further adjustments needed.apps/web/public/static/locales/fi/common.json (1)
3334-3334
: LGTM – new translation string is correctThe Finnish translation “Varaus vanhentunut” accurately reflects “reservation expired” and the JSON syntax is valid (comma-separated, quoted key/value).
No further action needed.apps/web/public/static/locales/pl/common.json (1)
3334-3334
: New key looks good – verify cross-locale consistencyThe Polish translation for the newly-added key
reservation_expired
is clear and correct.
Please make sure the same key exists in every other locale file so runtime look-ups won’t fall back to the default language.apps/web/public/static/locales/zh-CN/common.json (1)
3334-3334
: Translation entry looks correct & consistent
Key"reservation_expired"
is newly added and the Chinese value “预订已过期” accurately conveys “reservation expired”. No further action needed.apps/web/public/static/locales/hu/common.json (1)
3334-3334
: Translation looks correct – no further action needed.The added key
"reservation_expired"
is correctly translated to Hungarian (“A foglalás lejárt”) and follows the existing JSON style (quotes, comma). LGTM.apps/web/public/static/locales/no/common.json (1)
3334-3334
: Adds missing Norwegian translation forreservation_expired
– looks good.apps/web/public/static/locales/en/common.json (1)
3358-3360
: Looks good – remember to propagate to non-English locales
The new key/value pair is well-formed and follows existing naming conventions. Just double-check that every non-English JSON file contains the corresponding"reservation_expired"
translation before merging, otherwiset()
look-ups will silently fall back to the English string.packages/prisma/schema.prisma (1)
968-988
: Adding an enum value needs an irreversible Postgres migration – double-check the migration & rollback strategy
RESERVATION_EXPIRED
is appended toWebhookTriggerEvents
, which means Prisma will generateALTER TYPE "WebhookTriggerEvents" ADD VALUE 'RESERVATION_EXPIRED';
.
On Postgres this statement:
- Is irreversible (you can’t
DROP VALUE
), so a down-migration will silently be a no-op unless you recreate the type.- Locks the enum for the duration of the change; on large tables this can briefly block writes.
Please confirm that:
• The generated migration exists and succeeds on a prod-sized DB.
• You’re comfortable that rollbacks will recreate the enum/type rather than rely onprisma migrate dev reset
.
• All TypeScript/GraphQL unions derived fromWebhookTriggerEvents
were re-generated (prisma generate
, zod, Kysely enums, etc.) so the new value is type-safe across the codebase.If needed, create a companion “downgrade” script that recreates the enum without the new value and rewires the columns, or document that rollback is unsupported.
apps/web/public/static/locales/de/common.json (1)
3334-3334
: Key added successfully – no issues foundThe new translation entry for “reservation_expired” is syntactically correct (valid JSON, includes trailing comma) and follows the established key/value pattern.
No further action needed here.apps/web/public/static/locales/sr/common.json (1)
3334-3334
: New locale key looks goodKey is unique, follows existing naming convention, and translation is concise without trailing punctuation (consistent with nearby entries).
No further action needed.apps/web/public/static/locales/ja/common.json (1)
3334-3334
: Translation looks accurate – no issues foundKey
reservation_expired
is added with the translation予約期限切れ
, which correctly conveys “reservation expired.”
No duplication or JSON-syntax problems detected. 👍apps/web/public/static/locales/it/common.json (1)
3334-3334
: Italian translation looks good – remember to sync other locale files
"reservation_expired": "Prenotazione scaduta"
is clear and idiomatic.
Confirm the same key exists in every othercommon.json
locale to prevent undefined-string fallbacks at runtime.apps/web/public/static/locales/da/common.json (1)
3334-3334
: Localization key looks goodKey/value pair is syntactically correct, Danish translation is clear, and trailing comma keeps JSON valid. No further action needed.
apps/web/public/static/locales/es/common.json (1)
3334-3334
: Localization entry looks goodKey is consistent with other locales, string reads naturally in Spanish, and surrounding commas keep the JSON valid. No further action needed.
apps/web/public/static/locales/el/common.json (1)
3334-3334
: LGTM – accurate translation & valid JSONThe new
reservation_expired
key is syntactically correct, follows existing style (“Η κράτηση …”), and is placed in the designated “add-above” area, preserving merge-conflict guard lines.
No issues detected.apps/web/public/static/locales/vi/common.json (1)
3333-3335
: LGTM – translation key added correctlyKey
reservation_expired
is added with the correct Vietnamese translation and JSON syntax (including trailing comma). No other issues spotted.apps/web/public/static/locales/et/common.json (1)
3334-3334
: Translation key looks correctThe new
reservation_expired
key is added with an accurate Estonian translation and valid JSON syntax. No further action required.apps/web/public/static/locales/uk/common.json (1)
3334-3334
: Key added correctly; verify cross-locale coverage.The new
"reservation_expired"
entry looks good linguistically ("Бронювання закінчилося"
), follows the existing pattern, and contains no interpolation placeholders that would require braces.Just double-check that the same key now exists in all locale files so that runtime look-ups never fall back to the default language.
packages/prisma/migrations/20250723210656_remove_selected_slots_realtion_with_webhook_triggers/migration.sql (1)
1-6
: Confirm safe removal ofselectedSlotId
– irreversible destructive migrationI ran
rg -n --no-heading 'selectedSlotId'
and only found its addition and removal in migration files:
• 20250623204508_add_reservation_expired_webhook/migration.sql – adds
selectedSlotId
• 20250723210656_remove_selected_slots_realtion_with_webhook_triggers/migration.sql – drops the FK and columnNo references remain in application code.
Please verify:
- Business logic or analytics don’t rely on this column anywhere (including ad-hoc queries or dashboards).
- You have an export/archival plan for existing
selectedSlotId
data if it’s needed for historic replay or reporting.apps/web/public/static/locales/nl/common.json (1)
3334-3334
: Translation entry looks good.Key
reservation_expired
is new, translation is idiomatic (“Reservering verlopen”) and JSON syntax remains valid. No duplication detected.apps/web/public/static/locales/ko/common.json (1)
3334-3334
:reservation_expired
번역이 추가되었습니다 – 다른 언어 리소스도 같이 업데이트됐는지 확인해주세요.Korean 번역 자체는 자연스럽습니다. 다만 새 키를 추가할 때는 전체 locale 세트(예:
en
,de
,fr
, …)에 동일한 키가 빠짐없이 들어갔는지 한 번 더 점검해 주세요.
누락되면 런타임에 fallback 문제가 발생하거나 i18n-lint가 실패할 수 있습니다.apps/web/public/static/locales/zh-TW/common.json (1)
3334-3334
: String addition looks good – please ensure parity across locales.
"reservation_expired": "預訂已過期"
is correctly translated and formatted.
Just make sure the same key exists in every other locale file so the UI doesn’t fall back to the default language.apps/web/public/static/locales/cs/common.json (1)
3334-3334
: New string looks correctThe added translation for
reservation_expired
(“Platnost rezervace vypršela”) is accurate Czech and the key follows the existing naming style. JSON syntax is valid (comma-separated list).apps/web/public/static/locales/sk-SK/common.json (1)
3334-3334
: Verify presence ofreservation_expired
across all localesThe new key is correctly added here, but please ensure:
- The same
reservation_expired
entry exists in the base (locale-neutral /en-US
) file, otherwise fallback strings will break.- Other production locales are updated (or at least intentionally left to fall back) so runtime look-ups don’t 404.
No action needed in this file if that’s already covered.
apps/web/public/static/locales/sk/common.json (1)
69-70
: JSON fix & new key look good• Added missing comma keeps the file valid JSON.
•"reservation_expired"
key follows existing naming convention and the Slovak translation “Rezervácia vypršala” is correct.No further action needed. 👍
apps/web/public/static/locales/ar/common.json (1)
3334-3334
: Consistency with existing localisation styleKey name, punctuation and Arabic translation look good and match the pattern used elsewhere (straight key / value pair, ending with a comma). No further action needed 👍
apps/web/public/static/locales/lv/common.json (1)
164-165
: Translation looks good – please get it signed-off by a native speakerThe new keys are syntactically correct and you fixed the missing comma issue.
For quality assurance, have a Latvian translator quickly verify that both the grammar and tone match the rest of the file.apps/web/public/static/locales/ta/common.json (1)
213-214
: Tamil entry added correctly – double-check the wordingJSON remains valid and the key order is preserved.
Kindly ask a native Tamil reviewer to confirm that “முன்பதிவு காலாவதியானது” is the preferred phrasing in this context.docs/developing/guides/automation/webhooks.mdx (1)
185-185
: Table row correctly updated – thanks for keeping it in syncapps/web/public/static/locales/km/common.json (1)
3334-3334
: New locale key added; ensure parity across all language filesThe new string
"reservation_expired"
is present in the Khmer locale.
Please confirm that the same key exists (with appropriate translations) in every other locale JSON understatic/locales/
so translation look-ups don’t fall back to English.If the other locale files were updated in a separate commit, you can ignore this note.
apps/web/public/static/locales/pt/common.json (1)
3334-3334
: Consistent translation – looks good.The Portuguese string follows the same pattern used elsewhere (e.g., “Reserva cancelada”) and reads naturally.
No action required.packages/features/webhooks/lib/constants.ts (1)
23-23
: Addition ofRESERVATION_EXPIRED
event looks correct
Enum value is properly appended and keeps the grouping consistent with the other core events.apps/web/public/static/locales/tr/common.json (1)
3334-3334
: New localization entry looks good
The keyreservation_expired
is properly added with an accurate Turkish translation and follows the existing formatting conventions.apps/web/public/static/locales/hr/common.json (1)
455-456
: String added correctly – no action required
The newreservation_expired
key is additive, keeps the JSON valid (comma placement is correct), and follows the established naming / translation conventions.packages/prisma/migrations/20250623204508_add_reservation_expired_webhook/migration.sql (1)
1-2
: Enum value addition looks fine
AddingRESERVATION_EXPIRED
is forward-only and doesn’t break existing rows.packages/trpc/server/routers/viewer/slots/reserveSlot.handler.test.ts (2)
21-28
: LGTM! Webhook mocks are properly isolated.The mocks for
getWebhooks
andscheduleReservationExpiredTrigger
appropriately isolate the test from external webhook dependencies, allowing the cookie settings tests to focus on their core functionality.
34-48
: Mocks inreserveSlot.handler.test.ts
are correctly configured—no changes needed.The
buildContext
stub consistently provides a non-nulleventType.findUnique
return value (includingteamId
andteam.parentId
), and there are no competing mocks or resets in this file. The “Event type not found” error must be coming from a different test suite.packages/trpc/server/routers/viewer/slots/reserveSlot.handler.ts (2)
6-14
: LGTM! Imports are well-organized for webhook functionality.The new imports properly support the reservation expiration webhook feature by bringing in webhook scheduling utilities, organization/team helpers, and the necessary enum values.
37-50
: LGTM! Query expansion supports webhook organization filtering.The additional fields (
teamId
andteam.parentId
) are necessary for determining the effective team context when scheduling webhooks, especially for organization-level webhook subscriptions.packages/features/webhooks/lib/scheduleTrigger.ts (1)
20-29
: LGTM! Well-structured type definition.The
SLOT_TYPE
properly defines all necessary fields for slot reservation tracking in webhook payloads.
<<<<<<< HEAD | ||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Afegiu les vostres noves cadenes a dalt ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑", | ||
"reservation_expired": "Reserva caducada" | ||
======= |
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.
Resolve merge-conflict markers – file is unparsable JSON
<<<<<<< HEAD
, =======
, and >>>>>>> …
markers are still in the file together with a duplicated "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS"
key.
Until these are removed the JSON cannot be parsed, which will break every build step that tries to load the locale files.
-<<<<<<< HEAD
- "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Afegiu les vostres noves cadenes a dalt ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑",
- "reservation_expired": "Reserva caducada"
-=======
+ "reservation_expired": "Reserva caducada",
After selecting the correct block:
- Delete all conflict markers.
- Keep a single copy of the sentinel key (
ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS
) at the very end of the object. - Re-run
npm run lint:locales
(or equivalent) to ensure the JSON is valid.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/web/public/static/locales/ca/common.json around lines 3334 to 3337,
there are unresolved merge conflict markers including <<<<<<< HEAD and =======,
along with duplicated keys. Remove all conflict markers completely, keep only
one instance of the "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS"
key at the end of the JSON object, and then run the locale linter (e.g., npm run
lint:locales) to verify the JSON is valid and parsable.
"no_members_affected_by_disabling_delegation_credential": "Ningún miembro afectado por la desactivación de credenciales de delegación", | ||
"reservation_expired": "Reserva vencida", | ||
"download_expense_log": "Descargar registro de gastos", |
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.
Duplicate key breaks the JSON payload
"download_expense_log"
already exists earlier in the file.
Having the same key twice is invalid JSON and many loaders will either reject the file or silently drop the first occurrence, causing hard-to-trace i18n bugs at runtime.
"reservation_expired": "Reserva vencida",
- "download_expense_log": "Descargar registro de gastos",
Remove the second copy (shown above) or rename it so every key is unique.
🤖 Prompt for AI Agents
In apps/web/public/static/locales/es-419/common.json around lines 3333 to 3335,
there is a duplicate key "download_expense_log" which breaks the JSON structure.
To fix this, remove the second occurrence of the "download_expense_log" key or
rename it to a unique key to ensure all keys in the JSON file are distinct and
valid.
"no_members_affected_by_disabling_delegation_credential": "Nenhum membro afetado pela desativação da credencial de delegação", | ||
"reservation_expired": "Reserva expirada", | ||
"download_expense_log": "Baixar registro de despesas", |
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.
Duplicate key breaks JSON semantics – remove the 2nd "download_expense_log"
entry
The key download_expense_log
appears twice (lines 3333 & 3335).
Although some JSON parsers keep the last occurrence, duplicated keys are illegal JSON and will fail strict validators / tooling (e.g. i18n extractors, TS-type generation).
"download_expense_log": "Baixar registro de despesas",
- "reservation_expired": "Reserva expirada",
- "download_expense_log": "Baixar registro de despesas",
+ "reservation_expired": "Reserva expirada",
After the removal, the newly-added reservation_expired
string is kept and the JSON stays valid.
📝 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.
"no_members_affected_by_disabling_delegation_credential": "Nenhum membro afetado pela desativação da credencial de delegação", | |
"reservation_expired": "Reserva expirada", | |
"download_expense_log": "Baixar registro de despesas", | |
"no_members_affected_by_disabling_delegation_credential": "Nenhum membro afetado pela desativação da credencial de delegação", | |
"download_expense_log": "Baixar registro de despesas", | |
"reservation_expired": "Reserva expirada", |
🤖 Prompt for AI Agents
In apps/web/public/static/locales/pt-BR/common.json around lines 3333 to 3335,
there is a duplicate key "download_expense_log" which breaks JSON semantics.
Remove the second occurrence of the "download_expense_log" key to ensure the
JSON remains valid and keep the "reservation_expired" entry intact.
ALTER TABLE "WebhookScheduledTriggers" ADD COLUMN "selectedSlotId" INTEGER; | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "WebhookScheduledTriggers" ADD CONSTRAINT "WebhookScheduledTriggers_selectedSlotId_fkey" FOREIGN KEY ("selectedSlotId") REFERENCES "SelectedSlots"("id") ON DELETE CASCADE ON UPDATE CASCADE; |
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.
💡 Verification agent
🧩 Analysis chain
Avoid temporary column churn – squash this change or keep the column
selectedSlotId
is introduced here and removed again in a later migration in the same PR. Shipping both migrations will:
- Lock & rewrite the large
WebhookScheduledTriggers
table twice. - Require two deploys/rollbacks instead of one.
Unless you actually need selectedSlotId
long-term, drop the addition now and fold the enum change into a single migration:
-ALTER TABLE "WebhookScheduledTriggers" ADD COLUMN "selectedSlotId" INTEGER;
-
--- AddForeignKey
-ALTER TABLE "WebhookScheduledTriggers" ADD CONSTRAINT "WebhookScheduledTriggers_selectedSlotId_fkey" FOREIGN KEY ("selectedSlotId") REFERENCES "SelectedSlots"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Otherwise, remove the follow-up migration that deletes the column.
🏁 Script executed:
#!/bin/bash
rg "selectedSlotId" -n packages/prisma/migrations
Length of output: 1153
Eliminate temporary column churn by consolidating these migrations
You currently add then immediately drop selectedSlotId
in two separate migrations:
- packages/prisma/migrations/20250623204508_add_reservation_expired_webhook/migration.sql (adds column + FK)
- packages/prisma/migrations/20250723210656_remove_selected_slots_realtion_with_webhook_triggers/migration.sql (drops FK + column)
Shipping both will:
- Lock & rewrite the large
WebhookScheduledTriggers
table twice - Force two deploys/rollbacks instead of one
Choose one of the following fixes:
- If you don’t need
selectedSlotId
long-term, drop both the add and drop steps and fold any enum or schema changes into a single migration. - If you do need the column, remove the second migration (
20250723210656_remove_selected_slots_realtion_with_webhook_triggers
) so that the column remains in place.
🤖 Prompt for AI Agents
In
packages/prisma/migrations/20250623204508_add_reservation_expired_webhook/migration.sql
lines 5 to 8, you add the selectedSlotId column and foreign key but then
immediately drop them in a later migration, causing unnecessary table locks and
rewrites. To fix this, either remove both the add and drop steps and consolidate
any related schema changes into a single migration if the column is not needed
long-term, or if the column is needed, delete the later migration that drops the
column and foreign key to keep the column intact.
// FIXME: In case of team event, users doesn't have assignees, those are in hosts. users just have the creator of the event which is wrong. | ||
// Also, we must not block all the users' slots, we must use routedTeamMemberIds if set like we do in getSchedule. | ||
// We could even improve it by identifying the next person being booked now that we have a queue of assignees. |
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.
Address the FIXME comment about team event assignees.
The comment indicates that for team events, the users
array might contain only the event creator rather than the actual assignees. This could lead to incorrect slot reservations and webhook scheduling.
Would you like me to help implement the proper logic for handling team event assignees using routedTeamMemberIds
as mentioned in the comment?
🤖 Prompt for AI Agents
In packages/trpc/server/routers/viewer/slots/reserveSlot.handler.ts around lines
105 to 107, the current logic incorrectly uses the event creator as the assignee
for team events, which causes wrong slot reservations. Update the code to check
if routedTeamMemberIds is set and use those IDs as the actual assignees instead
of the users array. This will ensure only the relevant team members' slots are
blocked and webhook scheduling is accurate. Adjust the logic to handle the queue
of assignees if applicable, similar to the approach in getSchedule.
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.
There are lots of unrelated file changes in this PR. Can you clean things up a bit and keep only the changes related to the issue at hand?
There also seems to be a test failing. Pls fix that.
I can see there are two migration files which seems to be bit messy. can you clean those up as well?
What does this PR do?
This feature introduces a new webhook event that triggers when a reservation expires. It allows external systems to receive real-time notifications about expired reservations, enabling better automation and integration workflows.
Key Highlights:
Event Trigger: Fires automatically upon reservation expiration.
Payload: Includes reservation details such as id, timestamps, and status.
Integration: Can be configured via existing webhook settings.
Fixes feature: expired reservation tracking #21845
Fixes CAL-5934
Visual Demo (For contributors especially)
A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).
Video Demo (if applicable):
Image Demo of Final Payload:
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
Summary by cubic
Added a new webhook event that triggers when a reservation expires, allowing external systems to get notified in real time.