Commit Graph
15598 Commits
Author SHA1 Message Date
Syed Ali ShahbazandGitHub d381c2c2cb init (#26782) 2026-01-13 12:51:24 +00:00
3aa6499cd4 fix: remove header bug (#26438)
* remove header and add standard pagination

* Remove unused props from OutOfOfficeEntriesList

Removed unnecessary props from the data table component.

* removed standard pagination

* fix

* Update OutOfOfficeEntriesList.tsx

* remove unnecessary padding

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-13 12:14:19 +00:00
Pedro CastroandGitHub 1e67f98970 fix: add Icelandic, Lithuanian, and Norwegian locale support for Booker (#25519)
- Create unified date/time formatter with Intl-first approach and dayjs fallback
- Add support for is/lt/nb locales in Booker components
- Unify date formatting across Booker (Header, dates, weekdays)
- Update translation pipeline to include is, lt, nb
- Add tests for new locales and formatter
- Add timezone support in dayjs fallback
- Add formatter caching with circuit breaker
- Use unified formatDateTime in Header.tsx
2026-01-13 08:47:39 -03:00
sean-brydonandGitHub aaf5958b7d feat: adds admin billing section (#26747)
* feat: adds admin billing section

* use loading prop

* add log on resend error

* add error log in billing portal
2026-01-13 10:34:52 +00:00
Dhairyashil ShindeandGitHub 80941c17a0 feat: companion unique id firefox (#26791) 2026-01-13 10:29:10 +00:00
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
829d6c4714 feat(pbac): add FeatureOptIn resource to permission registry (#26761)
* feat(pbac): add Feature resource to permission registry

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): add migration for Feature resource permissions

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): add English translations for Feature resource

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): update Feature resource for opt-in/opt-out control (read and update only)

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): rename Feature to FeatureOptIn resource

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat(pbac): simplify update description text

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 10:17:41 +00:00
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
fd6e2a9ca5 fix: enable DI for FeatureOptInService (#26061)
* fix integration test

* fix: enable DI for FeatureOptInService

* create containers/FeaturesRepository.ts

* refactor: convert FeatureOptInService and FeaturesRepository to moduleLoader pattern

- Create feature-specific tokens in feature-opt-in/di/tokens.ts and flags/di/tokens.ts
- Update modules to use bindModuleToClassOnToken for type-safe dependency injection
- Simplify containers to use moduleLoader.loadModule() for automatic dependency loading
- Import feature-specific tokens in central tokens.ts using spread operator

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename FeatureOptInServiceInterface to IFeatureOptInService

Follow the codebase convention of using 'I' prefix for interface files and names.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* fix: export featuresRepositoryModule for backward compatibility

The FeaturesRepository module was refactored to use moduleLoader pattern but
AvailableSlots.ts still imports featuresRepositoryModule. This adds the export
to maintain backward compatibility.

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 11:02:00 +01:00
sean-brydonGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
383314d3e2 feat: add skip trial feature for teams/orgs billing page (#26584)
* feat: add skip trial feature for teams/orgs billing page

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* feat: add translation strings for skip trial feature and fix lint-staged config

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: use IS_TEAM_BILLING_ENABLED instead of IS_SELF_HOSTED

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* fix: use correct DialogHeader props in billing-view.tsx

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* restore lint staged config file

* invalidate trpc cache

* fix: update role filter and error message in skipTrialForTeam handler

- Changed role filter to include both OWNER and ADMIN roles to match authorization logic
- Updated error message to reflect that both owners and admins can skip the trial

Addresses Cubic AI review feedback on PR #26584

Co-Authored-By: unknown <>

* fix: optimize skipTrialForTeam to query only specific team by ID

Address Cubic AI review feedback: Replace findAllAcceptedTeamMemberships
(which fetches all teams) with TeamRepository.findById (which fetches
only the specific team needed). Authorization is already validated
earlier in the handler, so this redundant query was inefficient.

Co-Authored-By: unknown <>

* fix static methods

* feat: use pbac

* fix: remove redundant team query in getSubscriptionStatus handler

Co-Authored-By: sean@cal.com <Sean@brydon.io>

* add pbac to skip team handler

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 09:17:42 +00:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
cee3195708 fix: optimize routing form mutation to avoid costly name update triggers (#26781)
* fix: optimize routing form mutation to avoid costly name update triggers

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Add load test script for form responses

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 08:53:10 +00:00
Bailey PumfleetGitHubPedro CastroDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
7c66f33de2 chore: UX Fixes (#26643)
* Copy changes

* Move search bar inline with new button

* Get rid of no more results message

* Change hidden badge to (hidden)

* Remove Cal.ai badge from sidebar

* Add dropdown to create button when there is multiple options

* Fix delete dialog

* Saved filters updates

* More string fixes

* Switch members table to use names

* Fix member spacing

* Fix routing form identifier field

* Fix routing forms stuff

* Only show SMS hint on SMS options

* Make workflow delete button minimal

* Fix padding on workflow steps

* Remove min width on workflow title

* Fix delete workflow PR

* Fix org profile buttons

* Fix org profile screen partially scrolled down

* Improve logos & banner uploads

* Personal profile fixes

* Fix settings general view stuff

* Sentence case consistency

* Fix stuff I broke

* Fix fab

* Fix hidden translation string

* Fix text fields

* Make button small for solo users too

* fix: update E2E tests to match sentence case labels in routing forms

* fix: update tests to match sentence case label changes

- insights.e2e.ts: chart titles (14 strings)
- event-types.e2e.ts: Organizer phone number location
- EditLocationDialog.test.tsx: phone number labels

* fix: address Cubic AI review feedback (confidence 9+)

- Replace hardcoded text-gray-500 with text-muted in TextField.tsx hint section
- Replace text locator with data-testid in E2E test for location select

Co-Authored-By: unknown <>

* fix: update E2E tests for sentence case label changes

- Use data-testid selectors for location options (more reliable than text)
- Update field identifiers in routing-forms tests to match new labels
- Fix Long text selector in manage-booking-questions test

* fix: replace text locator with data-testid in manage-booking-questions E2E test

Replace fragile text="Long text" locator with resilient
page.getByTestId("select-option-textarea") selector per E2E best practices.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* fix: use .last() for multiple location select items

---------

Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 00:56:08 -05:00
Syed Ali ShahbazandGitHub 32d97fbea4 Add parentId condition to findOrganizationIdBySlug (#26729) 2026-01-13 03:53:06 +00:00
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
a20ad44209 feat: filter generic calendars from subscription batch (#26774)
Add filtering to SelectedCalendarRepository.findNextSubscriptionBatch to
exclude generic calendars (holidays, contacts, shared, imported, resources)
based on their externalId suffixes.

Changes:
- Add GENERIC_CALENDAR_SUFFIXES constant mapping providers to their
  generic calendar suffixes in AdaptersFactory
- Add getGenericCalendarSuffixes method to AdapterFactory interface
- Update findNextSubscriptionBatch to accept and use genericCalendarSuffixes
  parameter to filter out calendars with matching externalId suffixes
- Update CalendarSubscriptionService.checkForNewSubscriptions to pass
  generic calendar suffixes from the adapter factory
- Update tests to cover the new filtering logic

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 22:39:49 -03:00
Volnei MunhozandGitHub a6d7e4f107 Add claude.md (#26778) 2026-01-12 22:03:21 -03:00
Bailey PumfleetGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
5f21f54bae feat: Add compliance page to settings (#26777)
* Add compliance page to settings

* fix: sanitize error logging in B2 download route

Avoid logging raw error objects which may expose sensitive B2 credentials
or internal information. Use sanitized error message instead.

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 21:50:09 -03:00
Pedro CastroandGitHub 3a6ca9ef15 chore: update dependencies (#26710)
* chore: update dependencies

   - @modelcontextprotocol/sdk: 1.24.0 → 1.25.2
   via resolution
   - jose: 4.13.1 → 4.15.9
   - serialize-javascript: 6.0.1 → 6.0.2 via
   resolution

* fix: update jose and webpack versions

* chore: bump transitive dependencies

- webpack 5.94.0
- express 5.2.1
- @adobe/css-tools 4.3.2
- jsondiffpatch 0.7.2

* chore: add min-document resolution

* fix: remove jose from resolutions

Incompatible with openid-client@6.x which requires jose 5.x/6.x exports.
jose is updated directly in apps/web and packages/features/auth

* fix: replace express with body-parser, remove webpack

- body-parser: 2.2.1 (CVE-2025-13466)
- Removed webpack 5.94.0 (causes TS2729)
- Removed express 5.2.1 (causes path-to-regexp errors)

* fix: remove body-parser resolution for Express 4.x compatibility

body-parser 2.x is designed for Express 5.x but NestJS uses Express 4.x,
causing API v2 E2E tests to fail
2026-01-12 21:48:55 -03:00
Dhairyashil ShindeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
95688b38fa fix(companion): event type links for org user (#26775)
* checkpoint 1

* checkpoint 2

* update extension header

* fix some minor ios ui bugs

* fix(companion): restore username fetching for URL fallback display

Addresses Cubic AI review feedback (confidence 9/10): The username was
hardcoded to 'username' but still used by BasicsTab as a fallback for
URL display when bookingUrl is unavailable. This restores the useEffect
that fetches the actual username from CalComAPIService.getUsername().

Co-Authored-By: unknown <>

* complete devins code change

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-13 05:37:56 +05:30
Joe Au-YeungGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Eunjae Lee
8dbe3848e7 feat: Create Integration Attribute Sync records (#26007)
* Add db schema

* Add `CredentialRepository.findByTeamIdAndSlugs`

* Add enabled app slugs for attribute syncing

* Create repository for `IntegrationAttributeSync`

* Create zod schemas

* Create `AttributeSyncUserRuleOutputMapper`

* Create `IntegrationAttributeSyncService`

* Create DI contianer

* Create trpc endpoints

* Create page

* Include team name in `CredentialRepository.findByTeamIdAndSlugs`

* Update schema and relations

* Update types and schemas

* Add more methods to IntegrationAttributeSyncRepository

* Add more services to `IntegrationAttributeSyncService`
- getById
- Init updateIncludeRulesAndMappings

* Refactor `getTeams.handler` to use repository

* Create `createAttributeSync` trpc endpoint

* Create `updateAttributeSync` trpc endpoint

* Add router to trpc

* Create attribute sync child components

* Pass custom actions to `FormCard`

* Create `IntegrationAttributeSyncCard`

* Pass inital props via server side

* Fix prop

* Only refetch on mutation

* Fixes

* Add form error when duplicate field and attribute combo

* Add `updateTransactionWithRUleAndMappings` logic

* Adjust zod schemas

* Service add `updateIncludeRulesAndMappings`

* Pass orgId from server to component

* Rename types

* Add deleteById method to repository

* Add name to integrationAttributeSync

* Add deleteById method to service

* Rename method

* Add deleteAttributeSync trpc endpoint

* Make the IntegrationAttributeSyncCard a dummy component

* test: add tests for IntegrationAttributeSync feature

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Move creating a attribute sync record to the service

* Add i18n strings

* Safe select credential in find by id and team

* Fix default credentialId value in form

* Update repository return types

* Add i18n string

* Make credentialId optional for form schema

* Fix label

* Add cascade deletes

* Add verification that syncs belong to org

* Create mapper for repository output

* Type fixes

* Remove old test file

* Pass `attributeOptions` from parent to children

* Infer types from zod schema

* Type fixes

* Type fix

* Clean up

* Add i18n strings

* Remove unused file

* Address feedback

* Add migration file

* Address feedback

* Add validation for new integration values

* Remove unused router

* Move away from z.infer to z.ZodType

* Clean up comments

* Type fix

* Type fixes

* Type fix

* fix: add passthrough to syncFormDataSchema to preserve extra fields

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: remove incorrect test that expected extra fields to pass through syncFormDataSchema

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Add indexes

* Add aria label

* Address feedback - consistent validation

* Fix import paths for attribute types

* refactor: change attributeSyncRules array to singular attributeSyncRule

The database schema enforces a one-to-one relationship between
IntegrationAttributeSync and AttributeSyncRule (via @unique constraint),
and the UI only supports a single rule. This change makes the TypeScript
type match the database schema and UI behavior.

Changes:
- Update IntegrationAttributeSync interface to use attributeSyncRule: AttributeSyncRule | null
- Update mapper to return singular rule instead of wrapping in array
- Update UI component to access sync.attributeSyncRule directly
- Update IIntegrationAttributeSyncUpdateParams Omit type
- Update tests to use attributeSyncRule: null instead of attributeSyncRules: []

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* feat: implement FeatureOptInService (#25805)

* feat: implement FeatureOptInService WIP

* clean up

* feat: consolidate feature repositories and add updateFeatureForUser

- Implement updateFeatureForUser in FeaturesRepository (similar to updateFeatureForTeam)
- Move getUserFeatureState and getTeamFeatureState from PrismaFeatureOptInRepository to FeaturesRepository
- Update FeatureOptInService to use only FeaturesRepository
- Add setUserFeatureState and setTeamFeatureState methods to FeatureOptInService
- Update _router.ts to remove PrismaFeatureOptInRepository usage
- Remove PrismaFeatureOptInRepository.ts and FeatureOptInRepositoryInterface.ts
- Update features.repository.interface.ts and features.repository.mock.ts
- Add integration tests for updateFeatureForUser, getUserFeatureState, getTeamFeatureState
- Update service.integration-test.ts to use FeaturesRepository

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: rename updateFeatureForUser to setUserFeatureState

Rename to match the convention used for setTeamFeatureState

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: return FeatureState type from getUserFeatureState and getTeamFeatureState

* fix integration tests

* clean up logics

* update services and router

* refactor: change getUserFeatureState and getTeamFeatureState to accept featureIds array

- Renamed getUserFeatureState to getUserFeatureStates
- Renamed getTeamFeatureState to getTeamFeatureStates
- Changed parameter from featureId: string to featureIds: string[]
- Changed return type from FeatureState to Record<string, FeatureState>
- Updated FeatureOptInService to use the new batch methods
- Added tests for querying multiple features in a single call
- Optimized listFeaturesForTeam to fetch all feature states in one query

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add getFeatureStateForTeams for batch querying multiple teams

- Added getFeatureStateForTeams method to query a single feature across multiple teams in one call
- Updated FeatureOptInService.resolveFeatureStateAcrossTeams to use the new batch method
- Replaces N+1 queries with a single database query for team states
- Added comprehensive integration tests for the new method

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: combine org and team state queries into single call

- Include orgId in the teamIds array passed to getFeatureStateForTeams
- Extract org state and team states from the combined result
- Reduces database queries from 3 to 2 in resolveFeatureStateAcrossTeams

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use team.isOrganization and clarify computeEffectiveState comment

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* refactor: use MembershipRepository.findAllByUserId with isOrganization

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* feat: add featureId validation using isOptInFeature type guard

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* less queries

* add fallback value

* fix type error

* move files

* add autoOptInFeatures column

* use autoOptInFeatures flag within FeatureOptInService

* add setUserAutoOptIn and setTeamAutoOptIn

* fix computeEffectiveState logic

* rewrite computeEffectiveState

* clean up integration tests

* clean up in afterEach

* fix type error

* refactor: use FeaturesRepository methods instead of direct Prisma calls

Replace all manual userFeatures and teamFeatures Prisma operations with
the new setUserFeatureState and setTeamFeatureState repository methods.

Changes include:
- Admin handlers (assignFeatureToTeam, unassignFeatureFromTeam)
- Test fixtures and integration tests
- Playwright fixtures
- Development scripts

This ensures consistent feature flag management through the repository
pattern and supports the new tri-state semantics (enabled/disabled/inherit).

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* clean up

* fix the logic

* extract some logic into applyAutoOptIn()

* remove wrong code

* refactor: convert setUserFeatureState and setTeamFeatureState to object params with discriminated union

- Convert multiple positional parameters to single object parameter
- Use discriminated union types: assignedBy required for enabled/disabled, omitted for inherit
- Update all callers across repository, service, handlers, fixtures, and tests

* fix type error

* use Promise.all

* fix

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Prevent duplicate field and attribute mappings

* Add validation that attribute belongs to the org

* fix: address Cubic AI review feedback

- Add @@index([credentialId]) to IntegrationAttributeSync model for efficient cascade deletes and credential-based queries (confidence: 9/10)
- Fix translation key from 'credential_required' to 'attribute_sync_credential_required' to match existing locale definition (confidence: 10/10)

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* fix: address remaining cubic review feedback

- RuleBuilder.tsx: Use unique IDs for React keys instead of array index to prevent reconciliation bugs when removing conditions
- updateAttributeSync.handler.ts: Add early organization check before service calls for consistency
- createAttributeSync.handler.ts: Add CredentialNotFoundError class for type-safe error handling instead of string matching
- IntegrationAttributeSyncService.test.ts: Replace expect.fail() with proper Vitest rejects.toSatisfy() pattern

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

* Pull test file from main

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Eunjae Lee <hey@eunjae.dev>
2026-01-12 22:57:28 +00:00
Anik Dhabal BabuGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
9202028ab6 fix: resolve API v2 test flakes with cleanup and simplified slug (#26766)
* fix: resolve API v2 test flakes by using UUID-only slug

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

* fix: add beforeAll cleanup to prevent test flakes from leftover data

Co-Authored-By: anik@cal.com <adhabal2002@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 18:54:29 -03:00
2f90138757 feat: update translations via @LingoDotDev (#26773)
Co-authored-by: Lingo.dev <support@lingo.dev>
2026-01-12 21:52:37 +00:00
devin-ai-integration[bot]GitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>susan@cal.com <susan@cal.com>
41dcfe0307 chore: update company email banner copy (#26767)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: susan@cal.com <susan@cal.com>
2026-01-12 20:52:35 +00:00
913eb47ff1 fix: weekly view scheduler breaking on view switch (#25891)
* fix: weekly view scheduler columns offset

* fix

* fix

---------

Co-authored-by: Anik Dhabal Babu <adhabal2002@gmail.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-12 18:58:11 +00:00
Dhairyashil ShindeandGitHub e879c923ea feat(api): add bookingUrl field to event types API v2 response (#26195)
* feat(api): add bookingUrl field to event types API v2 response

Add a new bookingUrl field to EventTypeOutput_2024_06_14 that contains
the full, correct booking URL for each event type. This fixes the issue
where companion app and Chrome extension were hardcoding cal.com URLs
instead of using organization subdomains.

Changes:
- Add bookingUrl field to EventTypeOutput_2024_06_14 type definition
- Update repository to include organization data when fetching users
- Add buildBookingUrl method to compute URL using getOrgFullOrigin
- Include bookingUrl in getResponseEventType return object

The booking URL is computed using the first user's organization slug
(if any) to generate the correct subdomain URL (e.g., i.cal.com/keith/30min
for organization users instead of cal.com/keith/30min).

* fix: include organization data in getEventTypeByIdWithHosts

Update getEventTypeByIdWithHosts to use usersInclude to fetch
organization slug data, ensuring bookingUrl is computed correctly
for the GET /v2/event-types/{eventTypeId} endpoint.

* test: add unit tests and E2E assertions for bookingUrl field

* fix(api-v2): correct bookingUrl format for org users and fix double slashes

Fix issues with bookingUrl field in event types API v2 response:
- Remove trailing slashes from base URLs to prevent double slashes
- Use profile.username instead of user.username for organization users
  (profile contains clean username without org suffix)
- Include user profiles in repository queries to access profile data
- Create local org-domains utility to replace @calcom/features dependency
  which isn't available in API v2 runtime

Changes:
- Add apps/api/v2/src/lib/org-domains.ts with getOrgFullOrigin function
  adapted from @calcom/features/ee/organizations/lib/orgDomains
- Update event-types.repository.ts to include profiles in usersInclude
- Update buildBookingUrl() to prioritize profile data when available
- Update unit tests to cover organization user profile scenarios

Fixes:
- Double slashes in URLs (e.g., http://localhost:3000//user/slug)
- Incorrect username format for org users (e.g., owner1-acme instead
  of owner1)
- Missing organization subdomain in booking URLs (e.g., should be
  http://acme.localhost:3000/owner1/30min not
  http://localhost:3000/owner1-acme/30min)

* deslop ai code

* handle empty username in both code and write test for it, use select instead of include

* feat(api-v2): reuse core org domain logic for event type bookingUrl

Export getOrgFullOrigin and subdomainSuffix from @calcom/platform-libraries/organizations
to reuse existing core logic instead of duplicating it in API v2. This ensures consistency
across the codebase and reduces maintenance burden.

- Export getOrgFullOrigin and subdomainSuffix from platform-libraries/organizations
- Update output-event-types.service to import from @calcom/platform-libraries/organizations
- Remove duplicate org-domains.ts file from API v2
- Update test mocks to use platform-libraries import path
- buildBookingUrl method now uses core getOrgFullOrigin function

This addresses feedback to reuse core code rather than introducing duplicate logic.

* test(api-v2): exclude bookingUrl from output comparison in e2e test

* refactor(api-v2): reuse core logic for event type bookingUrl

Replace duplicated username/org extraction logic in buildBookingUrl with
core functions. Use getBookerBaseUrlSync from @calcom/platform-libraries/organizations
for base URL generation, and add enrichUserWithProfile method that follows
the same pattern as core's UserRepository.enrichUsersWithTheirProfiles.

The enrichment logic is applied synchronously since profiles are already
fetched by the repository, avoiding the need to make the service async.
This ensures consistency with core patterns while maintaining the existing
synchronous API contract.

- Replace getOrgFullOrigin with getBookerBaseUrlSync
- Add enrichUserWithProfile method following core enrichment pattern
- Simplify buildBookingUrl to use enriched user data
- Update tests to mock getBookerBaseUrlSync and verify enrichment flow

* trailing slash cubic comment

* address review comments

* address review comments 2

* better code

* Updated the test to give the user an organization

* address review comments again

* Revert "address review comments again"

This reverts commit 622ea3fc8dcd7f5c3113614afcfc86beadecca0e.

* allow both the full UserWithProfile and the partial EventTypeUser (from select queries) to use the same getUserMainProfile() method, eliminating code duplication without changing the performance-optimized repository queries.

* reveiw points
2026-01-12 14:57:17 -03:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ae2ea190d8 feat: add DEVIN_ACTIONS_PAT instructions for pushing to forked PRs (#26693)
* feat: add DEVIN_ACTIONS_PAT instructions for pushing to forked PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* refactor: simplify PAT instructions to be high-level

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: allow workflow_dispatch to run on draft PRs

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: only process targeted PR when pr_number is provided

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* feat: add critical fork PR error handling instruction to stale PR workflow

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>
2026-01-12 14:42:37 -03:00
AnshumancanrockandGitHub 5c9a5c5729 fix: use cross-platform rimraf for build scripts (#25814)
* use cross-platform rimraf for build scripts

* fix: use cross-platform rimraf for build scripts

* fix: replace cp with npx shx cp for cross-platform compatibility

* Update schema.prisma
2026-01-12 22:56:18 +05:30
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
77184226e5 ci: use pull_request_target for conflict resolver label trigger (#26762)
* fix: use pull_request_target for conflict resolver label trigger

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: update if condition to check for pull_request_target event name

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>
2026-01-12 14:24:43 -03:00
a4d4626319 revert: "feat: rename --font-cal to --font-heading + use Cal Sans UI (#26064)" (#26759)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2026-01-12 16:57:27 +00:00
Pedro CastroandGitHub 3e063d6744 fix: use HEAD^2 and relative threshold in conflict (#26758)
resolver validation

- Change git diff from HEAD^1 to HEAD^2 to show PRs contribution
(matches GitHubs Files changed view) instead of what main brought in
- Replace fixed 50-file threshold with relative threshold (original PR files + 10)
- A 20-file PR with 100 files in merge = bad
- A 100-file PR with 108 files in merge = fine
2026-01-12 16:47:08 +00:00
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
0413783ffb docs: extract DI pattern guide to separate file with moduleLoader pattern (#26756)
* docs: add moduleLoader pattern documentation to knowledge-base

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: rewrite DI section to use moduleLoader pattern as primary approach

- Replace manual module loading examples with moduleLoader pattern
- Add Mistake 4 about manual module loading being not type-safe
- Update Core Concepts to explain moduleLoader components
- Show both depsMap (multiple deps) and dep (single dep) usage
- Emphasize build-time type safety throughout

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

* docs: extract DI pattern to separate file

- Move DI documentation from knowledge-base.md to di-pattern.md
- Add brief reference in knowledge-base.md pointing to the new file
- Keeps knowledge-base.md focused on quick notes while DI gets its own detailed guide

Co-Authored-By: eunjae@cal.com <hey@eunjae.dev>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 15:26:47 +00:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
92f13cdb56 fix: strengthen validation in conflict resolver to prevent bad merge commits (#26754)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 15:10:18 +00:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1e295827c7 refactor: change conflict resolver from cron to label-based trigger (#26757)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 15:01:51 +00:00
MorganandGitHub c7cd25b7d5 chore: api v2 esModuleInterop more imports (#26755) 2026-01-12 11:39:01 -03:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
d24807e0e1 fix: make OOO team member select close after selection (#26736)
* fix: make OOO team member select close after selection

Replace the custom always-visible scrollable list with a proper Select
component that closes after selection like a normal dropdown. The Select
component uses onMenuScrollToBottom for infinite scroll and onInputChange
for search functionality.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: also convert Team OOO member select to use Select component

Both 'Select team member' sections now use the proper Select component
that closes after selection. Removed unused useInViewObserver import.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix: add menuPlacement='bottom' to Team OOO member select

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>
2026-01-12 14:35:19 +00:00
MorganandGitHub 6840642cb7 chore: esModuleInterop: true api v2 tsconfig (#26752)
* chore: api v2 esModuleInterop

* chore: api v2 esModuleInterop
2026-01-12 11:24:08 -03:00
Joe Au-YeungGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
d5c2212c41 chore: Add logging eventId from Stripe webhook (#26623)
* Add loggin

* fix: use established logger instead of console.log for Stripe webhook eventId

Co-Authored-By: unknown <>

* fix: remove sensitive stripe-signature header from error logs

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 14:02:35 +00:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c5cb2edd65 feat: add Biome rule to restrict @calcom imports in API v2 (#26749)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 13:39:29 +00:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
023dfc2a5e feat: request maintainer access for fork PRs without edit permissions (#26750)
- Update devin-conflict-resolver.yml to check maintainerCanModify for fork PRs
- Instead of skipping fork PRs entirely, now checks if maintainer access is enabled
- Posts friendly comment asking contributors to enable 'Allow edits from maintainers'
- Adds 'maintainer-access-requested' label to track which PRs have been notified
- Update stale-pr-devin-completion.yml to post similar comment when triggered
- Both workflows avoid duplicate comments by checking for existing requests

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 13:39:15 +00:00
Dhairyashil ShindeandGitHub dd4e1ba11b fix: api v2 dev server error (#26748) 2026-01-12 13:33:48 +00:00
Eunjae LeeGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
70d5a78d69 docs: add DI pattern guide to knowledge-base.md (#26751)
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 14:33:40 +01:00
ea2036672b fix: normalize backslashes in glob paths for Windows compatibility (#25613)
Co-authored-by: Pallav <90088723+Pallava-Joshi@users.noreply.github.com>
2026-01-12 13:33:28 +00:00
77a0d69c1a fix(ui): fixing the hover bug in the dropdown component (#26257)
* fix(ui): fixing the hover bug in the dropdown component

* revert

---------

Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
2026-01-12 13:26:19 +00:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
cf6581eaea ci: only auto-fix Cubic suggestions with confidence >= 9/10 (#26745)
* fix: only auto-fix Cubic suggestions with confidence >= 9/10

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* Apply suggestion from @keithwillcode

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 18:16:35 +05:30
Volnei MunhozandGitHub c36f4d4a65 Revert "fix: add withSentryConfig to enable Sentry tracing in production (#26…" (#26744)
This reverts commit dd4e8344c9.
2026-01-12 12:16:08 +00:00
Volnei MunhozGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
dd4e8344c9 fix: add withSentryConfig to enable Sentry tracing in production (#26743)
This adds the withSentryConfig wrapper to the Next.js configuration,
which is required for Sentry tracing to work properly. The wrapper is
only applied in production when both NEXT_PUBLIC_SENTRY_DSN and
SENTRY_TRACES_SAMPLE_RATE environment variables are set.

Without this wrapper, Sentry cannot properly instrument the build for
performance monitoring, causing spans (including calendar telemetry)
to not be recorded despite the SDK being initialized.

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 12:07:31 +00:00
Alex van AndelGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>keith@cal.com <keithwillcode@gmail.com>
6fb42b63e0 feat: add comprehensive validation tests for event-types/[id] GET endpoint (#23809)
* feat: add comprehensive validation tests for event-types/[id] GET endpoint

- Add integration tests for complex validation scenarios
- Test locations, booking fields, metadata, and seats validation
- Test edge cases that could cause validation mismatches between validators and DB results
- Ensure API response structure matches schemaEventTypeReadPublic schema
- Successfully catch validation discrepancies like missing displayLocationPublicly and assignAllTeamMembers fields

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: add explicit type annotations for booking fields find callbacks

- Fix TypeScript errors on lines 388 and 395
- Provide proper type annotations for find method callback parameters
- Replace any[] with specific { label: string; value: string }[] type
- Ensure CI type checking passes

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* feat: convert event-types integration test to use real database

- Replace prismaMock with real Prisma client operations
- Create actual database records for comprehensive test scenarios
- Add proper setup/teardown with unique timestamps for test isolation
- Maintain all existing validation test coverage
- Follow Cal.com integration test patterns for database operations

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* feat: restore original mock-based test alongside integration test

- Restored original _get.test.ts with prismaMock for unit testing
- Kept _get.integration.test.ts with real database for integration testing
- Both tests provide complementary coverage: mocks for fast unit tests, real DB for validation testing
- Fixed type annotations in find callbacks to maintain type safety

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: rename integration test to use proper naming convention

- Rename _get.integration.test.ts to _get.integration-test.ts
- Follows Cal.com vitest workspace pattern for integration tests
- Ensures integration test runs in proper CI workflow with database setup

Co-Authored-By: alex@cal.com <me@alexvanandel.com>

* fix: update tests to use handler return value instead of res._getData()

Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>

* fix: add proper type assertions for locations and bookingFields in tests

Co-Authored-By: unknown <>

* fix: create schedule for test user to fix foreign key constraint in integration tests

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: keith@cal.com <keithwillcode@gmail.com>
2026-01-12 12:01:43 +00:00
b6df61d287 fixes for safari extension (#26741)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2026-01-12 16:50:44 +05:30
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
77f59b1e4d chore: Integrate confirmation booking audit (#26523)
* chore: Integrate booking confirmation booking audit

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Use BookingStatus type instead of string for booking.status

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Make booking-audit integration test utils reusable

* refactor: enhance handlePaymentSuccess to accept appSlug and actor identification

- Updated handlePaymentSuccess function to accept an object with paymentId, bookingId, appSlug, and traceContext.
- Introduced getActor function to determine the actor based on appSlug and credentialId.
- Modified webhook handlers for Alby, BTCPayServer, HitPay, PayPal, and Stripe to pass the new parameters.
- Improved logging for missing credentialId in payment processing.
- Adjusted related schemas to ensure proper type handling for booking status and actor identification.

* fix: Correct import paths and getActor function call

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Use ActorIdentification type instead of AuditActor in getActor

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add guard clause for undefined actor in fireBookingAcceptedEvent

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix: Add actionSource to all confirm calls

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: Integrate actor identification and action source updates across booking services

- Added `makeUserActor` to various booking service files to enhance actor identification.
- Updated action source handling in booking confirmation and related functions to include "MAGIC_LINK".
- Refactored schemas to accommodate new actor and action source requirements, ensuring consistent type handling.
- Improved error handling and logging for booking actions to enhance traceability.

* Remvoe formatting changes

* Add test

* refactor: Enhance booking confirmation tests and event handling

- Updated `confirm.handler.test.ts` to improve test coverage for booking acceptance and rejection scenarios, including bulk bookings.
- Refactored the mock implementation of `BookingEventHandlerService` to streamline event handling for accepted and rejected bookings.
- Adjusted the `handleConfirmation` function to utilize `acceptedBookings` for better clarity and maintainability.
- Added tests to ensure correct invocation of event handler methods for both single and bulk booking confirmations and rejections.

* fix tests

* refactor: Use confirmHandler directly in link and verify-booking-token routes

Refactors the link and verify-booking-token API routes to call confirmHandler directly instead of using the tRPC caller pattern. This simplifies the code by removing the need for session getter, legacy request building, and context creation.

Changes:
- apps/web/app/api/link/route.ts: Use confirmHandler directly with ctx and input
- apps/web/app/api/verify-booking-token/route.ts: Use confirmHandler directly with ctx and input
- Updated tests to mock confirmHandler instead of tRPC caller

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* fix ts errors due to merge frommain

* feat: introduce getAppActor utility for actor creation

This commit adds a new utility function, getAppActor, to streamline the process of creating actor objects for apps based on their slug and credential ID. The function is integrated into handlePaymentSuccess and handleStripePaymentSuccess, replacing the previous inline actor creation logic. This refactor enhances code maintainability and readability by centralizing actor creation logic.

Changes:
- New file: packages/app-store/_utils/getAppActor.ts
- Updated handlePaymentSuccess and handleStripePaymentSuccess to use getAppActor
- Removed redundant actor creation code from these functions

* refactor: Update appSlug in payment success handlers to use appConfig.slug

This commit modifies the appSlug parameter in the handlePaymentSuccess function across multiple payment webhook handlers to utilize the appConfig.slug value instead of hardcoded strings. This change enhances consistency and maintainability of the code.

Changes:
- Updated appSlug in handlePaymentSuccess for btcpayserver, hitpay, and paypal webhooks.
- Adjusted a test case to reflect the new appSlug value for consistency.

* test: Enhance booking token verification and audit action tests

This commit adds additional assertions to the booking token verification tests to ensure that the confirmHandler is not called when an error occurs. It also introduces a mechanism to clean up additional booking UIDs after each test in the accepted action integration tests, improving test reliability. Furthermore, it updates the action source schema comment for clarity.

Changes:
- Updated tests in `verify-booking-token` to check that `mockConfirmHandler` is not called on error.
- Implemented cleanup logic for additional booking UIDs in `accepted-action.integration-test.ts`.
- Clarified comment in `actionSource.ts` regarding the schema for action sources.
- Refactored `handleConfirmation.ts` and `confirm.handler.ts` to include tracing logger for error handling in booking events.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 08:17:26 -03:00
Hariom BalharaGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c9bb03b602 chore: Integrate add guests booking audit (#26568)
* chore: Integrate add guests booking audit

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* chore: Add actionSource parameter to support API_V2 audit logging

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* refactor: update attendee audit action service to use new email schema

- Modified the `AttendeeAddedAuditActionService` to replace the old attendees schema with a new `emailSchema` for better validation.
- Adjusted the `addGuestsHandler` to pass the action source explicitly and updated the audit logging to reflect the new structure.
- Cleaned up the code for better readability and consistency.

* test: add happy path integration test for attendee added action

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-01-12 11:11:33 +00:00
Abhay MishraandGitHub b517adfb66 fix: auto-scroll active installed-apps category tab into view on mobile (#26414)
* fix: auto-scroll active installed-apps category tab into view on mobile

* updated code3
2026-01-12 11:11:15 +00:00
sean-brydonGitHubcubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>Anik Dhabal BabuDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Keith Williams
ac90caa81b feat: add DAL for monthly proration tracking (#26588)
* feat(billing): add database schema for monthly proration tracking

add new database models and migration for tracking seat changes and monthly proration on annual subscriptions

- new models: SeatChangeLog, MonthlyProration
- new enums: SeatChangeType, ProrationStatus
- extend TeamBilling and OrganizationBilling with billingPeriod, pricePerSeat, paidSeats fields
- add feature flag 'monthly-proration' (disabled by default)
- squashed migration: 20260106093811_add_monthly_proration_tracking

the schema supports:
- tracking seat additions/removals per month with metadata
- storing proration calculations and stripe invoice details
- high-water mark billing via paidSeats field
- proper foreign key relationships and indexes for query performance

* feat(billing): add repository layer for monthly proration

add repository pattern for proration data access

- MonthlyProrationRepository: crud operations for proration records
  - create, update, and query proration records
  - status management (pending, invoice_created, charged, failed)
  - retry count tracking

- MonthlyProrationTeamRepository: team-specific queries with billing context
  - fetch teams with billing information
  - query annual teams with unprocessed seat changes
  - update billing info and paidSeats
  - metadata fallback for legacy teams without billing records

- update IBillingRepository interface to include proration fields

these repositories provide clean data access layer without business logic

* feat(billing): add seat change tracking service

add service for logging and querying seat changes per month

- SeatChangeTrackingService: track seat additions and removals
  - log seat additions with user and metadata context
  - log seat removals with optional triggered-by info
  - calculate monthly changes (additions, removals, net change)
  - retrieve unprocessed changes for a given month
  - mark changes as processed after proration calculation
  - auto-detect billing entity (team vs organization)

- stripe-subscription-utils: extract billing data from stripe subscriptions
  - determine billing period (monthly vs annually)
  - extract price per seat and quantity

includes comprehensive unit tests

* feat(billing): add billing period service

add service to determine billing period and proration eligibility

- BillingPeriodService: query and manage billing period information
  - check if team is on annual vs monthly plan
  - check if team is in trial period
  - determine if monthly proration should apply (annual + not in trial + feature flag)
  - lazy load billing data from stripe if missing in database
  - backfill missing billing data automatically

supports both TeamBilling and OrganizationBilling models
includes comprehensive unit tests with stripe mocking

* feat(billing): add monthly proration service

add core service for calculating and processing monthly seat prorations

- MonthlyProrationService: orchestrate monthly proration workflow
  - process monthly prorations for teams with seat changes
  - calculate prorated amounts based on remaining subscription days
  - create stripe invoice items for seat additions
  - handle payment success and failure webhooks
  - track high-water mark (paidSeats) for billing
  - update stripe subscription quantities after payment
  - lazy load and backfill missing billing data from stripe
  - support retry logic for failed payments

calculation logic:
- only charge for net seat increases (additions - removals, capped at 0)
- prorate based on remaining days in annual subscription
- track separately from stripe's built-in proration to aggregate monthly

includes unit tests and integration tests with stripe mocking

* refactor(billing): extract prisma logic from services to repositories

move database access logic from services to repository layer for better separation of concerns

- add SeatChangeLogRepository for seat change log data access
- add BillingPeriodRepository for billing period queries and updates
- refactor SeatChangeTrackingService to use SeatChangeLogRepository
- refactor BillingPeriodService to use BillingPeriodRepository
- add create methods to MonthlyProrationTeamRepository for billing records
- refactor MonthlyProrationService to use repository for billing creation
- remove direct prisma calls from services (except FeaturesRepository dependency)

services now focus on business logic while repositories handle data access

* refactor(billing): inject prisma via constructor in repositories

make repositories more testable by accepting prisma client via constructor

- SeatChangeLogRepository: accept optional prisma in constructor
- BillingPeriodRepository: accept optional prisma in constructor
- MonthlyProrationRepository: accept optional prisma in constructor
- MonthlyProrationTeamRepository: accept optional prisma in constructor

all repositories default to global prisma instance when not provided
enables easier mocking in tests by injecting test prisma instances

* refactor: remove verbose comments and unnecessary try-catch

* refactor: change pricePerSeat and proratedAmount to cents (Int)

store monetary values as integers in cents instead of floats for precision
remove unnecessary schema comments

* fix tests and add back try catch error handlign

* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* add faeture flag to config.ts

* Update packages/features/ee/billing/service/proration/__tests__/MonthlyProrationService.integration-test.ts

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* restore schema

* add hooks types for flag

* fix: correct pricePerSeat calculations for cents-based storage

MonthlyProrationService now correctly handles pricePerSeat stored as
cents (INTEGER) instead of dollars (DOUBLE PRECISION). Removed duplicate
conversions to cents that were causing 100x price inflation.

* Use cents for money values

* fix type error

* Move integration to test to use cents value

* fix integration import

* mock subscription

* include paid seats tracking in proration service

* add mocks for invoice creation

* feat: use stripebilling service instead of using stripe directly

* fix validation erorr handler in proration service

* fix: fix sub

* use correct seat value

* fix(billing): mark seat changes as processed when netChange is zero

When a team has additions and removals that net to zero, the function
was returning null without calling markAsProcessed(). This left seat
change logs in an unprocessed state indefinitely, causing subsequent
proration runs to re-query the same changes repeatedly.

Changed the early return condition from checking netChange === 0 to
checking if there are no changes at all (additions === 0 && removals === 0).
This ensures that when there are actual seat changes that net to zero,
a proration record is still created and seat changes are marked as processed.

Co-Authored-By: unknown <>

* update test to reflect new return type of proration

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2026-01-12 10:58:21 +00:00
Volnei MunhozandGitHub 4c0b0115a2 remove explicity json check as it is already in included files (#26739) 2026-01-12 10:43:49 +00:00