* fix: APIV2 team membership addition
* feat: Add trimming for email domain and orgAutoAcceptEmail in auto-accept logic
- Trim whitespace from both user email domain and orgAutoAcceptEmail
- Ensures consistent matching even with accidental whitespace
- Addresses feedback from PR review
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* simplify
* feat: Use shared OrganizationMembershipService in TRPC for consistent auto-accept logic
- Create OrganizationMembershipService.container.ts for DI in TRPC
- Update getOrgConnectionInfo to apply trimming + case-insensitive comparison
- Precompute auto-accept decisions in createNewUsersConnectToOrgIfExists using the service
- Use service in handleNewUsersInvites for consistent auto-accept determination
- Ensures both API v2 and TRPC paths use identical trimming and normalization logic
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Revert "feat: Use shared OrganizationMembershipService in TRPC for consistent auto-accept logic"
This reverts commit 0b2bd28b6e32e8c1d3dea139ca8ff9cbf402ac00.
* refactor: Unify OrganizationRepository and remove duplicate PrismaOrganizationRepository (#24869)
* refactor: Convert OrganizationRepository from static to instance methods
- Add constructor accepting deps object with prismaClient
- Convert all static methods to instance methods
- Add getOrganizationAutoAcceptSettings method
- Create singleton instance export in repository barrel file
- Update API v2 OrganizationsRepository to extend from OrganizationRepository
- Update all call sites to use singleton instance
- Add platform-libraries organizations.ts export
- Fix mock imports to use repository barrel
- Fix unsafe optional chaining in next-auth-options.ts
- Fix any types in test files with proper type inference
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update all imports to use OrganizationRepository barrel export
- Update imports from direct OrganizationRepository file to barrel export
- This ensures mocks work correctly in tests
- Fixes 202 failing tests related to organizationRepository mock
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update test mocks to use partial mock pattern
- Convert organizationMock to partial mock that preserves real class
- Add proper prisma mocks to failing test files
- Remove old OrganizationRepository mocks from test files
- This fixes test failures related to mock interception
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Export mocked singleton and update tests to use it directly
- Export mockedSingleton as organizationRepositoryMock from organizationMock
- Update delegationCredential.test.ts to import and use the exported mock
- This fixes 'vi.mocked(...).mockResolvedValue is not a function' errors
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Use platform-libraries import for API v2 OrganizationRepository
API v2 should import shared features through @calcom/platform-libraries
instead of directly from @calcom/features to maintain proper architectural
boundaries and packaging/licensing separation.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Implement DI pattern for OrganizationRepository
- Create OrganizationRepository.module.ts and .container.ts for DI
- Replace singleton pattern with getOrganizationRepository() across 20 files
- Update platform-libraries to export getOrganizationRepository
- Delete duplicate PrismaOrganizationRepository.ts
- Remove singleton export file (repositories/index.ts)
- Update test mocks to use DI container pattern
- All type checks and unit tests passing
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Implement read/write client separation in OrganizationRepository
- Updated OrganizationRepository constructor to accept optional prismaWriteClient parameter
- Routed all write operations (create, update) through prismaWrite client
- Routed all read operations (find, get) through prismaRead client
- Updated API v2 OrganizationsRepository to pass both dbRead.prisma and dbWrite.prisma to super()
- Optimized getOrganizationRepository() calls by storing in local variables to avoid repeated function calls
- This fixes the critical issue where API v2 was passing read-only client to base class with write methods
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Fix mock setup and optimize getOrganizationRepository() calls
- Fixed verify-email.test.ts mock to return mocked repository instance instead of scenario helper object
- Added mockReset to organizationMock.ts beforeEach to properly reset mock implementations between tests
- Added local variables in page.tsx to store getOrganizationRepository() result for consistency
This fixes the issue where getOrganizationRepository() was returning organizationScenarios.organizationRepository (scenario helper) instead of the actual mocked repository instance, causing findUniqueNonPlatformOrgsByMatchingAutoAcceptEmail to be undefined.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Simplify OrganizationRepository to use single prismaClient
- Updated base OrganizationRepository constructor to accept only { prismaClient } instead of { prismaClient, prismaWriteClient? }
- Replaced this.prismaRead and this.prismaWrite with single this.prismaClient property
- Updated API v2 OrganizationsRepository to pass only dbWrite.prisma as prismaClient
- Removed unused PrismaReadService import from API v2
- All read and write operations now use the same client instance
This simplifies the architecture as requested - API v2 uses write client for all operations, and apps/web uses the client from DI container.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: Match OrganizationsRepository.findById signature with base class
The findById method in OrganizationsRepository was using a different signature
than the base OrganizationRepository class, causing type errors in CI.
Changed from: findById(organizationId: number)
Changed to: findById({ id }: { id: number })
This matches the base class signature and resolves the CI unit test failures.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Update all findById call sites to use object parameter
Fixed 6 call sites in API v2 that were calling findById with a number
instead of the required { id: number } object parameter:
- is-org.guard.ts
- is-admin-api-enabled.guard.ts
- is-webhook-in-org.guard.ts
- organizations.service.ts
- managed-organizations.service.ts (2 call sites)
This resolves the API v2 build failure caused by the signature change
in OrganizationsRepository.findById to match the base class.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Remove redundant findById override from OrganizationsRepository
The findById method was duplicating the base class OrganizationRepository
implementation. Both methods had identical logic (filtering by isOrganization: true),
so the override was unnecessary.
Since OrganizationsRepository extends OrganizationRepository and passes
dbWrite.prisma to the base constructor, the base class method already
provides the exact same functionality.
This resolves the API v2 build failure by eliminating the duplicate method
that was causing conflicts.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Remove unncessary changes
* Store in variable
* Revert "Remove unncessary changes"
This reverts commit af9351786a21616c9508c441191c17f2374fb2cc.
* Revert dbRead/dbWrite changes
* Add organizations library to tsconfig.json
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Morgan <33722304+ThyMinimalDev@users.noreply.github.com>
## What does this PR do?
- Redesigns and streamlines the onboarding flow for personal, team, and organization accounts
- Consolidates shared components and improves code organization
- Adds browser preview for better user experience during onboarding
- Simplifies the personal onboarding flow by removing the video integration step
- Enhances team onboarding with CSV upload functionality
## Visual Demo (For contributors especially)
#### Image Demo:
- The PR adds a new browser preview component that shows users how their profile/team will look during onboarding
- Redesigned UI with a more consistent layout across all onboarding steps
- Improved mobile responsiveness with better component organization
## Mandatory Tasks (DO NOT REMOVE)
- [x] I have self-reviewed the code.
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.
## How should this be tested?
1. Test the complete onboarding flow for personal accounts:
- Start at `/onboarding/getting-started`
- Proceed through personal details and calendar setup
- Verify the flow completes successfully
2. Test the team onboarding flow:
- Start at `/onboarding/getting-started` and select team
- Complete team details
- Test the invite options including CSV upload
- Verify team creation works correctly
3. Test the organization onboarding flow:
- Start at `/onboarding/getting-started` and select organization
- Complete organization details and branding
- Test member invitations
- Verify organization creation works correctly
4. Verify browser preview functionality:
- Check that the preview updates in real-time as you enter information
- Confirm it displays correctly on different screen sizes
## Checklist
- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
* feat: Pbac decorator and guard
* feat: v2 roles endpoints
* fix: test
* fix: starting v2
* fix: test error
* fix: test api keys
* fix fixture
* test permission creation
* feat: permissions endpoints
* refactors
* refactor: project structure
* test: role permissions crud
* test: permissions endpoint negative tests
* docs: org, team permissions swagger
* unit tests for validator
* Update roles.guard.ts
* fix type
* test: error messages
* refactor: dont throw error in pbac
* delete redundant test file
* feedback: logging error
* fix: persist role.permissions when updating role.otherProperty
* refactor: use output service to return permissions
* refactor: service functions return current permissions
* refactor: remove OrganizationsRepository from providers
* refactor: try catch possibly duplicate create
* refactor: require min length name if provided
* refactor: org role has orgId and team role teamId
* fix: pbac guard caching
* fix: e2e tests in parallel
* refactor: use IsTeamInOrg guard for orgs teams roles and permissions endpoints
* refactor: use redis service getter and setter
* refactor: invalidate team permissions cache when permissions change
* refactor: delete keys instead of versioning when caching
* feat: improve overlapping events display in weekly calendar view
- Add cascading layout algorithm for overlapping events
- First event at 80% width, subsequent events offset by 8%
- Implement hover behavior to bring events to front (z-index 100)
- Extract overlap logic into reusable utility functions
- Add comprehensive unit tests for overlap detection and layout calculation
- Sort events by start time, then by duration for consistent rendering
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* feat: add weekly calendar playground page for testing overlapping events
- Create comprehensive playground page with 8 test scenarios
- Include two overlapping, three cascading, non-overlapping, same start time, chain overlaps, dense day, touching events, and mixed statuses
- Add focused view with scenario selector and grid view for side-by-side comparison
- Update playground index to include weekly calendar link
- Each scenario includes description, expected behavior, and collapsible event data
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* update base props
* remove unneccessary things
* fix: isolate Calendar store instances to prevent shared state
- Refactor useCalendarStore to use Zustand's createStore with React Context
- Each Calendar component now creates its own isolated store instance
- Maintains backward compatibility with global store fallback
- Fixes issue where multiple Calendar instances on same page shared state
This allows the playground page to render multiple Calendar instances
without state conflicts between them.
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* fix: prevent event overflow in dense overlap scenarios
- Dynamically compress offset step based on overlap group size
- Ensure leftOffset + width never exceeds 100% to prevent bleeding into next day
- Add width clamping as safety guard against rounding errors
- Add 3 new tests for overflow prevention with dense event scenarios
Fixes issue where 10+ overlapping events would cascade beyond day boundary
and bleed into the next day's column. The algorithm now calculates the
maximum safe step size per overlap group while maintaining visual cascade.
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* remove global store
* fix: comprehensive overflow prevention with safety margin and CSS fix
- Add safetyMarginPercent (0.5%) to prevent rounding and CSS box model overflow
- Implement floor3 rounding for width to guarantee left + width <= 100 - safetyMargin
- Calculate width from rounded left offset to avoid rounding mismatch
- Remove inset-x-1 class conflict that was setting both left and right positioning
- Change from marginLeft to left positioning for proper control
- Add test for 20+ overlapping events to verify no overflow
- Update existing tests to verify safety margin is respected
This fixes the slight overflow issue reported by the user where events were
still bleeding into adjacent day columns despite the initial dynamic step
compression fix. The root cause was a combination of:
1. CSS conflict: inset-x-1 class setting both left and right positioning
2. Rounding mismatch: width calculated from unrounded left offset
3. No safety margin for CSS box model effects (borders, padding)
All 21 tests now pass including new safety margin verification.
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* feat: update Dense Day scenario to 20+ events
- Increase from 11 to 21 overlapping events in Dense Day scenario
- Update title from '10+ Events' to '20+ Events'
- Add 10 more diverse events with staggered start times
- Better stress test for overflow prevention with safety margin
This provides a more comprehensive test case for the overflow prevention
fix and matches the user's request for 20+ events instead of 10+.
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* WIP
* feat: enhance event tooltip to show full event details
- Replace simple title-only tooltip with rich content tooltip
- Display event title, time range, description, and status
- Add color indicator matching the event's visual style
- Set min-width (200px) and max-width (300px) for better readability
- Use inverted theme colors for better contrast in tooltip
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* faster animation
* feat: position tooltip based on day of week
- Show tooltip on right side for Monday-Thursday (days 1-4)
- Show tooltip on left side for Friday-Sunday (days 5-0)
- Calculate day of week using dayjs from event start date
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* add margin for tooltip
* feat: add event duration layout test scenario
- Add new scenario with events of varying durations (3, 7, 15, 20, 30, 53 minutes)
- Test layout logic where eventDuration > 30 changes flex direction
- Events ≤30min show horizontal layout (title and time inline)
- Events >30min show vertical layout (title and time stacked)
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* update styles
* feat: add minimum height of 15px for events
- Ensure very short events (e.g., 3 minutes) are still visible
- Use CSS max() to apply minimum height while respecting duration-based height
- Prevents events from becoming too small to interact with
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* update playground
* do not mutate
* pre-compute some values
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Sean Brydon <sean@cal.com>
- Remove cal.cache query parameter parsing from booking and slots flows
- Set shouldServeCache to false for all booking availability checks
- Remove _shouldServeCache from schemas and type definitions
- Clean up all references in platform atoms and API endpoints
This ensures fresh Google Calendar data is always fetched for conflict checking,
preventing bookings when there are actual calendar conflicts.
* refactor: decouple @calcom/prisma from @calcom/features, @calcom/ee, and @calcom/lib
- Inline helper functions in zod-utils.ts (emailSchema, slugify, getValidRhfFieldName, isPasswordValid, intervalLimitsType, zodAttributesQueryValue)
- Update schema.prisma @zod.import comments to reference zod-utils instead of @calcom/lib
- Inline idempotency key generation in booking-idempotency-key extension using uuid v5
- Move usage-tracking extension to @calcom/ee/prisma-extensions/
- Remove usage-tracking extension from packages/prisma/index.ts
- Move Prisma DI module from @calcom/prisma to @calcom/features/di/modules/Prisma.ts
- Update 20 import paths in @calcom/features to use new Prisma DI module
- Remove @calcom/lib dependency from @calcom/prisma package.json
- Add uuid dependency to @calcom/prisma package.json
This reduces the dependency footprint of @calcom/prisma and breaks circular dependencies between packages.
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* feat: add EE-specific Prisma DI module with usage tracking
Create packages/ee/di/modules/PrismaEE.ts to apply the usage-tracking extension in EE contexts. This module:
- Imports the base prisma client from @calcom/prisma
- Applies the usageTrackingExtention from @calcom/ee/prisma-extensions/usage-tracking
- Exports the same DI tokens as the base Prisma module for override in EE containers
This ensures usage tracking functionality is preserved in EE builds while keeping the base @calcom/prisma package free of EE dependencies.
Note: EE containers should load this module after the base Prisma module to override the bindings.
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
## What does this PR do?
Adds a welcome modal for new organizations that appears after organization creation. The modal showcases key features of the Organizations plan and provides a better onboarding experience.
## Visual Demo (For contributors especially)
#### Image Demo:

## Mandatory Tasks (DO NOT REMOVE)
- [x] I have self-reviewed the code.
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works.
## How should this be tested?
1. Create a new organization through either:
- The onboarding flow
- The settings/organizations/new page
- The organization creation form
2. After successful creation and redirect, verify the welcome modal appears showing organization features.
3. Verify the modal can be closed by:
- Clicking the "Continue" button
- Clicking outside the modal
- Pressing ESC key
4. Verify the modal doesn't reappear after being closed (query param and session storage should be cleared).
## Checklist
- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
* Allow team admins to see hidden fields and UTM tracking data
- Add team admin permission check for booking data visibility
- Team admins can now view hidden booking field answers
- Team admins can now view UTM tracking parameters
- Support for managed events (parent team admins can view child event data)
- Maintain backward compatibility with existing host permissions
Fixes team admin access to booking details as requested in issue.
* feat: allow all team members to view hidden fields and UTM data
Previously only team admins could view hidden booking field answers and UTM tracking parameters. Now all team members can see this data, providing better transparency within teams.
- Changed from isTeamAdmin to isTeamMember check
- Team members (not just admins) can now view hidden booking fields
- Team members can now view UTM tracking parameters
- Maintains host permission (organizers can still see everything)
- Supports managed events (parent team members can view child event data)
* Address reviewer feedback: use existing membership pattern
- Remove custom checkIfUserIsTeamAdmin function
- Use existing userId_teamId pattern with prisma.membership.findUnique
- Revert PrismaPlugin and variable name changes
- Maintain same functionality with cleaner implementation
* fix: use existing isTeamAdmin function and remove unnecessary UI changes
* fix: Allow all team members to see hidden fields instead of just admins
- Replace isTeamAdmin with isTeamMember in booking view permissions
- Rename isLoggedInUserTeamAdmin to isLoggedInUserTeamMember for clarity
- All team members can now view hidden fields and UTM tracking data
Addresses feedback from @hariombalhara to allow all team members (not just admins) to see hidden booking data.
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: Correct import path for isTeamMember function
- Change import from non-existent @calcom/lib/server/queries/teams
- Use correct path @calcom/features/ee/teams/lib/queries
- Fixes type check error: Cannot find module
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: Optimize isTeamMember check to call function only once
- Extract teamId using nullish coalescing operator
- Single isTeamMember call instead of two
- Cleaner and more efficient logic
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* simplify
---------
Co-authored-by: naaa760 <neh6a683@gmail.com>
Co-authored-by: neha <neha@posthog.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-31 12:05:02 +00:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: implement booking calendar view with weekly layout
- Create reusable WeekCalendarView component that displays bookings in a weekly calendar format
- Replace EmptyScreen in BookingsCalendar with the new calendar view
- Calendar view includes:
- Week navigation with Today, Previous, and Next buttons
- 7-day week view with time slots from 12 AM to 11 PM
- Bookings displayed as colored blocks positioned by time
- Support for event type colors and status-based colors
- Responsive design that fills the viewport
- Hover tooltips showing booking details
- Filters remain functional at the top of the view
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* refactor: use existing Calendar component from weeklyview
- Replace custom calendar implementation with the existing Calendar component
- Use parseEventTypeColor to properly handle event type colors
- Simplify implementation by leveraging existing calendar infrastructure
- Maintain week navigation and filtering functionality
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* fix imports
* fix: replace isSameOrAfter with isAfter || isSame
- isSameOrAfter method does not exist in dayjs
- Use combination of isAfter and isSame instead
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* remove useBookerTime dependency from weekly calendar view
* modify date range filters
* initial callback
* sort events
* clean up FilterBar
* add showBackgroundPattern
* update styles
* update style
* update styles
* fix type error
* fix error
* update styles
* update styles
* update event colors
* rename component
* persist weekStart on the url
* use FilterBar
* apply feedback
* extract BorderColor type
* use client
* clean up
* adjust styles
* color-code events
* rename borderColor to color
* restore class name
* add feature flag
* update class name
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* chore: BookingHydrationService - generate calendarEvent without PII
* chore: wip add build calendarEvent from booking in CalEventBuilder
* chore: build calendar event from booking
* remove hydration service
* test: add comprehensive test for CalendarEventBuilder.fromBooking with all properties
- Add vi.mock() calls for external dependencies (getBookerBaseUrl, getTranslation, getCalEventResponses)
- Add comprehensive test 'should create a complete calendar event with all properties using a booking'
- Test covers team scheduling, video calls, seats/webinar, recurring events, custom fields, and all configuration flags
- Fix import paths in CalendarEventBuilder.ts to use @calcom/features prefix
- Fix timestamp format issues in existing tests to use toISOString()
- Fix destinationCalendar length expectations to account for user calendar
- Fix responses format in seats tests to match bookingResponsesSchema
Co-Authored-By: morgan@cal.com <morgan@cal.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-31 07:31:50 +00:00
Alex van AndelGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
When BOOKING_LOGGING_EVENT_IDS is set to an empty string, the current
implementation splits it into [''] and Number('') returns 0, causing
any event type with ID 0 to incorrectly trigger debug logging.
This fix:
- Filters out empty/invalid event IDs (NaN, <=0)
- Filters out empty usernames
- Only matches valid, positive event type IDs
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-30 19:32:17 +00:00
Rajiv SahalGitHubrajiv@cal.com <sahalrajiv6900@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor: move org admin related logic to org server
* fix: update cancellation logic to make sure org admin can cancel seated bookings of a team user
* fix: import path
* update bookings repository
* fix: update reschedule endpoint logic to let org admin reschedule bookings for a user
* refactor: make logic more simple
* chore: update platform libraries
* more refactors
* fix: add check to make sure org admin can reschedule booking
* chore: remove unused comments
* test: add e2e tests for org admin reschedule and cancel seated bookings
- Add seated event type creation for testing
- Add test for org admin rescheduling a seated booking for a managed user
- Add test for org admin canceling a full seated booking for a managed user
- Add test for org admin canceling a specific seat in a seated booking
These tests verify the functionality added in PR #24640 which allows
org admins to reschedule and cancel seated bookings for users in their
organization.
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
* chore: add cubic feedback
* fix: tests for seated booking management by org admin
* chore: implement PR feedback
* fixup
* chore: update docs
* fixup: get optional user from request and then pass it down to getBookingForReschedule
* fix: validate seatUid before checking booking cancellation status
Move canRescheduleBooking call to happen after input validation
(including seatUid validation for seated bookings) but before the
actual booking creation. This ensures that when trying to reschedule
a seated booking without providing seatUid, users get the proper
'seatUid required' error instead of 'booking has been cancelled' error.
Fixes failing e2e test: 'should not be able to reschedule seated
booking if seatUid is not provided'
Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-30 16:43:05 +02:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: move bookings tabs to sidebar navigation
- Add bookings sub-items (Upcoming, Unconfirmed, Recurring, Past, Cancelled) to sidebar navigation
- Remove HorizontalTabs component from bookings view
- Add redirect from /bookings to /bookings/upcoming for default navigation
- Parent Bookings menu item now automatically navigates to Upcoming sub-item
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* clean up
* add e2e tests
* address feedback
* add horizontal tab back
* useBuildHref
* update preserveQueryParams logic
* put back lint rule
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-30 15:35:26 +01: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>
* fix: use highest role for org admins accessing sub team event types
When an org admin who is also a member of a sub team (but only as MEMBER role) tries to update a sub team event type, they were being denied access. This was because the permission check logic was using the team MEMBER role instead of checking both team and org roles and using the highest one.
This fix updates PermissionCheckService.checkPermission() and checkPermissions() to use the highest role between team membership and org membership, similar to how getEventTypePermissions() already works.
Changes:
- Added getHighestRole() helper method to determine the highest role between two roles
- Updated checkPermission() to check both team and org membership and use the highest role
- Updated checkPermissions() to use the same logic
- Added test case for org admin who is team member updating sub team event type
Fixes the issue where org admins get 'permission required eventType.update' errors when updating sub team event types.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* test: add PBAC-enabled test case for org admin accessing sub team event types
Adds a test case to verify that when PBAC is enabled, org admins who are also members of a sub team (but only with MEMBER role) can still access sub team event types through their org-level ADMIN permissions.
This complements the existing fallback (PBAC disabled) test case and ensures both code paths handle org admin permissions correctly.
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
## What does this PR do?
Currently we load /event-types for a few seconds while the onboarding hook catches up. This adds that logic to the serverside and not just client side to ensure onboarding is triggered
Adds server-side onboarding redirect checks to prevent users from accessing event types pages before completing onboarding. This implementation:
- Creates a new `checkOnboardingRedirect` utility function in a dedicated file
- Applies the redirect check on both the root page and event-types page
- Optimizes performance by using organizationId from session when available
- Handles email verification requirements before redirecting to onboarding
- Supports both legacy and v3 onboarding paths based on feature flags
## How should this be tested?
- Create a new user account that hasn't completed onboarding
- Attempt to access the root page or event-types page directly
- Verify you're redirected to the appropriate onboarding flow
- Test with email verification feature flag enabled/disabled
- Test with onboarding-v3 feature flag enabled/disabled
- Verify users who have completed onboarding can access event-types normally
- Verify organization users aren't redirected to onboarding
## Video Demo
Before:
[CleanShot 2025-10-30 at 10.54.41.mp4 <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/user-attachments/thumbnails/8282decc-a00d-4bc8-9215-fe1c4809fd8f.mp4" />](https://app.graphite.dev/user-attachments/video/8282decc-a00d-4bc8-9215-fe1c4809fd8f.mp4)
After
## [CleanShot 2025-10-30 at 10.54.06.mp4 <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/user-attachments/thumbnails/2acc7601-6c8c-496a-af4d-08dadef9aa2d.mp4" />](https://app.graphite.dev/user-attachments/video/2acc7601-6c8c-496a-af4d-08dadef9aa2d.mp4)
## Checklist
- [x] I have self-reviewed the code
- [x] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change
- [x] I confirm automated tests are in place that prove my fix is effective or that my feature works
* fix: Modified teamName to be null when host is not fixed
* feat: Added test cases for round robin bookings reassignment with fixed and non-fixed hosts
* feat: improve team name handling in round robin reassignment
* refactor: improve booking title validation in reassignment tests
* feat: add bookingRequiresAuthentication validation to 2024-04-15 booking controller
- Add checkBookingRequiresAuthentication method to validate authentication requirements
- Check if user is event type owner, host, team admin/owner, or org admin/owner
- Add comprehensive e2e tests for bookingRequiresAuthentication feature
- Ensure parity with 2024-08-13 controller implementation
- Fix type issue in setPlatformAttendeesEmails method
Co-Authored-By: morgan@cal.com <morgan@cal.com>
* refactor: move Prisma calls to repository pattern
- Add findByIdIncludeHostsAndTeamMembers method to EventTypeRepository
- Inject PrismaEventTypeRepository and PrismaTeamRepository into controller
- Replace direct Prisma calls with repository methods in checkBookingRequiresAuthentication
- Use getTeamByIdIfUserIsAdmin for org admin/owner check
- Add repositories to BookingsModule_2024_04_15 providers
Co-Authored-By: morgan@cal.com <morgan@cal.com>
* handle httpException in handleBookingErrors
* test: add test case for authenticated but unauthorized user booking
- Create second user who is not authorized to book the event type
- Verify that authenticated user without proper permissions receives 403 Forbidden
- Test validates that bookingRequiresAuthentication properly checks authorization levels
- Cleanup unauthorized user in afterAll hook
Co-Authored-By: morgan@cal.com <morgan@cal.com>
* fix: add accepted filter to team members and handle org-owned event types
Addresses PR comments from cubic-dev-ai and @ThyMinimalDev:
1. Add accepted: true filter to team.members query
- Prevents pending team invitations from being treated as authorized
- Also filter by role to only fetch ADMIN and OWNER roles
- Reduces payload size and improves query performance
2. Add isOrganization field to team select
- Enables proper handling of org-owned event types
3. Update authorization logic for org-owned event types
- Handle case where team.isOrganization is true with no parent
- Ensure org admins/owners are properly authorized for org-owned events
- Matches behavior of 2024-08-13 controller
Changes:
- packages/features/eventtypes/repositories/eventTypeRepository.ts:
* Add where clause to members query with accepted: true and role filter
* Add isOrganization: true to team select
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts:
* Update authorization logic to handle org-owned event types
* Check if team.isOrganization is true when no parentId exists
Co-Authored-By: morgan@cal.com <morgan@cal.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-10-29 16:48:16 +00:00
Hariom BalharaGitHubhariom@cal.com <hariombalhara@gmail.com>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Alex van Andel
* fix: prevent base64 logo/banner storage in organization onboarding
- Add processOnboardingBrandAssets helper method to BaseOnboardingService
- Process base64 images and upload them before storing in database
- Use uploadAvatar with userId to avoid foreign key issues before Team exists
- Handle both create and update/resume flows
- Ensure OrganizationOnboarding and Team records store regular URLs not base64
- Fixes header size issues when logoUrl is added to session cookies
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* fix: use processed URLs from OrganizationOnboarding record
- Update SelfHostedOnboardingService to use organizationOnboarding.logo/bannerUrl instead of raw input
- Update BillingEnabledOrgOnboardingService payment intent to use processed URLs
- Ensures Team records receive processed URLs, not base64 data
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: remove unused variables and imports
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* refactor: extract image processing to helper method and add tests
- Created private processImageField() method to eliminate code duplication
- Uses regex for more robust data URI and URL detection
- Processes logo and bannerUrl in parallel with Promise.all
- Added 2 important tests for base64 image processing:
1. Verifies base64 conversion with correct resize options (bannerUrl uses maxSize: 1500)
2. Validates undefined vs null semantics (no-op vs explicit clear)
- Fixed pre-existing lint warnings by replacing 'any' types with proper types
Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>
* Improve code
* Fixup organizationId
* simplify
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
* Add critical logger for booking created log to prevent stdout buffering issues
Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>
* Add comment
* Separate critialLogger into it's own file
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
## What does this PR do?
- Redirects users to the personal settings page after organization creation instead of the getting-started page
- Adds a new `skipToPersonal` function in `useSubmitOnboarding` hook to handle this redirection
- Creates a new `getGettingStartedPathWhenInvited` method in `OnboardingPathService` to provide the correct path for invited users
- Updates all invitation-related code to use the new path method
- Improves UI spacing in the organization invite view
## Visual Demo (For contributors especially)
#### Image Demo (if applicable):
- Before: Users were redirected to `/onboarding/getting-started` or `/getting-started` after organization creation
- After: Users are now redirected to `/onboarding/personal/settings` or `/getting-started` based on feature flag
## Mandatory Tasks (DO NOT REMOVE)
- [ ] I have self-reviewed the code.
- [ ] I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
- [ ] I confirm automated tests are in place that prove my fix is effective or that my feature works.
## How should this be tested?
1. Create a new organization through the onboarding flow
2. Verify you are redirected to the personal settings page instead of getting-started
3. Accept an invitation to an organization as a new user
4. Verify you are directed to the personal settings page after signup
5. Check that the UI spacing in the organization invite view looks correct
## Checklist
- I have read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
- My code follows the style guidelines of this project
- I have commented my code, particularly in hard-to-understand areas
- I have checked if my changes generate no new warnings
* i18n
* WIP icon stuff
* More icon work
* More gradient tuning
* Mvoe plan-icon to planicon.tsx
* Fix cubic suggestion
* Fix darkmode icon and gradients
* Fix type error
* Onboarding path service
* Update usages of onboarding path and getting started hook
2025-10-28 11:10:25 +00:00
Eunjae LeeGitHubeunjae@cal.com <hey@eunjae.dev>Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Keith Williams
* feat: add seed-all command to run all seed scripts
- Add seed-all command to packages/prisma/package.json
- Create scripts/seed-all.ts to run seed.ts, seed-insights.ts, and seed-pbac-organization.ts in sequence
- Update Prisma configuration to use seed-all as the default seed command
- Add GitHub workflow to test seed-all command with a real PostgreSQL database
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* fix: use correct path resolution in seed-all script
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* fix: simplify database verification step in test workflow
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* refactor: use seed-all in cache-db action instead of separate workflow
- Update cache-db action to use seed-all command
- Remove test-seed-all.yml workflow as requested
Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>
* fix error
* change command name
* fix integration tests
* run basic seed by default
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>