Follow-up to #27085 - removes the remaining code references to the
deprecated user.startTime and user.endTime columns that were missed
in the initial PR.
Changes:
- Remove startTime/endTime from availabilityUserSelect in prisma selects
- Remove startTime/endTime from GetUserAvailabilityInitialData type
- Remove startTime/endTime from defaultEvents user mock object
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-22 11:29:41 -03:00
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Volnei Munhoz
* Early return if date range is empty
* test: add tests for empty workingHours early return optimization
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
* refactor: Extract schedule determination to seperate fn
* refactor: Extract schedule detection to seperate file and add tests
* RouterOutputs should be used in hooks, not direct type imports
* refactor: First high level changes to getUsersAvailability
* Fix usage of getUserAvailability where getUsersAvailability is unused
* Fix user.schema.ts in APIv2
* User handler did not provide initial data
* Small ts fixes
* Set user non-nullable in getTimezoneFromDelegatedCredential
* Small ts fixes, ensure consumers are aware its nonnullable
* Mode is defaulted to none
* Mode is defaulted to none, fix ts when directly using fn (temp)
2026-01-08 14:45:26 +00:00
Volnei MunhozGitHubVolnei Munhozcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* refactor: replace shouldServeCache with mode parameter for calendar cache control
Replace the boolean shouldServeCache parameter with a new CalendarFetchMode type
that can have values 'slots', 'overlay', and 'booking'. This provides better
control over when to serve cache vs relay on calendar providers.
- 'slots' mode: Check feature flags and use cache when available (for getting
actual calendar availability)
- 'overlay' mode: Don't use cache (for overlay calendar availability)
- 'booking' mode: Don't use cache (for booking confirmation)
- undefined: Same as 'slots' for backwards compatibility
The cache decision logic is now centralized in getCalendar.ts based on the mode
parameter.
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: update CalendarService.test.ts to use mode parameter
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* refactor: use shared GetAvailabilityParams type across all calendar services
- Import GetAvailabilityParams and GetAvailabilityWithTimeZonesParams from @calcom/types/Calendar
- Replace inline type definitions with shared types in all calendar service implementations
- Update BaseCalendarService, CalendarCacheWrapper, and CalendarTelemetryWrapper
- Ensures consistent typing and follows DRY principles
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: add missing IntegrationCalendar import and update mock getAvailability signature
- Add IntegrationCalendar back to sendgrid CalendarService imports
- Update bookingScenario mock getAvailability to use typed params object
- Add listCalendars method to mock Calendar object
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: update test files to use typed params object for getAvailability methods
- Update CalendarCacheWrapper.test.ts to call getAvailability/getAvailabilityWithTimeZones with params object
- Update getCalendarsEvents.test.ts toHaveBeenCalledWith assertions to expect params object
- All 32 tests now pass
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* refactor: consolidate to single GetAvailabilityParams type for both getAvailability methods
- Remove GetAvailabilityWithTimeZonesParams, use GetAvailabilityParams for both methods
- Add mode parameter to getAvailabilityWithTimeZones calls
- Update wrapper classes to pass mode through to underlying calendar
- Update test files to include mode in getAvailabilityWithTimeZones calls and assertions
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* refactor: use EventBusyDate with optional timeZone for getAvailabilityWithTimeZones
- Add optional timeZone field to EventBusyDate type
- Update getAvailabilityWithTimeZones return type to use EventBusyDate[]
- Update Google Calendar service and wrapper classes to use the new type
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: type errors and remove unused calendar watching methods
- Fix type errors in CalendarCacheWrapper.ts (convert null to undefined for timeZone)
- Fix type errors in getCalendarsEvents.ts (ensure timeZone is always present)
- Remove unused watchCalendar/unwatchCalendar from Calendar interface
- Remove unused startWatchingCalendarsInGoogle/stopWatchingCalendarsInGoogle from GoogleCalendarService
- Remove unused imports (uuid, uniqueBy, GOOGLE_WEBHOOK_URL, ONE_MONTH_IN_MS)
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: remove watchCalendar/unwatchCalendar from CalendarTelemetryWrapper
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* refactor: remove verbose JSDoc param comments from wrapper classes
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* refactor: make mode parameter required in getCalendar
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: add required mode parameter to all getCalendar callers
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: provide default mode value in getBusyCalendarTimes
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: add mode parameter to remaining getCalendar callers
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: add mode parameter to vital and wipemycalother reschedule
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: add mode parameter to credential-sync API endpoint
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* refactor: add 'none' mode to CalendarFetchMode and use as default
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* test: add mode parameter to getCalendarsEvents test calls
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* Update packages/app-store/delegationCredential.ts
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* refactor(holidays): improve code quality and address PR review feedback
- Move HolidaysView.tsx from /features to /apps/web/modules following
the pattern of keeping trpc-using components in /apps/web/modules
- Fix prisma import to use named import: `import { prisma }`
- Fix timezone bug in checkConflicts: use dayjs.utc() for consistent
date boundaries regardless of server timezone
- Fix toggleHoliday validation to include both current and next year
holidays, matching the holidays displayed to users
- Implement dependency injection pattern for holiday repository:
- Create PrismaHolidayRepository with instance methods
- Add HOLIDAY_REPOSITORY DI token and module
- Update containers to load holiday repository module
- Update calculateHolidayBlockedDates to use injected repository
- Remove stale HOLIDAY_CACHE_DAYS env declaration (now a constant)
- Update tests to mock repository instead of prisma directly
* feat(holidays): improve UI responsiveness and add country flags
- Add country flag emojis to holidays dropdown using Unicode regional
indicator symbols
- Handle edge cases for religious holidays (Hindu, Christian, etc.)
which dont have 2-letter country codes
- Increase country dropdown width to 180px for better readability
- Make OOO/Holidays tabs responsive: use Select dropdown on mobile,
ToggleGroup on desktop
- Make + Add button responsive: show only + icon on mobile,
full text on desktop
- Fix PrismaHolidayRepository import to use @calcom/prisma for
consistency with other repositories
* feat(holidays): add contextual emojis for holidays
- Add keyword-based emoji mapping for 80+ holidays
- Display holiday emojis in styled containers on settings page
- Add country flag emojis to dropdown using Unicode regional indicators
- Use dynamic emojis on booking page unavailable dates
* fix(holidays): address PR review feedback
- Fix emoji ordering: move Chinese/Lunar New Year before generic new year to prevent incorrect match
- Fix i18n: use t() instead of hardcoded text more in conflict warning
- Fix a11y: use sr-only pattern for mobile button to maintain screen reader accessibility
* fix failing test: packages/features/availability/lib/calculateHolidayBlockedDates.test.ts
* fix failing test: packages/features/availability/lib/calculateHolidayBlockedDates.test.ts
* fix failing tests and builds
* feat: add holidays feature for automatic availability blocking- Add UserHolidaySettings model for storing user preferences- Generate static holiday data for 20 countries using date-holidays- Create HolidayService for runtime holiday queries- Add TRPC router with endpoints for country selection and holiday toggles- Create Holidays tab UI in Availability page with conflict warnings- Integrate holiday blocking into getUserAvailability calculation- Show holiday indicator on blocked dates in booker page- Add warning in OOO modal when dates overlap with holidays
* feat: add optimizations, tests, and code quality improvements
- Add memoization/caching to HolidayService for better performance
- Optimize checkConflicts DB query with OR conditions for specific dates
- Add HolidayService unit tests (10 tests)
- Add error handling with Alert component for failed queries
- Memoize HolidayListItem component to prevent unnecessary re-renders
- Extract magic numbers into constants.ts
- Use TRPCError consistently in handlers
- Add missing i18n keys for error messages
- Update handlers to follow Cal.com patterns (default exports, minimal comments)
- Add regeneration instructions in constants
* refactor: replace static JSON with Google Calendar API integration
- Add GoogleHolidayService to fetch holidays from Google Calendar public calendars
- Add HolidayCache Prisma model for caching API responses
- Add GOOGLE_CALENDAR_API_KEY and HOLIDAY_CACHE_DAYS env variables
- Support 38 countries via Google Calendar holiday calendars
- Update HolidayService methods to async with database caching
- Update all TRPC handlers for async holiday methods
- Fix UI to display holiday dates correctly
- Remove static holidays.json and generate script
* use we instead of calcom in i18n message
* address cubics comments
* move holidays from availability to ooo
* public holidays filter for holidays
* follow i18n _one and _other pattern
* remove holiday feature flag
* revert lint command code change
* revert lint command code change 2.0
* revert lint command code change 3.0
* bye bye my christmas emoji :crying-emoji
* remove comments
* refactor(holidays): add repository pattern, split services, and add tests
- Create HolidayRepository for database operations
- Split GoogleHolidayService into GoogleCalendarClient and HolidayCacheService
- Add dependency injection to HolidayService and HolidayCacheService
- Update TRPC handlers to use HolidayRepository
- Add tests for HolidayRepository and calculateHolidayBlockedDates
- Update calendar IDs to use official holiday format (244 countries + religions)
* fix: address PR review feedback
- Remove unused date-holidays package
- Add pluralization for and_more_holidays_with_conflicts translation
- DRY: spread GOOGLE_RELIGIOUS_HOLIDAY_CALENDARS into GOOGLE_HOLIDAY_CALENDARS
- Add select to userHolidaySettings query in getUserAvailability
- Optimize checkConflicts with pre-computed timestamps
* refactor(holidays): apply proxy pattern and move logic to service
- Rename HolidayCacheService to HolidayServiceCachingProxy (proxy pattern)
- Remove HOLIDAY_CACHE_DAYS env var, use constant directly
- Add isSupportedCountry() method to HolidayService
- Add getUserSettings() and updateSettings() to HolidayService
- Move toggleHoliday logic from handler to service
- Move checkConflicts logic from handler to service
- Add findBookingsInDateRanges() to HolidayRepository
- Simplify all handlers to just call service methods
* feat(bookings): add backend validation to prevent booking on holidays
Adds explicit holiday conflict validation during booking creation to
handle the race condition where a host enables a holiday after a guest
selects a date but before they submit the booking.
Changes:
- Add checkHolidayConflict validation with HolidayRepository integration
- Integrate ensureNoHolidayConflict in RegularBookingService
- Add BookingOnHoliday error code with proper HTTP 400 response
- Handle holiday error display in BookEventForm with name interpolation
- Hide trace ID for expected validation errors
- Add unit tests for holiday conflict validation
* fix failing type check
* fix: address PR review comments for holiday feature
- Change error code from BAD_REQUEST to INTERNAL_SERVER_ERROR in
toggleHoliday handler (errors are internal failures, not bad input)
- Refactor ensureNoHolidayConflict to use Promise.all for parallel
user checking instead of sequential loop
* refactor: use Promise.all with logging in loop for holiday check
- Check all users in parallel using Promise.all
- Log conflicts inside the loop as they are detected
- Wait for all checks to complete before throwing error
* fix(holidays): use host timezone for holiday conflict checks
The holiday feature was checking booking dates against holidays using
server/local timezone instead of the host's timezone. This caused
bookings near midnight boundaries to incorrectly pass or fail the
holiday check.
Example: A booking at Dec 24th 8PM UTC (which is Dec 25th in IST)
was not being blocked for an Indian host with Christmas as a holiday.
Changes:
- Add .utc() to holiday date formatting for consistency
- Fetch host's timezone in checkHolidayConflict
- Convert booking time to host's timezone before comparison
- Add findUserSettingsWithTimezone to HolidayRepository
- Update error message to clarify it's the host's local time
- Add timezone edge case tests
* fix(holidays): align holiday blocking with OOO pattern for consistent timezone handling
- Simplify calculateHolidayBlockedDates to match OOO pattern using dayjs.utc()
- Fix date range query to use full day bounds (startOfDay/endOfDay) so holidays
stored at midnight UTC are correctly found during booking validation
- Remove separate checkHolidayConflict booking-time validation - holidays now
block through oooExcludedDateRanges like OOO does
- Remove getHolidayOnDate from HolidayService (no longer needed)
- Remove findUserSettingsWithTimezone from HolidayRepository (no longer needed)
- Clean up related tests
Holiday blocking now works exactly like OOO:
1. Holidays are added to datesOutOfOffice in calculateHolidayBlockedDates
2. buildDateRanges processes them via processOOO with .tz(timeZone, true)
3. oooExcludedDateRanges excludes those dates from availability
4. ensureAvailableUsers uses oooExcludedDateRanges to block bookings
This ensures consistent timezone handling where Dec 25th blocks all hours
of Dec 25th in the host's timezone, regardless of booker's timezone.
* update test
* update .env.example file
* feat: ooo message on booking page
* make ooo days selectable even when no redirect booking
* handle long notes
* remove unused i18n key
* Private notes stay private on the server, No accidental data leaks through client-side payloads
* address cubics comments
* fix: replace toggle with checkbox for OOO note visibility
- Replace Switch with Checkbox for "show note publicly" option
- Remove "OOO Message:" prefix from displayed notes on booking page
- Update i18n text to "Show note on public booking page"
- Remove unused ooo_message i18n key
* fix the accessibility issue by using proper htmlFor and id association
* only allow selecting OOO dates when the note is public
* move SystemField to features
* migrate workflow service
* merge two tests for team repository
* update imports and migrate team repository
* migrate delegation credential repository
* migrate credential repository
* migrate entityPermissionUtils
* migrate hashedLink service and repository
* migrate membership service
* update imports
* remove file
* migrate buildEventUrlFromBooking
* migrate getAllUserBookings to features
* update imports
* update organizationMock
* migrate slots
* migrate date-ranges to schedules dir
* migrate getAggregatedAvailability
* fix
* refactor
* migrate useCreateEventType hook to features
* migrate assignValueToUser
* migrate validateUsername to auth features
* migrate system field back to lib
* migrate getLabelValueMapFromResponses back to lib
* update imports
* use relative path
* fix type checks
* fix
* fix
* fix tests
* update gh codeowners
* fix
* fix