* feat: workflow auto translation * tests: add unit tests * refactor: tests and workflow * fix: type err * fix: type err * fix: remove redundant index on WorkflowStepTranslation The @@index on [workflowStepId, field, targetLocale] duplicates the @@unique constraint on the same columns. A unique index already provides efficient lookups, so the separate @@index adds storage overhead and write latency without benefit. Addresses Cubic AI review feedback (confidence 9/10). Co-Authored-By: unknown <> * fix: correct locale mapping when translation API returns null Map translations with their corresponding locales before filtering to preserve correct locale-to-translation associations. Previously, filtering out null translations would reindex the array, causing incorrect locale mappings when any translation in the batch failed. Also fixes pre-existing lint warnings: - Move exports to end of file - Add explicit return type to processTranslations - Replace ternary with if-else for upsertMany selection Co-Authored-By: udit@cal.com <udit222001@gmail.com> * fix: address review feedback for workflow auto-translation - Add change detection before creating translation tasks - Rename userLocale to sourceLocale in task props for clarity - Show source language in UI with new translation key - Extract SUPPORTED_LOCALES to shared translationConstants.ts - Fix locale mapping bug in translateEventTypeData.ts - Add WhatsApp translation support - Abstract translation lookup into shared translationLookup.ts helper - Restore if-else readability for SCANNING_WORKFLOW_STEPS Co-authored-by: Udit Takkar <udit.takkar@cal.com> Co-Authored-By: unknown <> * fix: update test to use sourceLocale instead of userLocale Co-Authored-By: unknown <> * refactor: feedback * fix: handle first time * fix: tests * fix: tests * fix: address Cubic AI review feedback (confidence 9/10 issues) - WhatsApp translation: Apply variable substitution using getSMSMessageWithVariables and clear contentSid when using translated body to ensure Twilio uses the translated text instead of the original template - update.handler.ts: Change sourceLocale assignment from ?? to || for consistency with tasker payload behavior (line 481) - ITranslationService.ts: Rename methods from plural to singular naming: - getWorkflowStepTranslations -> getWorkflowStepTranslation - getEventTypeTranslations -> getEventTypeTranslation Updated all call sites and tests accordingly Co-Authored-By: unknown <> * fix: address Cubic AI review feedback (confidence 9/10+ issues) - Fix getSMSMessageWithVariables to handle WHATSAPP_ATTENDEE action for locale and timezone (confidence 9/10) - Remove WhatsApp translation feature that set contentSid to undefined since Twilio ignores body parameter for WhatsApp and requires pre-approved Message Templates (confidence 10/10) Co-Authored-By: unknown <> * fix: translatio * Add tests: packages/features/eventTypeTranslation/repositories/EventTypeTranslationRepository.test.ts Generated by Paragon from proposal for PR #27087 * Add tests: packages/features/tasker/tasks/translateWorkflowStepData.test.ts Generated by Paragon from proposal for PR #27087 * chore: nit * chore: verfied atg * fix: set sourceLocale for new steps, add shouldDirty to checkbox, remove spec docs - Set sourceLocale fallback in addedSteps mapping to fix stale detection mismatch - Add { shouldDirty: true } to autoTranslateEnabled checkbox onChange - Remove specs/workflow-translation/ directory (planning docs, not for repo) Co-authored-by: Udit Takkar <udit.07.takkar@gmail.com> Co-Authored-By: unknown <> * chore: add specs back * fix: type error * fix: type error * fix: type err * fix: tests * refactor: feedback * fix: type err * refactor --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Udit Takkar <udit.takkar@cal.com> Co-authored-by: Udit Takkar <udit.07.takkar@gmail.com>
Cal.com api v2 is a Nest.js project.
Local development
This setup will allow you to develop with api v2 locally. If you want to also test atoms locally with platform's example app,
then proceed to apps/api/v2/README-PLATFORM.md instead.
- Install dependencies
$ yarn install
- Download and install Docker on your computer and then make sure it is running. You simply need to open Docker dashboard.
- Make sure that mailhog is running - it is used by v2 to send emails locally. You can start it by:
$ cd packages/emails && yarn dx
- Setup api v2 environment - make a copy of
apps/api/v2/.env.exampleand rename it toapps/api/v2/.env- it has almost all the required values setup - ones you need to add will be explained below.
- Then copy the value of
NEXTAUTH_SECRETfrom there to the root.envNEXTAUTH_SECRET. If you haveNEXTAUTH_SECRETalready in the root.envthen you can paste that value inapps/api/v2/.env.
Note: make sure that the value of `NEXTAUTH_SECRET` is the same in both the root `.env` and in the api v2 `.env`.
- Setup license key. In the Deployment table in database create the following entry:
id, logo, theme, licenseKey, agreedLicenseAt:-
1, null, null, '00000000-0000-0000-0000-000000000000', '2023-05-15 21:39:47.611'
Then in the apps/api/v2/.env set the license key environment variable:
CALCOM_LICENSE_KEY="00000000-0000-0000-0000-000000000000"
- (optional) Prisma setup and database seeding - if you need to setup and seed database you can do it:
$ cd packages/prisma
$ yarn prisma generate
$ yarn prisma migrate dev
$ yarn db-seed
- Proceed to the next section to start api v2
Running api v2
Start api v2 using:
$ yarn dev
Sometimes it happens that v2 api restarts because some unrelated log of build files changed if you are running it while cal web app is running. If it happens and is annoying you, you can just build it and then run without watch mode:
cd apps/api/v2
yarn dev:build
yarn start
Api v2 depends on various platform packages "platform-libraries, platform-constants, platform-enums, platform-utils, platform-types" so if any of them change you might need to restart api v2 so it rebuild these dependencies and picks up the changes.
Notably, you can run following command(in different terminal) to ensure that any change in any of the dependencies is rebuilt and detected. It watches platform-libraries, platform-constants, platform-enums, platform-utils, platform-types.
$ yarn run dev:build:watch
OR if you don't want to use docker, you can run following command.
$ yarn dev:no-docker
Test
# unit tests
$ yarn run test
# e2e tests
$ yarn run test:e2e
# run specific e2e test file in watch mode
$ yarn run test:e2e some-file.e2e-spec.ts
# test coverage
$ yarn run test:cov
Conventions
Guards
- In case a guard would return "false" for "canActivate" instead throw ForbiddenException with an error message containing guard name and the error.
- In case a guard would return "false" for "canActivate" DO NOT cache the result in redis, because we don't want that someone is forbidden, updates whatever was the problem, and then has to wait for cache to expire. We only cache in redis guard results where "canAccess" is "true".
- If you use ApiAuthGuard but want that only specific auth method is allowed, for example, api key, then you also need to add
@ApiAuthGuardOnlyAllow(["API_KEY"])under the@UseGuards(ApiAuthGuard). Shortly, useApiAuthGuardOnlyAllowto specify which auth methods are allowed byApiAuthGuard. IfApiAuthGuardOnlyAllowis not used or nothing is passed to it or empty array it means that all auth methods are allowed.