* fix: remove IS_PRODUCTION gate from BookingAuditProducer
Remove the IS_PRODUCTION check that was preventing booking audits from
being queued in production. Audits are still properly gated by:
1. Organization check: Audits are skipped for non-organization bookings
(organizationId === null)
2. Feature flag: The BookingAuditTaskConsumer checks if the 'booking-audit'
feature is enabled for the organization via featuresRepository.checkIfTeamHasFeature()
The IS_PRODUCTION gate was intentionally added to prevent logs from being
created in production while the action data versioning was being actively
reviewed and finalized. Without proper versioning handling, the Booking
History UI could crash when encountering unversioned data. Now that the
versioning system is in place, this gate can be safely removed.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: revert formatting, keep only IS_PRODUCTION removal
Reverts the unintended formatting changes from the previous commit.
Only removes the IS_PRODUCTION gate without changing indentation.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: add booking-audit feature flag check in producer to avoid unnecessary task creation
- Query booking-audit and booking-email-sms-tasker flags in parallel before fireBookingEvents
- Pass isBookingAuditEnabled through BookingEventHandler to producer's queueTask method
- Add conditional check in queueTask with debug log when skipping audit
- Reuse pre-queried isBookingEmailSmsTaskerEnabled flag instead of querying again
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: make isBookingAuditEnabled required and pass it through all booking audit flows
- Make isBookingAuditEnabled a required property in BookingAuditProducerService interface
- Update all BookingEventHandler methods to require isBookingAuditEnabled
- Add feature flag check in all flows that call booking audit:
- handleSeats (seat booking/rescheduling)
- RecurringBookingService (bulk bookings)
- handleCancelBooking (booking cancellation)
- handleConfirmation (booking acceptance)
- roundRobinReassignment (automatic reassignment)
- roundRobinManualReassignment (manual reassignment)
- trpc handlers: addGuests, confirm, editLocation, requestReschedule
- Skip queueing audit tasks when feature is disabled with debug logging
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: add featuresRepository dependency to RecurringBookingService DI module
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: make isBookingAuditEnabled optional for non-main flows
Keep feature flag check only in main flows (handleSeats, RegularBookingService, RecurringBookingService) which are frequently triggered. For other flows (handleCancelBooking, handleConfirmation, roundRobinReassignment, etc.), rely on the existing consumer-level check.
Changes:
- Revert feature flag check from non-main flows
- Make isBookingAuditEnabled optional in interface for non-main flow methods
- Keep isBookingAuditEnabled required for main flow methods (queueCreatedAudit, queueRescheduledAudit, queueSeatBookedAudit, queueSeatRescheduledAudit, queueBulkCreatedAudit, queueBulkRescheduledAudit)
- Update BookingEventHandlerService to use required params for main flows and optional for non-main flows
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: remove isBookingAuditEnabled from non-main flow methods
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: make isBookingAuditEnabled required in all BookingEventHandlerService methods
- Add isBookingAuditEnabled as required parameter in all BookingAuditProducerService interface methods
- Update BookingAuditTaskerProducerService to use simplified check (!params.isBookingAuditEnabled)
- Update BookingEventHandlerService to require isBookingAuditEnabled in all methods
- Update all callers to query booking-audit feature flag and pass isBookingAuditEnabled:
- handleCancelBooking
- handleConfirmation
- roundRobinReassignment
- roundRobinManualReassignment
- addGuests.handler
- confirm.handler
- editLocation.handler
- requestReschedule.handler
- Inject featuresRepository in API V2's booking-location.service.ts
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* test: update roundRobinReassignment tests to include isBookingAuditEnabled
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* test: update roundRobinManualReassignment tests to include isBookingAuditEnabled
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: inject featuresRepository in API V2 RecurringBookingService
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: import PrismaWorkerModule for PrismaFeaturesRepository dependency
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: use booking's organization for feature flag check in addGuests handler
Use booking.user?.profiles?.[0]?.organizationId instead of user.organizationId
to check the booking-audit feature flag. This ensures the feature flag is
checked against the booking's organization rather than the actor's organization,
which is consistent with other handlers in this PR.
Addresses Cubic AI review feedback (confidence 9/10).
Co-Authored-By: unknown <>
* Add comment
* fix: use user.organizationId for feature flag check in addGuests handler
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: use booking's organizationId for feature flag check in addGuests handler
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: revert to user.organizationId for feature flag check in addGuests handler
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: add isBookingAuditEnabled to onNoShowUpdated calls after main merge
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: add isBookingAuditEnabled to onNoShowUpdated calls and update tests
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: prevent 500 error when deleting calendar events with empty uid
This fix addresses a 500 error that occurs when trying to delete a Google
Calendar event with an empty event ID, which results in a malformed API URL.
Root cause: When calendar event creation fails or returns without an ID,
booking references were being created with empty uids. Later, when trying
to delete these events (e.g., during reschedule), the empty uid caused
a 404 from Google Calendar API which was then thrown as a 500 error.
Changes:
1. CalendarManager.deleteEvent: Added validation to skip deletion if
bookingRefUid is empty, with appropriate error logging. This is a
safety net for existing bad data in the database.
2. EventManager.create: Added filtering to exclude booking references
with empty uids from being stored, with error logging to help
diagnose the root cause of missing event IDs.
3. EventManager.updateLocation: Same filtering applied for consistency.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: revert EventManager filtering to preserve existing behavior
The test expects that booking references with empty uids are still created
when calendar event creation fails. This is intentional behavior to track
failed calendar syncs. The CalendarManager.deleteEvent fix handles the
deletion case gracefully by skipping the API call when uid is empty.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: throw ErrorWithCode instead of silently returning when bookingRefUid is empty
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: validate uid before calling calendar.deleteEvent to prevent 500 error
- Add uid check in lastAttendeeDeleteBooking.ts before calling calendar.deleteEvent
- Add uid check in EventManager.updateAllCalendarEvents before calling calendar.deleteEvent
- Revert CalendarManager.deleteEvent changes (validation at call sites is the proper fix)
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: add error logging safeguard in CalendarManager.deleteEvent for empty bookingRefUid
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: move bookingRefUid check before getCalendar call
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: prevent storing booking references with empty uid when calendar event creation fails
Root cause fix: Change the check from 'if (createdEvent)' to 'if (createdEvent.createdEvent)'
in createAllCalendarEvents to prevent failed calendar events from being added to results.
This prevents empty uids from being stored in the database in the first place, which
was causing 500 errors when trying to delete non-existent calendar events later.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* test: update test to expect no calendar reference when calendar event creation fails
The root cause fix changes behavior so that failed calendar events no longer
create booking references with empty uids. This test now expects an empty
references array when calendar event creation fails, which is the correct
behavior that prevents 500 errors later when trying to delete non-existent
calendar events.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* refactor: use createdEvent.success instead of createdEvent.createdEvent
Using success is more semantically clear since it explicitly checks the
success status rather than checking if the nested object exists.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* refactor: use optional chaining for createdEvent?.success
Using optional chaining is safer in case createdEvent is somehow undefined.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* revert: remove root cause fix to preserve backfilling script compatibility
The root cause fix (checking createdEvent?.success instead of createdEvent)
would break the backfilling script that relies on booking references with
empty uids to identify which bookings need backfilling.
This PR now only includes defensive checks to prevent 500 errors when
deleting calendar events with empty uids.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* revert
* fix
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 08:42:14 -03:00
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor: move repositories from lib to features domain folders
- Move HolidayRepository to features/holidays/repositories
- Move PrismaTrackingRepository to features/bookings/repositories
- Move PrismaBookingPaymentRepository to features/bookings/repositories
- Move PrismaRoutingFormResponseRepository to features/routing-forms/repositories
- Move PrismaAssignmentReasonRepository to features/assignment-reason/repositories
- Move VerificationTokenRepository to features/auth/repositories
- Move WorkspacePlatformRepository to features/workspace-platform/repositories
- Move DTO files to their respective feature domains
- Merge lib DestinationCalendarRepository into features version
- Merge lib SelectedCalendarRepository into features version
- Update all import paths across the codebase
This follows the vertical slice architecture pattern by organizing
repositories by domain rather than by technical layer.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: update VerificationTokenService import path to new location
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: update test file imports to use new repository locations
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* mv
* fix structure
* fix
* refactor: merge unit tests for SelectedCalendarRepository into single file
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 08:41:04 -03:00
Rajiv SahalGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: disable save button when workflow has no changes
* test: wait for save button to be enabled before clicking
* test: ensure input value is set before pressing Enter
* test fix
* fix: add shouldDirty to enable save button on name change
* test: clean up workflow test fixtures
* fix: disable save button when workflow has no changes
* test: update workflow E2E tests
* test: fix workflow E2E
* fix: enable save button when workflow form fields change
* fix tests
* fix: disable save button when workflow has no changes
* remove comments
* chore: improve fixture logic
* cleanup: remove unnecessary changes
* update workflow fixture to handle team workflow creation
---------
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Rajiv Sahal <sahalrajiv-extc@atharvacoe.ac.in>
Co-authored-by: Romit <romitgabani@icloud.com>
Co-authored-by: Romit <romitgabani1.work@gmail.com>
Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com>
* fix: broken style on availability delete button
* fix/final
2026-02-09 08:49:37 +00:00
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* test: add E2E tests for assignAllTeamMembers with attribute segment filters
Cover all 4 attribute types (SINGLE_SELECT, MULTI_SELECT, TEXT, NUMBER)
with booking flow verification plus edge cases (no match, all match).
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: use auto-retrying assertion for no-match edge case test
Replace flaky waitForTimeout(2000) + count check with Playwright's
toHaveCount(0, { timeout: 15000 }) which retries until availability
settles, preventing CI timing issues.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* test: add exclusion tests for members without attribute assigned
Add 4 new E2E tests covering the case where team members have no
attribute assigned at all (not just a different value). Each attribute
type (SINGLE_SELECT, MULTI_SELECT, TEXT, NUMBER) is tested to verify
that members without the attribute are excluded from the booking pool.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* test: add negation operator tests and restructure exclusion tests
- Restructure 'Members without attribute assigned' tests: assign
matching attribute to teammate-1 (not owner) so round-robin can't
coincidentally pass when the bug exists
- Add 4 negation operator tests (select_not_any_in, multiselect_not_some_in,
not_equal for TEXT and NUMBER) that verify unassigned members should
match negation filters. Marked with test.fail() as they confirm a
known bug where getLogicResultForAllMembers skips members without
attribute assignments entirely.
- Add edge case: no members have attribute assigned -> no available slots
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* test: remove test.fail() markers from negation tests after bug fix
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-09 14:07:49 +05:30
Joe Au-YeungGitHubjoe@cal.com <j.auyeung419@gmail.com>joe@cal.com <j.auyeung419@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: add comprehensive E2E tests for routing form attribute conditions
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: assert routedTeamMemberIds in URL instead of email in results
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: assert both routedTeamMemberIds in URL and email in results
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: include users without attribute assignments in exclusion condition evaluation
Users with no attribute assigned were excluded from the team members list
entirely, causing exclusion operators (not_equals, not_some_in, not_like,
not_between, etc.) to never match them. Now getAttributesAssignmentData
includes all team members, even those without attribute assignments.
Also adds unit tests and E2E tests for this scenario.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* fix: update getAttributes test to reflect new behavior for empty attributes
Users without attribute assignments are now included with empty attributes
so exclusion operators can match them. Updated test expectation accordingly.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* refactor: remove redundant usersWithAssignments code (fix already in _prepareAssignmentData from main)
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: defer email validation to after first blur on signup form
Change react-hook-form validation mode from "onChange" to "onTouched"
so that the "Invalid email" error only appears after the user has
interacted with the field and moved away, not on every keystroke.
Password strength hints still update in real-time since onTouched
validates on change after the field has been touched (blurred once).
Fixes#19163
* test: add unit tests for signup email validation mode
Verify the onTouched form validation behavior:
- No error shown while user is typing
- Error appears only after blur with invalid email
- No error for valid email after blur
- Revalidation on each keystroke after first blur
* remove eslint comment
---------
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Add aria-label to the TimeFormatToggle and LayoutToggle components
on the booking page so screen readers can identify these radio groups.
Uses existing translation keys "time_format" and "layout".
Fixes#20703
2026-02-09 06:13:27 +00:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Remove unused attendeeIds field and unnecessary prisma.booking.findUnique from beforeEach
- Store booking.id in testData to avoid re-querying booking in test body
- Track additional attendee emails via additionalAttendeeEmails array for proper afterEach cleanup
- Remove fragile prisma.attendee.delete (throws P2025 on missing record) from test body
- Use deleteMany-based cleanupTestData for second attendee cleanup instead
The test was flaky because:
1. It used prisma.attendee.delete (singular) which throws if record is already gone
2. It re-queried the booking via findUnique mid-test which could fail if cascade-deleted
3. The second attendee email was not tracked in afterEach cleanup
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: prevent textarea resize overlapping buttons in rejection dialog
The rejection reason textarea in the booking rejection dialog allows
manual resizing via the drag handle, which can cause it to expand over
the dialog footer buttons. Adding resize-none prevents this overlap.
Fixes#17536
* Update RejectionReasonDialog.tsx
---------
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
* fix(booking): make provider label and location link visible on mobile
* correct order
* remove comments
---------
Co-authored-by: Sahitya Chandra <sahityajb@gmail.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
* fix: resolve organizer default conferencing app credential for location update
- Fix Google Meet credential lookup in EventManager to properly map 'google:meet' to 'google_video' type
- Add automatic credential ID resolution when selecting 'Organizer Default App' as location
- Fixes 'Location update failed' error when editing round-robin team event location to organizer default app (Google Meet) with multiple Google Calendar connections
Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>
* fix update
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Fix exclusion filter - include all team members
* Fix display when members aren't saved in the DB
* Update tests
* Use integration tests for findTeamMembersMatchingAttributeLogic for better behaviour testing
* Add test that verifies that it was working earlier and broken in b/w and not working again
* Revert changes to AddMembersWithSwitch.tsx
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
---------
Co-authored-by: Joe Au-Yeung <j.auyeung419@gmail.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 12:48:48 -05:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>eunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ui): change phone booking display from Organizer Phone Number to Phone Call
The label \"Organizer Phone Number\" was confusing for attendees on the
booking page, as it exposed internal terminology. Replaced with the
more user-friendly \"Phone Call\" label across the booking UI, companion
app, and test assertions.
Closes#13010
* fix: remove duplicate phone_call i18n key
The phone_call key already existed in en/common.json (line 1685,
Cal.ai Voice Agent section). Removed the duplicate entry we added.
Found by ai-codex review.
2026-02-06 15:28:38 +00:00
Benny JooGitHubbenny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>benny@cal.com <sldisek783@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: use LOGO constant for generic OG image instead of hardcoded value
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* test: add unit tests for OgImages module
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: remove unused LOGO import from OgImages test
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix
* test: update OgImages tests to reflect LOGO_DARK constant
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* add comment
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-06 14:19:00 +00:00
Peer RichelsenGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* Revert "Revert "feat: redesign team creation flow to match onboarding-v3 design (#26733)""
This re-applies the team creation redesign from PR #26733 which was
previously reverted. Cherry-picked from 2540423ba3.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: check org/username slug when in org context
* fix: use expect(page).toHaveURL() instead of page.waitForURL() in team e2e test
Co-Authored-By: unknown <>
* fix: redirect URL
* fix: flag import
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(companion): add upcoming bookings widget for iOS and Android
- Add iOS widget using @bacons/apple-targets with SwiftUI
- Add Android widget using react-native-android-widget
- Configure App Groups for iOS data sharing between app and widget
- Create widget sync hook to update widget data when bookings change
- Widget displays up to 5 upcoming bookings with title, time, and attendee
- Widget refreshes every 15 minutes and when app goes to background
Co-Authored-By: peer@cal.com <peer@cal.com>
* fix(companion): refactor useWidgetSync to avoid React Compiler limitation
Move conditional logic outside of try/catch block to fix React Compiler
error: 'Support value blocks (conditional, logical, optional chaining,
etc) within a try/catch statement'
Co-Authored-By: peer@cal.com <peer@cal.com>
* fix(companion): fix widget data sync issues
- Fix Swift widget to read data as JSON string (format used by react-native-shared-group-preferences)
- Add fallback to read as raw Data for compatibility
- Fix query key mismatch by checking multiple common filter combinations
- Ensure widget finds cached bookings regardless of which filter the app used
Co-Authored-By: peer@cal.com <peer@cal.com>
* fix(companion): use ExtensionStorage from @bacons/apple-targets for widget data
- Replace react-native-shared-group-preferences with ExtensionStorage
- ExtensionStorage properly stores data in iOS App Groups
- Add ExtensionStorage.reloadWidget() call to trigger widget refresh
- This ensures the widget picks up new data immediately
Co-Authored-By: peer@cal.com <peer@cal.com>
* feat(companion): add upcoming bookings widget for ios - all shapes (#27564)
* ios working widget
* fix(companion): remove sensitive data logging from widget storage
Remove console.log statements that were logging full widgetData payload
and formatted widget bookings containing attendee names and booking
details. This addresses security concerns identified by Cubic AI review
(confidence 9/10).
Co-Authored-By: unknown <>
* dark mode
* new look
* fix deeplink
* fix biome lint
* fix(companion): remove booking titles from console logs to avoid PII exposure
Co-Authored-By: unknown <>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* lock the versions and dev mode logging
* remove dynamic imports
* feat(companion): upcoming bookings widget android (#27689)
* companion-upcoming-bookings-widget-android
* fix(companion): remove stale relative countdowns and fix past-time clamping in Android widget
- Remove relative countdown text (In 15m, In 1h, Now) that becomes stale
due to Android widget 30+ min update interval (Cubic violation 2)
- Remove Math.max(0, minutes) clamping that caused ended meetings to
display as 'Now' indefinitely (Cubic violation 1)
- Simplify accent color logic to use startTimeISO directly
- Keep absolute time display (date + startTime) which remains accurate
Co-Authored-By: unknown <>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil <dhairyashil10101010@gmail.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
Co-authored-by: Volnei Munhoz <volnei@cal.com>
* fix: event not created
* Update CalendarManager.ts
* Add tests: packages/features/calendars/lib/CalendarManager.ts
Generated by Paragon from proposal for PR #27675
* Add tests: packages/features/calendars/lib/CalendarManager.test.ts
Generated by Paragon from proposal for PR #27675
* Export processEvent for testing and refactor logic
* Fix missing newline at end of CalendarManager.test.ts
Add missing newline at the end of the file.
* fix test
2026-02-06 12:28:22 +00:00
Peer RichelsenGitHubhariom@cal.com <hariombalhara@gmail.com>hariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Hariom Balhara
* refactor: simplify link-as-an-app template to config.json only
- Remove api/, components/, index.ts, package.json from link-as-an-app template
- Add externalLink field to AppMetaSchema for external URL configuration
- Update API handler to dynamically create handlers for external link apps
- External link apps no longer create credentials (just redirect to URL)
- Update CLI to handle externalLinkUrl field for link-as-an-app template
- CLI now skips package.json update for apps without package.json
Co-Authored-By: peer@cal.com <peer@cal.com>
* fix: simplify external link handler to bypass credential creation
External link apps now directly return the redirect URL without going
through the AppDeclarativeHandler type, avoiding type conflicts with
the createCredential return type requirement.
Co-Authored-By: peer@cal.com <peer@cal.com>
* refactor: migrate 24 external link apps to simplified structure
Migrated the following apps to use config.json with externalLink field
instead of api/add.ts handlers:
- amie, autocheckin, baa-for-hipaa, bolna, chatbase, clic, cron, deel
- elevenlabs, fonio-ai, framer, granola, greetmate-ai, lindy, millis-ai
- monobot, n8n, pipedream, raycast, retell-ai, synthflow, telli, vimcal
- wordpress
Each app now only contains: config.json, DESCRIPTION.md, static/
Removed: api/, components/, index.ts, package.json
Co-Authored-By: peer@cal.com <peer@cal.com>
* nit
* Fix merge conflict issue
* refactor: generate REDIRECT_APPS dynamically during app-store build
- Add logic to build.ts to detect apps with externalLink field
- Generate redirect-apps.generated.ts with list of redirect app slugs
- Update redirectApps.ts to import from generated file
- Revert [...]args].ts to original state (Flow 1 is preferred)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: cast REDIRECT_APPS to readonly string[] for includes check
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Fix error with React
* Take exteral link URL as input
* deleted bun.lockb
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-02-06 12:28:11 +00:00
Hariom BalharaGitHubhariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* chore: Integrate mark-no-show booking audit
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Simplify host no-show audit and add comment for attendee actor
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Make actionSource required with ValidActionSource type and remove unnecessary comments
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Remove merge conflict markers from bookings.service.ts
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: implement SYSTEM as a booking audit source for background tasks, including no-show triggers.
* refactor: Move prisma query to BookingRepository for audit logging
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Conflict resolution
* refactor: introduce `handleMarkHostNoShow` for public viewer and standardize actor and action source parameters for no-show actions.
* refactor: Combine HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService into NoShowUpdatedActionService
- Create new NoShowUpdatedAuditActionService with combined schema supporting both noShowHost and noShowAttendee as optional fields
- Update BookingAuditActionServiceRegistry to use combined service with NO_SHOW_UPDATED action type
- Update BookingAuditTaskerProducerService with single queueNoShowUpdatedAudit method
- Update BookingAuditProducerService.interface.ts with combined method
- Update BookingEventHandlerService with single onNoShowUpdated method
- Update handleMarkNoShow.ts to use combined audit service
- Update tasker tasks (triggerGuestNoShow, triggerHostNoShow) to use combined service
- Add NO_SHOW_UPDATED to Prisma BookingAuditAction enum
- Remove old separate HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService files
This allows a single API action (e.g., API V2 markAbsent) that updates both host and attendee no-show status to be logged as a single audit event.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* chore: Add migration for NO_SHOW_UPDATED audit action enum value
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Update no-show audit schema to use host and attendees array
- Rename noShowHost to host and noShowAttendee to attendees (remove redundant prefix)
- Change attendees from single value to array to support multiple attendees in single audit entry
- Update handleMarkNoShow.ts to create single audit entry for all attendees
- Update tasker tasks (triggerGuestNoShow, triggerHostNoShow) to use new schema
- Update display data types to reflect new schema structure
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Update schema to be more clear. Call onNoShowUpdated immediately after DB update as audit only cares about DB update, and this would avoid any accidental Audit update on DB change
* chore: accommodate schema changes and fix type errors for no-show audit
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update migration to remove old no-show enum values
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Use updated attendees in webhook payload for guest no-show
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Remove duplicate imports and fix actor parameter in bookings.service.ts
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Move booking query to BookingRepository and remove unused method
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: centralize no-show audit event firing and attendee fetching within `handleMarkNoShow` for improved clarity.
* fix: Build attendeesNoShow as Record with attendee IDs as keys
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Fix and add tests for handleMarkBoShow
* refactor: Move prisma queries to AttendeeRepository and BookingRepository
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Correct return type for updateNoShow method (noShow can be null)
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update handleMarkNoShow tests to mock new repository methods
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix triggerGuestNoShow
* refactor: Move triggerGuestNoShow queries to AttendeeRepository and add unit tests
- Add new methods to AttendeeRepository:
- findByBookingId: Get attendees with id, email, noShow
- findByBookingIdWithDetails: Get full attendee details
- updateManyNoShowByBookingIdAndEmails: Update specific attendees
- updateManyNoShowByBookingIdExcludingEmails: Update all except specific emails
- Refactor triggerGuestNoShow.ts to use AttendeeRepository instead of direct Prisma calls
- Add comprehensive unit tests for triggerGuestNoShow following handleMarkNoShow.test.ts pattern:
- Mock repositories and external services
- In-memory DB simulation
- Test core functionality, audit logging, webhook payload, error handling, and edge cases
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Move triggerHostNoShow queries to repositories and delete unit test file
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Convert repository methods to use named parameters objects
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Enhance no-show handling by consolidating audit logging and updating repository interactions
- Refactor `buildResultPayload` to accept a structured argument for better clarity.
- Update `updateAttendees` to use a named parameter object for improved readability.
- Introduce `fireNoShowUpdatedEvent` to centralize no-show audit logging for both hosts and guests.
- Remove redundant methods and streamline attendee retrieval in `AttendeeRepository`.
- Add comprehensive unit tests for no-show event handling, ensuring accurate audit logging and webhook triggering.
* test: Add tests for handleMarkHostNoShow guest actor and unmarking host no-show
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: update attendeesNoShow validation to handle numeric keys
- Changed attendeesNoShow schema to use z.coerce.number() for key validation, ensuring string keys are correctly coerced to numbers.
- Updated test to validate attendeesNoShow data using numeric key comparison, improving robustness of the audit data checks.
* test: Add integration tests for NoShowUpdatedAuditActionService coerce fix
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: add graceful error handling for audit log enrichment
- Add hasError field to EnrichedAuditLog type
- Create buildFallbackAuditLog() method for failed enrichments
- Wrap enrichAuditLog() in try-catch to handle errors gracefully
- Add booking_audit_action.error_processing translation key
- Update BookingHistory.tsx to show warning icon for error logs
- Hide 'Show details' button for logs with hasError
- Add comprehensive test cases for error handling scenarios
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* feat: Enhance booking audit action services with new display fields and improved validation
- Added "attendee_no_show_updated" and "no_show_updated" translations to common.json.
- Updated IAuditActionService to include new methods for handling display fields and migration.
- Enhanced NoShowUpdatedAuditActionService to differentiate between host and attendee no-show updates.
- Improved ReassignmentAuditActionService to ensure consistent handling of audit data.
- Refactored BookingAuditViewerService for better clarity and maintainability.
* refactor: Use attendeeEmail instead of attendeeId as key in audit data and store host's userUuid
- Updated schema to use attendee email as key instead of attendee ID because attendee records can be reused with different person's data
- Store host's userUuid in audit data with format: host: { userUuid, noShow: { old, new } }
- Updated fireNoShowUpdated to accept hostUserUuid parameter
- Added uuid field to BookingRepository.findByUidIncludeEventTypeAttendeesAndUser
- Updated NoShowUpdatedAuditActionService getDisplayFields to work with email-based keys
- Added attendeeRepository to DI modules for BookingAuditTaskConsumer
- Updated tests to match new schema format
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* test: Update integration tests to use new schema format with host.userUuid and email keys
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: correct audit schema for SYSTEM source and ensure attendee lookup by bookingId
- Fix schema inconsistency: use host.userUuid format instead of hostNoShow
- Add user.uuid to getBooking select for audit logging
- Log warning when hostUserUuid is undefined but host no-show is being updated
- Use email as key for attendeesNoShow (not attendee ID) to match schema
- Fetch attendees by bookingId before updating to ensure correct scoping
- Remove unused safeStringify import
* refactor: Change attendeesNoShow schema from Record to Array format
- Update NoShowUpdatedAuditActionService schema to use array format:
attendeesNoShow: Array<{attendeeEmail: string, noShow: {old, new}}>
- Update handleMarkNoShow.ts to build attendeesNoShow as array
- Update common.ts fireNoShowUpdatedEvent to convert Map to array
- Update all tests to use new array format with attendeeEmail property
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Update attendeesNoShow schema to use array format in triggerNoShow tasks
- Refactor `triggerGuestNoShow` and `triggerHostNoShow` to replace Map with array for `attendeesNoShowAudit`.
- Update `fireNoShowUpdatedEvent` to handle the new array format for attendees.
- Ensure consistent data structure across no-show audit logging for better clarity and maintainability.
* fix: Update ReassignmentAuditActionService to use GetDisplayFieldsParams interface
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update ReassignmentAuditActionService tests to use GetDisplayFieldsParams interface
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Use handleMarkAttendeeNoShow for API v2 mark absent endpoint
- Export handleMarkAttendeeNoShow from platform-libraries
- Update API v2 bookings service to use handleMarkAttendeeNoShow with actionSource
- Add validation for userUuid before calling handleMarkAttendeeNoShow
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Enhance display fields structure in booking audit components
- Updated `BookingHistory.tsx` to allow for more flexible display fields, including optional raw values and arrays of values.
- Introduced `DisplayFieldValue` component for rendering display fields, improving clarity and maintainability.
- Adjusted `IAuditActionService` and `NoShowUpdatedAuditActionService` to align with the new display fields structure.
- Ensured consistent handling of display fields across the booking audit service for better data representation.
* fix: Remove debug code that duplicated first attendee in display fields
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Update attendee repository methods to use structured parameters
- Modified `updateNoShow`, `updateManyNoShowByBookingIdAndEmails`, and `updateManyNoShowByBookingIdExcludingEmails` methods to accept structured `where` and `data` parameters for better clarity and maintainability.
- Updated calls to these methods throughout the codebase to reflect the new parameter structure.
- Removed unused `findByIdWithNoShow` method and adjusted related logic to streamline attendee data retrieval.
* feat: Add infrastructure for no-show audit integration
- Add Prisma migrations for SYSTEM source and NO_SHOW_UPDATED audit action
- Add NoShowUpdatedAuditActionService with array-based attendeesNoShow schema
- Update BookingAuditActionServiceRegistry to include NO_SHOW_UPDATED
- Update BookingAuditTaskConsumer and BookingAuditViewerService
- Add AttendeeRepository methods for no-show queries
- Update IAuditActionService interface with values array support
- Update locales with no-show audit translation keys
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Add NO_SHOW_UPDATED to BookingAuditAction and SYSTEM to ActionSource types
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Remove HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED from BookingAuditAction type to match Prisma schema
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update BookingAuditActionSchema to use NO_SHOW_UPDATED instead of HOST_NO_SHOW_UPDATED and ATTENDEE_NO_SHOW_UPDATED
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Remove deprecated no-show audit services and unify to NoShowUpdatedAuditActionService
- Delete HostNoShowUpdatedAuditActionService and AttendeeNoShowUpdatedAuditActionService
- Update BookingAuditProducerService.interface.ts to use queueNoShowUpdatedAudit
- Update BookingAuditTaskerProducerService.ts to use queueNoShowUpdatedAudit
- Update BookingEventHandlerService.ts to use onNoShowUpdated
- Add integration tests for NoShowUpdatedAuditActionService
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update test mock to match new AttendeeRepository.updateNoShow signature
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: rename handleMarkAttendeeNoShow to handleMarkNoShow and update related types
- Renamed `handleMarkAttendeeNoShow` to `handleMarkNoShow` for clarity.
- Updated type definitions to reflect the new naming convention.
- Modified the `markNoShow` handler to require `userUuid` and adjusted related logic.
- Enhanced the `fireNoShowUpdatedEvent` to accommodate changes in event type structure.
- Updated references across various files to ensure consistency with the new function name.
* handle null value
* fix: add explicit parentheses for operator precedence clarity
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Fix cubic reported bug
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>