Files
cal.diy/packages/features/ee/organizations
51bce6763f refactor: split tRPC build into server and react phases (#26082)
* refactor: import AppRouter from generated types instead of server source

This change improves tRPC build performance by having the client-side code
import AppRouter from pre-generated type declarations instead of traversing
the entire server router tree.

Changes:
- Create type bridge file at packages/trpc/types/app-router.ts
- Update packages/trpc/react/trpc.ts to import from the bridge
- Update .gitignore to only ignore types/server (generated files)
- Update eslint.config.mjs to only ignore types/server (generated files)

The type bridge provides:
1. Faster typechecking - avoids parsing 458 server files
2. Stable import location that's easy to lint against
3. Single place to adjust if generated path changes

Build order is already enforced in turbo.json (type-check depends on @calcom/trpc#build).

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

* fix: move bridge file to react/ to avoid TS5055 error

Move the AppRouter type bridge file from types/app-router.ts to react/app-router.ts
to avoid the TS5055 'Cannot write file because it would overwrite input file' error.

The issue was that placing the bridge file in types/ caused TypeScript to treat
the generated .d.ts files as input files during the tRPC build, then fail when
trying to emit to the same location.

By placing the bridge in react/ (which is excluded from the tRPC server build),
the bridge file is only used by client code and doesn't interfere with the
server type generation.

Changes:
- Move bridge file from types/app-router.ts to react/app-router.ts
- Update import in react/trpc.ts to use ./app-router
- Revert .gitignore to ignore all of types/ (generated files)
- Revert eslint.config.mjs to ignore all of types/**

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

* refactor: split tRPC build into server and react phases

- Create tsconfig.server.json for server-only type generation
- Create tsconfig.react.json for react/client type generation
- Update build script to run server build first, then react build
- Remove || true so build properly fails on errors
- This allows react code to import from generated server types

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

* refactor: split @calcom/trpc exports to separate server and react entrypoints

- Remove react exports from @calcom/trpc root (index.ts)
- Update 89 files to import from @calcom/trpc/react instead of @calcom/trpc
- This fixes the boundary leak where server builds were pulling in react code
- Server build no longer compiles react/app-router.ts, fixing the chicken-and-egg
  issue where react code needed generated server types that didn't exist yet

This improves TypeScript build performance by preventing the server type
generation from traversing the entire react/client type graph.

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

* fix: import WorkflowType from lib/types instead of React component

This fixes a boundary leak where the server build was pulling in React
components through the WorkflowRepository import chain. By importing
WorkflowListType from lib/types instead of WorkflowListPage.tsx, the
server build no longer traverses React component files.

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

* fix: extract server-safe types to prevent boundary leaks in tRPC build

- Extract ChildrenEventType to lib/childrenEventType.ts (server-safe)
- Extract Slots type to calendars/lib/slots.ts (server-safe)
- Create types.server.ts files for eventtypes and bookings
- Update server code to import from server-safe type files
- Update DatePicker.tsx to use extracted Slots type
- Update app-store utils to use BookerEventForAppData type

This prevents the server build from pulling in React files through
transitive imports from @calcom/features barrel exports.

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

* fix: update Segment.test.tsx mock path to @calcom/trpc/react

The test was mocking @calcom/trpc but importing from @calcom/trpc/react.
After the entrypoint separation, the mock path needs to match the import path.

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

* fix: temporarily restore || true to unblock PR merge

The pre-existing Prisma type errors (~345 errors) will be addressed in a follow-up PR.
This allows the two-phase build architecture changes to be merged first.

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

* Run trpc build as part of API v2 build

* Removed the bridge file

* refactor: extract event type schemas to server-safe file

- Create packages/features/eventtypes/lib/schemas.ts with createEventTypeInput and EventTypeDuplicateInput
- Update types.ts to re-export schemas from the new server-safe location
- Update tRPC schema files to import from schemas.ts instead of types.server.ts
- Delete types.server.ts (was duplicating ~200 lines unnecessarily)

This keeps the server build graph clean while avoiding code duplication.

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

* Removed the optionality of the tRPC builds

* Removed the extra command for API v2

* refactor: rename calendars/lib/slots.ts to types.ts

Per Keith's feedback, renamed the file to types.ts since it contains type definitions.

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

* Added back tRPC build:server for API v2

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Dhairyashil Shinde <93669429+dhairyashiil@users.noreply.github.com>
2025-12-20 23:43:04 -03:00
..

Organizations feature

From the Original RFC:

We want to create organisations within Cal.com to enable people to easily and effectively manage multiple teams. An organisation will live above the current teams layer.

App setup

  1. Log in as admin and in Settings, turn on Organizations feature flag under Features section. Organizations feature has an operational feature flag in order to turn on the entire feature.

  2. Set the following environment variables as described:

    1. CALCOM_LICENSE_KEY: Since Organizations is an EE feature, a license key should be present, either as this environment variable or visiting as an Admin /auth/setup. To get a license key, please contact sales
    2. NEXT_PUBLIC_WEBAPP_URL: In case of local development, this variable should be set to http://app.cal.local:3000 to be able to handle subdomains correctly in terms of authentication and cookies
    3. NEXTAUTH_URL: Should be equal to NEXT_PUBLIC_WEBAPP_URL which is http://app.cal.local:3000
    4. NEXTAUTH_COOKIE_DOMAIN: In case of local development, this variable should be set to .cal.local to be able to accept session cookies in subdomains as well otherwise it should be set to the corresponding environment such as .cal.dev, .cal.qa or .cal.com. If you choose another subdomain, the value for this should match the apex domain of NEXT_PUBLIC_WEBAPP_URL with a leading dot (.)
    5. ORGANIZATIONS_ENABLED: Should be set to 1 or true
    6. STRIPE_ORG_MONTHLY_PRICE_ID: For dev and all testing should be set to your own testing key. Or ask for the shared key if you're a core member.
    7. ORGANIZATIONS_AUTOLINK: Optional. Set to 1 or true to let new signed-up users using Google external provider join the corresponding organization based on the email domain name.
  3. Add app.cal.local to your host file, either:

    1. sudo npx hostile set localhost app.cal.local
    2. Add it yourself
  4. Add acme.cal.local to host file given that the org create for it will be acme, otherwise do this for whatever slug will be assigned to the org. This is needed to test org-related public URLs, such as sub-teams, members and event-types.

  5. Be sure to be logged in with any type of user and visit /settings/organizations/new and follow setup steps with the slug matching the org slug from step 3

  6. Log in as admin and go to Settings and under Organizations you will need to accept the newly created organization in order to be operational

  7. After finishing the org creation, you will be automatically logged in as the owner of the organization, and the app will be shown in organization mode

Note

Browsers do not allow camera/mic access on any non-HTTPS hosts except for localhost. To test cal video organization meeting links locally (app.cal.local/video/[uid]). You can access the meeting link by replacing app.cal.local with localhost in the URL.

For eg:- Use http://localhost:3000/video/nAjnkjejuzis99NhN72rGt instead of http://app.cal.local:3000/video/nAjnkjejuzis99NhN72rGt.

To get an HTTPS URL for localhost, you can use a tunneling tool such as ngrok or Tunnelmole . Alternatively, you can generate an SSL certificate for your local domain using mkcert. Turn off any SSL certificate validation in your HTTPS client (be sure to do this for local only, otherwise its a security risk).

Tunnelmole - Open Source Tunnelling Tool:

To install Tunnelmole, execute the command:

curl -O https://install.tunnelmole.com/8dPBw/install && sudo bash install

After a successful installation, you can run Tunnelmole using the following command, replacing 8000 with your actual port number if it is different:

tmole 8000

In the output, you'll see two URLs, one HTTP and an HTTPS URL. For privacy and security reasons, it is recommended to use the HTTPS URL.

View the Tunnelmole README for additional information and other installation methods such as npm or building your own binaries from source.

ngrok - Closed Source Tunnelling Tool:

ngrok is a popular closed source tunneling tool. You can run ngrok using the same port, using the format ngrok http <port> replacing <port> with your actual port number. For example:

ngrok http 8000

This will generate a public URL that you can use to access your localhost server.

DNS setup

When a new organization is created, other than not being verified up until the admin accepts it in settings as explained in step 6, a flag gets created that marks the organization as missing DNS setup. That flag get auto-checked by the system upon organization creation when the Cal instance is deployed in Vercel and the subdomain registration was successful. Logging in as admin and going to Settings > Organizations section, you will see that flag as a badge, designed to give admins a glimpe on what is pending in terms of making an organization work. Alongside the mentioned badge, an email gets sent to admins in order to warn them there is a pending action about setting up DNS for the newly created organization to work. Read more about the Organization Setup here