* refactor: move eventTypeSlug and eventTypeLocations to @calcom/lib/zod
Move shared Zod schemas from @calcom/prisma/zod-utils to @calcom/lib/zod
to avoid prisma imports in non-repository code.
Changes:
- Create packages/lib/zod/eventType.ts with eventTypeSlug, eventTypeLocations,
and EventTypeLocation type
- Re-export from @calcom/prisma/zod-utils for backwards compatibility
- Update packages/features/eventtypes/lib/schemas.ts to import from @calcom/lib/zod
- Remove unused slugify function from zod-utils.ts
This allows files like schemas.ts to avoid importing from @calcom/prisma,
which helps maintain the architectural boundary that prisma should only
be imported in repository code.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* refactor: remove barrel file and use explicit imports
Address PR feedback:
- Delete packages/lib/zod/index.ts barrel file
- Update imports to use explicit path @calcom/lib/zod/eventType
- Simplify EventTypeLocation type to use z.infer
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* refactor: use explicit type definition with z.ZodType for eventTypeLocations
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix(ci): skip yarn install in deps job when cache is hit
The Install Dependencies / Yarn install & cache step in pr.yml is primarily
for populating the cache when nothing is cached. When cache keys are found,
we can skip the actual yarn install and let the workflow carry on quickly.
This adds a skip-install-if-cache-hit parameter to the yarn-install action
that allows skipping the install when node_modules cache is hit. This is
enabled for the deps job in yarn-install.yml but not for other jobs that
actually need node_modules for their work.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix(ci): also skip playwright install in deps job when cache is hit
Extends the skip-install-if-cache-hit parameter to the yarn-playwright-install
action as well, so both yarn install and playwright install are skipped in the
deps job when their respective caches are hit.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix(ci): use lookup-only cache check to avoid downloading 1.2GB
When skip-install-if-cache-hit is true, use actions/cache/restore@v4 with
lookup-only: true to check if caches exist without downloading them. This
avoids downloading ~1.2GB of cache data when we just want to verify caches
exist in the deps job.
The flow is now:
1. If skip-install-if-cache-hit is true, run lookup-only checks for all caches
2. If all caches hit, skip the entire restore + install flow (no downloads)
3. If any cache misses, fall back to normal restore + install + save behavior
This optimization only applies when skip-install-if-cache-hit is set to true,
so other jobs that need node_modules continue to work normally.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* Apply suggestion from @keithwillcode
* Apply suggestion from @keithwillcode
* Apply suggestion from @keithwillcode
* Apply suggestion from @keithwillcode
* fix(ci): address @cubic-dev-ai feedback on cache conditions
1. yarn-install: Add 'all-caches-check' step to compute whether all three
caches hit (not just node_modules). This ensures we only bail out when
everything is cached, matching the PR description.
2. yarn-playwright-install: Fix backward compatibility for install step.
In default mode, check playwright-cache.outputs.cache-hit (the restore step).
In skip mode, check playwright-cache-check.outputs.cache-hit (lookup-only).
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* chore: Delete cache-build cache entries on PR close
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* refactor: Extract cache-build key generation into reusable action
- Create .github/actions/cache-build-key to generate cache keys
- Update cache-build action to use the shared key action
- Update delete workflow to use the shared key action
- Checkout PR head SHA in delete workflow for correct hash computation
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: Remove PR head SHA checkout per review feedback
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* refactor: Use prefix-based cache deletion for simpler cleanup
- Use useblacksmith/cache-delete prefix mode to delete all caches matching branch
- Remove dependency on cache-build-key action for deletion
- No checkout needed since we're just using the branch name as prefix
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* refactor: Simplify cache key by removing Linux and node version segments
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix another
* fix flakes
* Update apps/web/playwright/fixtures/apps.ts
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
* fix
* fix
* test fix
* fix test
* tweak
---------
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
* fix(ci): use GitHub App token for team membership check
The default GITHUB_TOKEN doesn't have org-level permissions to query
team membership via the teams.getMembershipForUserInOrg API. This causes
the API to return 404 even for valid team members, making the trust check
incorrectly fail for core team members.
This change generates a short-lived GitHub App token with org-level access
to properly verify team membership.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix(ci): use getCollaboratorPermissionLevel for trust check
Replace the team membership check (teams.getMembershipForUserInOrg) with
getCollaboratorPermissionLevel which works with the default GITHUB_TOKEN.
This approach:
- Checks if users have write/maintain/admin access to the repo
- Works without requiring a GitHub App token with org-level permissions
- Is semantically correct: if someone can push to the repo, they're trusted
The previous approach using teams.getMembershipForUserInOrg required
org-level permissions that the default GITHUB_TOKEN doesn't have,
causing 404 errors even for valid team members.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* Apply suggestion from @keithwillcode
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Exclude 'link' toolbar item from Editor for all workflow actions (not just SMS)
- Add replaceCloakedLinksInHtml utility to sanitize HTML and replace cloaked links with visible URLs
- Apply sanitization to email content before sending in all workflow email paths
This ensures recipients can see the actual destination of URLs, helping them identify potentially malicious links.
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This change adds a trust-check job that gates CI for external contributors:
- Trusted contributors (OWNER, MEMBER, COLLABORATOR) can run CI immediately
- External contributors require approval from a core team member (write access or higher)
- Approval must be for the current commit SHA (stale approvals are ignored)
- Added pull_request_review trigger so CI runs when approval is given
- The required job now fails with a clear message for untrusted PRs
Co-authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
Co-authored-by: Pedro Castro <pedro@cal.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2025-12-29 22:31:11 -03:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* fix: align env vars between Production Builds and E2E workflows for turbo cache sharing
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: move E2E-specific env vars to step-level for turbo cache alignment
Instead of adding env vars to production-build-without-database.yml (which
caused DB calls during build), move the E2E-specific env vars from workflow-level
to step-level in e2e.yml. This ensures the cache-build step has the same env
context in both workflows, enabling turbo remote cache sharing.
Env vars moved to step-level:
- DATABASE_DIRECT_URL (to cache-db and Run Tests steps)
- E2E_TEST_MAILHOG_ENABLED (to Run Tests step)
- EMAIL_SERVER_* (to Run Tests step)
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: restore production build cache with stable key using actions/cache
- Restore artifact caching for .next, dist, and .turbo directories
- Use actions/cache@v4 (accelerated by Blacksmith on their runners)
- Design stable cache key scoped to branch:
- Includes branch name (head_ref for PRs, ref_name for pushes)
- Hashes yarn.lock for dependency changes
- Hashes source files in apps/web and packages/*/src
- Excludes generated directories (prisma/zod, kysely) that caused instability
- Add restore-keys for partial cache hits
- Only run yarn build on cache miss
- Revert e2e.yml env var changes (no longer needed with artifact caching)
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: simplify restore-keys to single fallback
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: remove restore-keys entirely for exact cache matching only
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: use broader package pattern with exclusions for generated prisma files
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: add exclusions for prisma/generated and prisma/client directories
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* Apply suggestion from @cubic-dev-ai[bot]
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* fix: add .json and .css patterns to cache hash for config and style changes
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
* mv
* wip
* wip
* wip
* wip
* plural
* fix: resolve TypeScript type errors for attribute refactoring
- Add TransformedAttributeOption type to handle transformed contains field
- Update imports to use routing-forms Attribute type where needed
- Fix getValueOfAttributeOption to use TransformedAttributeOption type
- Update AttributeOptionValueWithType to use TransformedAttributeOption
- Fix pre-existing lint warnings (any -> unknown, proper type casting)
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix
* cleanup
* cleanup
* fix
* fix
* fix
* fix
* fix
* fix: add explicit type annotation to reduce callback in getAttributes.ts
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: use RouterOutputs from @calcom/trpc/react for consistent type inference
- Update AppPage.tsx to use RouterOutputs from @calcom/trpc/react instead of inferRouterOutputs<AppRouter>
- Update MultiDisconnectIntegration.tsx to use the same RouterOutputs type source
- Add eslint-disable comments for pre-existing warnings (useEffect deps, img elements)
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: explicitly type attribute property in AttributeOptionAssignment
The attribute property from Pick<AttributeOption, 'attribute'> was typed as
'unknown' because Prisma relations don't have explicit types when picked.
This explicitly defines the attribute shape with id, type, and isLocked
properties that are used in assignValueToUser.ts.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: remove unused assignedUsers from AttributeOptionAssignment Pick
The assignedUsers property was not being used in the code but was required
by the Pick type, causing a type mismatch when the actual data from the
database query didn't include it.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix: update import path for AttributeOptionAssignment and BulkAttributeAssigner types
The types.d.ts file was moved from packages/lib/service/attribute/ to
packages/app-store/routing-forms/types/. Updated the import path in utils.ts
to point to the new location.
Co-Authored-By: benny@cal.com <sldisek783@gmail.com>
* fix
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Move managedEventTypeSlug generation inside beforeAll to ensure uniqueness across test runs
- Add deleteAllTeamEventTypes method to EventTypesRepositoryFixture
- Explicitly delete all team event types in afterAll before deleting teams
This fixes flaky tests in organizations-member-team-admin-event-types.e2e-spec.ts
where the managed event type creation was intermittently failing with 400 Bad Request.
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 16:12:01 -03:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* longpress ios - event type, booking, availability
* new booking details page for ios
* remove comments
* address cubics comments
* use lowercase type same as api v2
2025-12-29 18:57:48 +05:30
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat: add PUSH_IMAGE boolean input to release-docker workflow
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* refactor: simplify push-image expression to always return string
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: make RELEASE_TAG input work for manual workflow triggers
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: add postMessage listener to capture __iframeReady events early
This fixes a race condition in the embed E2E tests where the __iframeReady
event could fire before the Cal.ns[namespace] API was ready to receive it.
The fix adds a window.message listener immediately in the addInitScript that
captures __iframeReady events directly from postMessage, which doesn't depend
on the namespace API being ready. This ensures window.iframeReady is set
even if the event fires before the Cal API listener is attached.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* Revert "fix: add postMessage listener to capture __iframeReady events early"
This reverts commit fdd02fcf1e5286f2b3b36a9f4c9889b269720845.
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This fixes a race condition in the embed E2E tests where the __iframeReady
event could fire before the Cal.ns[namespace] API was ready to receive it.
The fix adds a window.message listener immediately in the addInitScript that
captures __iframeReady events directly from postMessage, which doesn't depend
on the namespace API being ready. This ensures window.iframeReady is set
even if the event fires before the Cal API listener is attached.
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* refactor: use explicit type annotations for TUpdateInputSchema to reduce type inference complexity
This change significantly reduces TypeScript type-checking time by:
1. Defining explicit TypeScript types instead of using z.infer<> on complex schema chains
2. Using z.ZodType<T> annotations on schemas to prevent TypeScript from inferring through .extend(), .partial(), .merge() chains
3. Removing the dependency on EventTypeSchema from @calcom/prisma/zod/modelSchema which pulls in many dependencies
The schema still validates all fields at runtime - only the compile-time type inference is optimized.
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: update BookingFieldInput and users types to fix type errors
- BookingFieldInput now includes name, hidden, required properties with index signature
- users type changed from (string | number)[] to number[]
- Zod schema updated to use z.array(z.number()) for users field
- Removed unused stringOrNumber import
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: handle bookingFields null case with Prisma.DbNull for JSON field compatibility
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: remove index signature from BookingFieldInput for API v2 DTO compatibility
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* chore: remove useless JSDoc comments per PR feedback
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* test: add unit tests for aiPhoneCallConfig transformation in ZUpdateInputSchema
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* test: add unit tests for bookingFields null to Prisma.DbNull transformation
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* chore: remove comments from update.handler.test.ts
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* refactor: scope test describe block to update.handler per PR feedback
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 07:40:49 -03:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: add artifact handling for API v2 E2E tests
- Add jest-junit reporter to generate JUnit XML test results
- Update workflow to upload from correct path (apps/api/v2/test-results)
- Add if-no-files-found: ignore and retention-days: 30 for consistency
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* Apply suggestion from @keithwillcode
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2025-12-29 02:22:38 -03:00
Keith WilliamsGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* chore: migrate GitHub workflows from Buildjet to Blacksmith
- Replace buildjet-*vcpu-ubuntu-2204 runners with blacksmith-*vcpu-ubuntu-2204
- Replace buildjet/cache@v4 with actions/cache@v4
- Replace buildjet/setup-node@v4 with actions/setup-node@v4
- Replace buildjet/cache-delete@v1 with useblacksmith/cache-delete@v1
- Rename delete-buildjet-cache.yml to delete-blacksmith-cache.yml
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* chore: bump Blacksmith runners to Ubuntu 24.04
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* Reduce 16vcpu to 4vcpu for the API v2 E2E
* Remove 8vcpu usage
* chore: switch Blacksmith runners to ARM architecture
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* chore: switch Blacksmith runners back to AMD (remove -arm suffix)
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: improve test cleanup to cover all bookings including reassignment-created ones
- Changed afterEach cleanup to find all bookings by eventTypeId instead of tracking bookingIds
- This ensures bookings created indirectly by managedEventManualReassignment are also cleaned up
- Removed problematic prefix-based deleteMany calls that could affect parallel tests
- Fixes idempotencyKey collision errors on high-parallelism CI runners
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: improve icons screenshot test stability with deviceScaleFactor and increased threshold
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
* fix: cap Playwright workers to 4 to match vCPU allocation on Blacksmith runners
Co-Authored-By: keith@cal.com <keithwillcode@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* fix: add proper disabled-state styling to Select component using state.isDisabled
* chore: apply hover:border-subtle since disabled items are not clickable and only hover state should change the border
<!-- This is an auto-generated description by cubic. -->
## Summary by cubic
Switch @calcom/prisma to use relative imports for client and enums. This removes self-references, stabilizes builds, and improves type resolution.
- **Refactors**
- Replaced imports from "@calcom/prisma/*" with local "./client" and "./enums" across extensions, selects, mocks, and availability check.
- Updated safeJSONStringify parameter type from any to unknown.
- Minor formatting cleanup in zod-utils.
<sup>Written for commit 85c0a7b75fb1291be5b848a73d1ccb5543283f49. Summary will update automatically on new commits.</sup>
<!-- End of auto-generated description by cubic. -->
The hasReadPermissionsForUserId function is async but was being
called without await in two locations.
This aligns with the existing correct usage in
ScheduleRepository.findManyDetailedScheduleByUserId
- Add await to getAllSchedulesByUserId.handler.ts
- Add await to ScheduleRepository.findDetailedScheduleById
- Refactor ScheduleRepository tests to use shared prismaMock
- Add new handler test with authorization coverage
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
* fix: add missing peer dependencies and fix inconsistent peer dependency declarations
- @calcom/ui: Move react from dependencies to peerDependencies (was inconsistent with react-dom being a peer)
- @calcom/emails: Move react and react-dom to peerDependencies
- @coss/ui: Add react and react-dom as peerDependencies (uses lucide-react and @base-ui/react)
- @calcom/app-store: Add react, react-dom, zod as peerDependencies (depends on @calcom/features which has these peers)
- @calcom/platform-libraries: Add react, react-dom, stripe, zod as peerDependencies (depends on @calcom/features)
- @calcom/features: Add next as peerDependency (depends on @calcom/trpc which has next as peer), update react/react-dom to flexible version ranges
- @calcom/features/ee: Add react, react-dom, react-hook-form as peerDependencies (uses @calcom/ui and @hookform packages)
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: add more peer dependencies for PnP compatibility
Additional changes:
- @calcom/app-store: Move stripe from dependencies to peerDependencies
- @calcom/ui: Move @tanstack/react-query to peerDependencies (singleton pattern)
- @calcom/trpc: Move @tanstack/react-query to peerDependencies (singleton pattern)
- @calcom/atoms: Move @tanstack/react-query to peerDependencies (singleton pattern)
- @calcom/stripepayment: Add react, react-dom, stripe as peerDependencies
- @calcom/caldavcalendar: Add react, react-dom, react-hook-form as peerDependencies
- @calcom/exchange2013calendar: Add react, react-dom, react-hook-form as peerDependencies
- @calcom/exchange2016calendar: Add react, react-dom, react-hook-form as peerDependencies
- @calcom/ics-feed: Add react, react-dom, react-hook-form as peerDependencies
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
* fix: revert dependency moves for packages with own builds
Packages with their own build step should not have dependencies
moved to peerDependencies as they need those deps at build time.
Reverted:
- @calcom/trpc: Keep @tanstack/react-query out of peerDependencies
- @calcom/atoms: Restore @tanstack/react-query to dependencies
- @calcom/stripepayment: Restore stripe to dependencies
Co-Authored-By: Volnei Munhoz <volnei.munhoz@gmail.com>
---------
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
ios:
https://github.com/user-attachments/assets/efdfd3e3-239f-4cbf-be1a-7784d1df1851
android:
https://github.com/user-attachments/assets/a8e22a5c-60f3-4fb6-8923-b8a786bceb0c
## Overview
This PR introduces native iOS UI components, refactors the profile menu, and simplifies the event type creation flow for a more native iOS experience.
## Key Changes
### iOS Native UI Components
- **iOS-specific Event Types Page**: Added native Stack.Header, glass UI, and context menus for iOS
- **Platform-specific Profile Sheet**: Created separate implementations for iOS (formSheet) and Android/Web (modal)
- **Bottom Glass UI Navbar**: Updated bottom navigation bar with glass UI styling for iOS
- **Native iOS Alerts**: Replaced custom modals with native `Alert.prompt` for event types and availability pages
### Profile Menu Refactor
- Restructured More page with folder layout and native iOS header support
- Added profile button to More page header on iOS with glass UI
- Added "Copy public page link" and "Roadmap" options to profile sheet
- Refactored Header component: removed inline profile modal, now uses route-based navigation
- Updated Availability page with New menu and profile button in header
- Fixed "My Settings" URL to use `/general` endpoint
- Removed "Profile" item from More section menu
- Updated tab layout to support `(more)` folder structure
### Simplified Event Type Creation
- Reduced event type creation to only require title input
- Auto-generate slug from title using slugify utility
- Set default duration to 15 minutes
- Leave description empty (users can edit later)
- Applied to both iOS and Android/Web platforms
### UI Improvements
- Updated login button styling: changed background color to pure black (#000000) with white text for better contrast