Skip to content

Comments

chore: Remove SendGrid related code from emailReminderManager#23591

Merged
emrysal merged 9 commits intomainfrom
chore/use-smtp-workflow-reminders
Sep 4, 2025
Merged

chore: Remove SendGrid related code from emailReminderManager#23591
emrysal merged 9 commits intomainfrom
chore/use-smtp-workflow-reminders

Conversation

@emrysal
Copy link
Contributor

@emrysal emrysal commented Sep 4, 2025

What does this PR do?

Removing code as I was about to change the following; which made less sense than complete removal.

if (isWorkflowSmtpEmailsEnabled || !isSendgridEnabled) {

to

if (true || !isSendgridEnabled) {

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 4, 2025

Walkthrough

Removed SendGrid-specific branching and feature-flag gating from the workflows email reminder flow and consolidated it to a single pathway using sendOrScheduleWorkflowEmails. scheduleEmailReminder no longer accepts userId, teamId, or isMandatoryReminder; call sites across round-robin, reminderScheduler, scheduleMandatoryReminder, viewer routers, and activateEventType.handler were updated accordingly. When scheduledDate is present a workflowReminder row is created and its UUID is used as referenceUid for scheduling. SendGrid imports, scheduling logic, currentDate computation, SendGrid tests, and SendGrid-specific env mocks were removed. SMS scheduling call sites no longer forward userId/teamId.

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/use-smtp-workflow-reminders

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@graphite-app graphite-app bot requested a review from a team September 4, 2025 14:54
@keithwillcode keithwillcode added core area: core, team members only foundation labels Sep 4, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 472ffef and 27aa5b0.

📒 Files selected for processing (1)
  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧠 Learnings (1)
📚 Learning: 2025-08-19T08:45:41.834Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/ee/workflows/lib/reminders/aiPhoneCallManager.ts:167-193
Timestamp: 2025-08-19T08:45:41.834Z
Learning: In calcom/cal.com AI phone call scheduling (aiPhoneCallManager.ts), workflow reminder records are intentionally kept in the database even when task scheduling fails, as they provide valuable debugging information for troubleshooting scheduling issues, per maintainer Udit-takkar in PR #22995.

Applied to files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧬 Code graph analysis (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)
packages/features/ee/workflows/lib/reminders/providers/emailProvider.ts (1)
  • sendOrScheduleWorkflowEmails (9-31)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Detect changes
🔇 Additional comments (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)

283-288: Ignore redundant shouldSchedule suggestion
The proposed shouldSchedule variable doesn’t exist and reminderUid is already undefined when no reminder is created, so introducing a non-existent flag is unnecessary. Disregard this change.

Likely an incorrect or invalid review comment.

import { getTranslation } from "@calcom/lib/server/i18n";
import prisma from "@calcom/prisma";
import type { TimeUnit } from "@calcom/prisma/enums";
import type { TimeUnit } from "@calcom/prisma";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Confirm TimeUnit source and make unit normalization deterministic.

  • Verify that @calcom/prisma is the intended source for TimeUnit (vs. @calcom/prisma/enums or generated client types). Mismatched enum sources can break the .toLocaleLowerCase() mapping later.
  • Prefer .toLowerCase() over .toLocaleLowerCase() to avoid locale-dependent surprises.

Apply:

-  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLocaleLowerCase() as timeUnitLowerCase;
+  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLowerCase() as timeUnitLowerCase;

Run to confirm import usage patterns:


🏁 Script executed:

#!/bin/bash
# Check all imports of TimeUnit to ensure consistency across the repo
rg -nP 'import\s+type\s*{\s*TimeUnit\s*}\s+from\s*[\"\\\'][^\"\\\']+[\"\\\']' -C2

Length of output: 116


🏁 Script executed:

#!/bin/bash
# Find all imports of TimeUnit
rg -n "import type { TimeUnit } from" -C2 --glob "*.ts"
# Find any imports from @calcom/prisma/enums"
rg -n "from '@calcom/prisma/enums'" -C2 --glob "*.ts"

Length of output: 805


🏁 Script executed:

#!/bin/bash
# Find all imports of TimeUnit across the repo
rg -F "import type { TimeUnit" -n --glob "*.ts"
# Check for any imports of TimeUnit or enums from '@calcom/prisma/enums'
rg -F "@calcom/prisma/enums" -n --glob "*.ts"
# Locate all occurrences of toLocaleLowerCase to verify usage sites
rg -n ".toLocaleLowerCase" -C2 --glob "*.ts"

Length of output: 63356


Normalize TimeUnit import source and use .toLowerCase() deterministically across all reminder managers

  • In packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (line 12), change
    import type { TimeUnit } from "@calcom/prisma";
    to
    import type { TimeUnit } from "@calcom/prisma/enums";
  • In the four EE reminder managers, replace all .toLocaleLowerCase() calls on timeSpan.timeUnit with .toLowerCase() and cast to timeUnitLowerCase:
    • emailReminderManager.ts (line 84)
    • aiPhoneCallManager.ts (line 150)
    • whatsappReminderManager.ts (line 53)
    • smsReminderManager.ts (line 122)
  • Verify each timeUnit is typed as timeUnitLowerCase | undefined after normalization.
🤖 Prompt for AI Agents
In packages/features/ee/workflows/lib/reminders/emailReminderManager.ts around
line 12 and at normalization site near line 84, change the type import from
`import type { TimeUnit } from "@calcom/prisma";` to `import type { TimeUnit }
from "@calcom/prisma/enums";`, and where you normalize `timeSpan.timeUnit`
replace any `.toLocaleLowerCase()` with `.toLowerCase()`, assign the result to a
new variable typed as `timeUnitLowerCase | undefined` (e.g., `const timeUnit:
timeUnitLowerCase | undefined = timeSpan?.timeUnit?.toLowerCase()`), and apply
the same `.toLowerCase()` replacement and typing pattern in the other EE
reminder managers at aiPhoneCallManager.ts line 150, whatsappReminderManager.ts
line 53, and smsReminderManager.ts line 122 so every `timeUnit` is
deterministically normalized and properly typed.

@vercel
Copy link

vercel bot commented Sep 4, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal Ignored Ignored Sep 4, 2025 6:46pm
cal-eu Ignored Ignored Sep 4, 2025 6:46pm

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (3)

216-217: Nit: comment still references SendGrid.

Update wording to match SMTP/tasker flow.

Apply:

-  // Allows debugging generated email content without waiting for sendgrid to send emails
+  // Allows debugging generated email content without waiting for tasker to run or SMTP to send

84-85: Use .toLowerCase() for deterministic normalization.

Avoid locale-dependent .toLocaleLowerCase().

Apply:

-  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLocaleLowerCase() as timeUnitLowerCase;
+  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLowerCase() as timeUnitLowerCase;

269-281: Set scheduled based on whether the date is in the future; avoid inconsistent rows.

Tasker drops jobs with sendAt <= now, yet we persist scheduled: true. Record should be kept but flagged correctly. This aligns with prior maintainer guidance about retaining reminders for diagnostics while reflecting reality.

Apply:

-  let reminderUid = undefined;
-  if (scheduledDate) {
+  let reminderUid: string | undefined;
+  const shouldSchedule = Boolean(scheduledDate && scheduledDate.isAfter(dayjs()));
+  if (scheduledDate) {
     const reminder = await prisma.workflowReminder.create({
       data: {
         bookingUid: uid,
         workflowStepId,
         method: WorkflowMethods.EMAIL,
         scheduledDate: scheduledDate.toDate(),
-        scheduled: true,
+        scheduled: shouldSchedule,
       },
     });
     reminderUid = reminder.uuid;
   }
🧹 Nitpick comments (3)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (3)

283-288: Only pass sendAt when the job should actually be scheduled.

Passing a past sendAt causes the provider to no-op. If product wants immediate send for past-due items, omit sendAt; otherwise, keep suppressing. Confirm desired behavior for BEFORE vs AFTER triggers.

Apply:

   await sendOrScheduleWorkflowEmails({
     ...mailData,
     to: sendTo,
-    sendAt: scheduledDate?.toDate(),
+    sendAt: shouldSchedule ? scheduledDate!.toDate() : undefined,
     referenceUid: reminderUid ?? undefined,
   });

292-296: Prisma: select only needed fields.

We only use uuid and referenceId; add select per repo guideline.

Apply:

-  const workflowReminder = await prisma.workflowReminder.findUnique({
-    where: {
-      id: reminderId,
-    },
-  });
+  const workflowReminder = await prisma.workflowReminder.findUnique({
+    where: { id: reminderId },
+    select: { uuid: true, referenceId: true },
+  });

298-301: Prefer logger over console.error.

Use the file logger for consistency.

Apply:

-  if (!workflowReminder) {
-    console.error("Workflow reminder not found");
-    return;
-  }
+  if (!workflowReminder) {
+    log.warn("Workflow reminder not found");
+    return;
+  }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 27aa5b0 and a525465.

📒 Files selected for processing (5)
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts (0 hunks)
  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1 hunks)
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.ts (0 hunks)
  • packages/features/ee/workflows/lib/reminders/scheduleMandatoryReminder.ts (0 hunks)
  • packages/trpc/server/routers/viewer/workflows/util.ts (0 hunks)
💤 Files with no reviewable changes (4)
  • packages/trpc/server/routers/viewer/workflows/util.ts
  • packages/features/ee/workflows/lib/reminders/scheduleMandatoryReminder.ts
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.ts
  • packages/features/ee/round-robin/roundRobinManualReassignment.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧠 Learnings (1)
📚 Learning: 2025-08-19T08:45:41.834Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/ee/workflows/lib/reminders/aiPhoneCallManager.ts:167-193
Timestamp: 2025-08-19T08:45:41.834Z
Learning: In calcom/cal.com AI phone call scheduling (aiPhoneCallManager.ts), workflow reminder records are intentionally kept in the database even when task scheduling fails, as they provide valuable debugging information for troubleshooting scheduling issues, per maintainer Udit-takkar in PR #22995.

Applied to files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧬 Code graph analysis (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)
packages/features/ee/workflows/lib/reminders/providers/emailProvider.ts (1)
  • sendOrScheduleWorkflowEmails (9-31)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)

12-12: LGTM on enum import source.

TimeUnit import normalized to @calcom/prisma/enums as recommended.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (3)

86-86: Use .toLowerCase() for deterministic casing.

Avoid locale-dependent .toLocaleLowerCase() here.

-  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLocaleLowerCase() as timeUnitLowerCase;
+  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLowerCase() as timeUnitLowerCase;

227-229: Nit: Update debug comment to remove “sendgrid”.

-  // Allows debugging generated email content without waiting for sendgrid to send emails
+  // Allows debugging generated email content without waiting for tasker/SMTP to send emails

280-292: Set scheduled based on future-ness; type reminderUid and add debug.

Marking scheduled: true even when sendAt is in the past leaves inconsistent rows (tasker won’t schedule). Keep the row (per team practice) but set scheduled accurately and type the uid.

-  let reminderUid = undefined;
-  if (scheduledDate) {
+  let reminderUid: string | undefined;
+  const shouldSchedule = Boolean(scheduledDate && scheduledDate.isAfter(dayjs()));
+  if (scheduledDate) {
     const reminder = await prisma.workflowReminder.create({
       data: {
         bookingUid: uid,
         workflowStepId,
         method: WorkflowMethods.EMAIL,
         scheduledDate: scheduledDate.toDate(),
-        scheduled: true,
+        scheduled: shouldSchedule,
       },
     });
     reminderUid = reminder.uuid;
+    log.debug(
+      `Created workflowReminder ${reminder.uuid} for booking ${uid} at ${scheduledDate.toDate().toISOString()} (shouldSchedule=${shouldSchedule})`
+    );
   }
🧹 Nitpick comments (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)

294-299: Confirm desired behavior for past sendAt; optionally gate scheduling.

With a past sendAt, sendOrScheduleWorkflowEmails no-ops. If that’s intended, keep as is. If you prefer immediate send when the window has passed, gate by shouldSchedule from above.

-    sendAt: scheduledDate?.toDate(),
-    referenceUid: reminderUid ?? undefined,
+    sendAt: shouldSchedule ? scheduledDate!.toDate() : undefined,
+    referenceUid: shouldSchedule ? reminderUid : undefined,
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c65054b and 20598d1.

📒 Files selected for processing (2)
  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1 hunks)
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • packages/features/ee/workflows/lib/reminders/reminderScheduler.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧠 Learnings (1)
📚 Learning: 2025-08-19T08:45:41.834Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/ee/workflows/lib/reminders/aiPhoneCallManager.ts:167-193
Timestamp: 2025-08-19T08:45:41.834Z
Learning: In calcom/cal.com AI phone call scheduling (aiPhoneCallManager.ts), workflow reminder records are intentionally kept in the database even when task scheduling fails, as they provide valuable debugging information for troubleshooting scheduling issues, per maintainer Udit-takkar in PR #22995.

Applied to files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧬 Code graph analysis (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)
packages/features/ee/workflows/lib/reminders/providers/emailProvider.ts (1)
  • sendOrScheduleWorkflowEmails (9-31)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/features/ee/workflows/lib/test/workflows.test.ts (2)

1099-1105: Strengthen the expectation to avoid false positives

Also assert call count to ensure only the unified SMTP path is hit once.

-  expect(emailProvider.sendOrScheduleWorkflowEmails).toHaveBeenCalled();
+  expect(emailProvider.sendOrScheduleWorkflowEmails).toHaveBeenCalledTimes(1);

1099-1105: Optional: Use module mocking instead of spying on the export

The test currently does

import * as emailProvider from "../reminders/providers/emailProvider";
vi.spyOn(emailProvider, "sendOrScheduleWorkflowEmails");

which only works so long as emailReminderManager.ts pulls in that named export. If you change the import style (e.g. move the function into a different module or switch to a default export), the spy will silently stop intercepting. Instead, mock the provider module at the top of the test to decouple from import details:

vi.mock("../reminders/providers/emailProvider", () => ({
  sendOrScheduleWorkflowEmails: vi.fn(),
}));

This ensures any import of that function is replaced by your mock, regardless of how the implementation imports it.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 20598d1 and d36daa7.

📒 Files selected for processing (1)
  • packages/features/ee/workflows/lib/test/workflows.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/workflows/lib/test/workflows.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/lib/test/workflows.test.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/workflows/lib/test/workflows.test.ts
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Tests / Unit
  • GitHub Check: Linters / lint
  • GitHub Check: Type check / check-types

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/features/ee/workflows/lib/test/workflows.test.ts (1)

1099-1102: Stub the provider and tighten the assertion

Avoid accidental network/side effects and assert key args.

Apply this diff to strengthen the expectation:

-    await scheduleEmailReminder(baseArgs);
-    expect(emailProvider.sendOrScheduleWorkflowEmails).toHaveBeenCalled();
+    await scheduleEmailReminder(baseArgs);
+    expect(emailProvider.sendOrScheduleWorkflowEmails).toHaveBeenCalledWith(
+      expect.objectContaining({
+        to: baseArgs.sendTo,
+        sendAt: undefined, // NEW_EVENT shouldn't schedule
+      })
+    );

Additionally, stub the spy to resolve immediately (outside this range, shown for context):

// near line 1062 or in beforeEach
vi.spyOn(emailProvider, "sendOrScheduleWorkflowEmails").mockResolvedValue(undefined as any);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d36daa7 and 5899e21.

📒 Files selected for processing (1)
  • packages/features/ee/workflows/lib/test/workflows.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/workflows/lib/test/workflows.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/lib/test/workflows.test.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/workflows/lib/test/workflows.test.ts
🧬 Code graph analysis (1)
packages/features/ee/workflows/lib/test/workflows.test.ts (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)
  • scheduleEmailReminder (61-300)
🔇 Additional comments (1)
packages/features/ee/workflows/lib/test/workflows.test.ts (1)

1099-1102: LGTM: unified SMTP path is exercised

The test now asserts the SMTP flow via sendOrScheduleWorkflowEmails; leftover SendGrid/teamId concerns are resolved.

volnei
volnei previously approved these changes Sep 4, 2025
Copy link
Contributor

@volnei volnei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@keithwillcode keithwillcode added this to the v5.7 milestone Sep 4, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Sep 4, 2025

E2E results are ready!

/**
* @deprecated only needed for SendGrid, use SMTP with tasker instead
*/
if (IMMEDIATE_WORKFLOW_TRIGGER_EVENTS.includes(triggerEvent)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@CarinaWolli CarinaWolli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this PR also cover removing the sendgrid related code in scheduleEmailReminders.ts?

@emrysal emrysal enabled auto-merge (squash) September 4, 2025 18:38
@github-actions github-actions bot marked this pull request as draft September 4, 2025 18:38
auto-merge was automatically disabled September 4, 2025 18:38

Pull request was converted to draft

CarinaWolli
CarinaWolli previously approved these changes Sep 4, 2025
@CarinaWolli CarinaWolli marked this pull request as ready for review September 4, 2025 18:41
@dosubot dosubot bot added the workflows area: workflows, automations label Sep 4, 2025
@emrysal emrysal enabled auto-merge (squash) September 4, 2025 18:43
@emrysal emrysal dismissed stale reviews from CarinaWolli and volnei via bb19be1 September 4, 2025 18:46
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (3)

85-85: Use .toLowerCase() (deterministic) instead of .toLocaleLowerCase().

Prevents locale-dependent behavior and matches enum normalization across managers.

-  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLocaleLowerCase() as timeUnitLowerCase;
+  const timeUnit: timeUnitLowerCase | undefined = timeSpan.timeUnit?.toLowerCase() as timeUnitLowerCase;

226-227: Update debug comment to reflect SMTP/tasker (no SendGrid).

Minor wording cleanup.

-  // Allows debugging generated email content without waiting for sendgrid to send emails
+  // Allows debugging generated email content without waiting for the SMTP/tasker pipeline to send emails

279-291: Don’t mark reminders as scheduled when sendAt is past; type reminderUid and gate referenceUid.

Set scheduled based on shouldSchedule and only pass referenceUid/sendAt when scheduling. Keeps the DB row for debugging while avoiding inconsistent state.

-  let reminderUid = undefined;
-  if (scheduledDate) {
+  let reminderUid: string | undefined;
+  const shouldSchedule = Boolean(scheduledDate && scheduledDate.isAfter(dayjs()));
+  if (scheduledDate) {
     const reminder = await prisma.workflowReminder.create({
       data: {
         bookingUid: uid,
         workflowStepId,
         method: WorkflowMethods.EMAIL,
         scheduledDate: scheduledDate.toDate(),
-        scheduled: true,
+        scheduled: shouldSchedule,
       },
     });
     reminderUid = reminder.uuid;
   }
 
-  await sendOrScheduleWorkflowEmails({
+  await sendOrScheduleWorkflowEmails({
     ...mailData,
     to: sendTo,
-    sendAt: scheduledDate?.toDate(),
-    referenceUid: reminderUid ?? undefined,
+    sendAt: shouldSchedule ? scheduledDate?.toDate() : undefined,
+    referenceUid: shouldSchedule ? reminderUid : undefined,
   });

Also applies to: 293-298

🧹 Nitpick comments (2)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (2)

302-307: Prisma: select only needed fields.

Avoid fetching unnecessary columns; you only use uuid and referenceId here.

-  const workflowReminder = await prisma.workflowReminder.findUnique({
-    where:
-      { id: reminderId },
-  });
+  const workflowReminder = await prisma.workflowReminder.findUnique({
+    where: { id: reminderId },
+    select: { uuid: true, referenceId: true },
+  });

309-309: Use logger instead of console.error.

Keep logging consistent and structured.

-    console.error("Workflow reminder not found");
+    log.warn("Workflow reminder not found");
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5899e21 and bb19be1.

📒 Files selected for processing (1)
  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

**/*.ts: For Prisma queries, only select data you need; never use include, always use select
Ensure the credential.key field is never returned from tRPC endpoints or APIs

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/review.mdc)

Flag excessive Day.js use in performance-critical code; prefer native Date or Day.js .utc() in hot paths like loops

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

Flag default exports and encourage named exports. Named exports provide better tree-shaking, easier refactoring, and clearer imports. Exempt main components like pages, layouts, and components that serve as the primary export of a module.

Files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧠 Learnings (1)
📚 Learning: 2025-08-19T08:45:41.834Z
Learnt from: Udit-takkar
PR: calcom/cal.com#22995
File: packages/features/ee/workflows/lib/reminders/aiPhoneCallManager.ts:167-193
Timestamp: 2025-08-19T08:45:41.834Z
Learning: In calcom/cal.com AI phone call scheduling (aiPhoneCallManager.ts), workflow reminder records are intentionally kept in the database even when task scheduling fails, as they provide valuable debugging information for troubleshooting scheduling issues, per maintainer Udit-takkar in PR #22995.

Applied to files:

  • packages/features/ee/workflows/lib/reminders/emailReminderManager.ts
🧬 Code graph analysis (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)
packages/features/ee/workflows/lib/reminders/providers/emailProvider.ts (1)
  • sendOrScheduleWorkflowEmails (9-31)
⏰ Context from checks skipped due to timeout of 180000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install dependencies / Yarn install & cache
🔇 Additional comments (1)
packages/features/ee/workflows/lib/reminders/emailReminderManager.ts (1)

89-93: Allow 0-minute offsets (don’t skip when timeSpan.time is 0)
In emailReminderManager.ts (lines 89–93), replace the truthy check timeSpan.time && timeUnit with timeSpan.time != null && timeUnit so that a zero-minute offset still schedules a reminder. Would 0-minute reminders be a valid use case in your workflows?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core area: core, team members only foundation ready-for-e2e size/L workflows area: workflows, automations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants