Skip to content

SMS workflow reminder retry count tracking#3

Open
akshayutture-augment wants to merge 1 commit into
sms-retry-basefrom
sms-retry-enhanced
Open

SMS workflow reminder retry count tracking#3
akshayutture-augment wants to merge 1 commit into
sms-retry-basefrom
sms-retry-enhanced

Conversation

@akshayutture-augment

@akshayutture-augment akshayutture-augment commented Nov 14, 2025

Copy link
Copy Markdown

Test 9

Summary by CodeRabbit

  • New Features

    • SMS reminders now include automatic retry logic when scheduling fails.
    • Added retry count tracking to help manage reminder delivery attempts.
  • Improvements

    • Enhanced cleanup process for past-due SMS reminders.
    • Improved error handling during SMS reminder scheduling.

✏️ Tip: You can customize this high-level summary in your review settings.


Replicated from ai-code-review-evaluation/cal.com-coderabbit#9

* add retry count to workflow reminder

* add logic to for retry count

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
@akshayutture-augment

Copy link
Copy Markdown
Author

@coderabbitai review

@akshayutture-augment

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 18, 2025

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Nov 18, 2025

Copy link
Copy Markdown

Walkthrough

This PR adds retry count tracking to SMS reminders by introducing a new retryCount field to the WorkflowReminder database model and migration. The SMS scheduling logic is enhanced to track, increment, and manage retry attempts when delivery fails or scheduling is unsuccessful.

Changes

Cohort / File(s) Change Summary
Database Schema Updates
packages/prisma/migrations/20240508134359_add_retry_count_to_workflow_reminder/migration.sql, packages/prisma/schema.prisma
Added new retryCount integer column to WorkflowReminder table with default value of 0
SMS Reminder Scheduling Logic
packages/features/ee/workflows/api/scheduleSMSReminders.ts
Enhanced delete logic to remove reminders with retryCount > 1 or past-due; extended reminder collection to include retryCount field; added retry count increment on scheduling failures and errors; improved control flow for empty reminder sets

Sequence Diagram

sequenceDiagram
    participant API as SMS Scheduler
    participant DB as Database
    participant SMS as SMS Service
    
    API->>DB: Fetch unscheduled reminders with retryCount
    DB-->>API: Return reminders list
    
    loop For each reminder
        API->>SMS: Attempt to schedule SMS
        alt Scheduling successful
            SMS-->>API: scheduledSMS returned
            API->>DB: Record scheduled SMS
        else Scheduling returns null
            API->>DB: Increment retryCount
            Note over DB: Reminder queued for retry
        end
    end
    
    alt Any error during scheduling
        API->>DB: Increment retryCount for affected reminder
    end
    
    API->>DB: Delete reminders where retryCount > 1 OR scheduledDate is past
    DB-->>API: Deletion complete
    API-->>API: Return 200 status with message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Conditional delete logic: Verify both OR conditions (retryCount > 1 and past-due dates) are correctly applied
  • Retry increment placement: Ensure retryCount is incremented in all failure paths (null scheduledSMS return and caught errors)
  • Type safety: Confirm PartialWorkflowReminder extended with retryCount maintains type consistency across the function
  • Data flow: Validate that reminders with high retry counts are properly cleaned up to prevent indefinite accumulation

Poem

🐰 A hop, a retry, a count kept true,
When messages stumble, we try anew!
Each failed attempt leaves a mark so bright,
Till reminders rest after their retry flight. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: adding retry count tracking to SMS workflow reminders across the schema, migration, and scheduling logic.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sms-retry-enhanced

Comment @coderabbitai help to get the list of available commands and usage tips.

@akshayutture-augment

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 21, 2025

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 (3)
packages/features/ee/workflows/api/scheduleSMSReminders.ts (3)

39-41: Consider making max retry attempts configurable.

The current threshold of retryCount > 1 allows only one retry attempt before deletion. For transient failures (network issues, rate limits, temporary service outages), a single retry may be insufficient. Consider:

  1. Increasing the threshold to allow more retries (e.g., retryCount > 3 for up to 3 retries)
  2. Making this configurable via environment variable or workflow settings
  3. Adding exponential backoff between retries if not already implemented

Example with configurable max retries:

+const MAX_SMS_RETRY_ATTEMPTS = parseInt(process.env.MAX_SMS_RETRY_ATTEMPTS || "3", 10);
+
 async function handler(req: NextApiRequest, res: NextApiResponse) {
   // ...
   await prisma.workflowReminder.deleteMany({
     where: {
       OR: [
         {
           method: WorkflowMethods.SMS,
           scheduledDate: {
             lte: dayjs().toISOString(),
           },
         },
         {
           method: WorkflowMethods.SMS,
           retryCount: {
-            gt: 1,
+            gt: MAX_SMS_RETRY_ATTEMPTS,
           },
         },
       ],
     },
   });

178-187: Add logging when scheduling fails and retry is triggered.

When scheduling fails (scheduledSMS is falsy), the retryCount is incremented silently. Adding logging here would improve observability and help diagnose recurring scheduling failures.

Apply this diff:

        } else {
+         console.log(`SMS scheduling failed for reminder ${reminder.id}, incrementing retryCount to ${reminder.retryCount + 1}`);
          await prisma.workflowReminder.update({
            where: {
              id: reminder.id,
            },
            data: {
              retryCount: reminder.retryCount + 1,
            },
          });
        }

189-199: Enhance error logging with reminder context.

The current error log doesn't include which reminder failed, making it difficult to debug issues. Include reminder details such as reminder.id and reminder.bookingUid for better traceability.

Apply this diff:

     } catch (error) {
       await prisma.workflowReminder.update({
         where: {
           id: reminder.id,
         },
         data: {
           retryCount: reminder.retryCount + 1,
         },
       });
-      console.log(`Error scheduling SMS with error ${error}`);
+      console.log(`Error scheduling SMS for reminder ${reminder.id} (booking: ${reminder.booking?.uid}), retryCount: ${reminder.retryCount + 1}, error: ${error}`);
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 917c7b0 and 2dae0bf.

📒 Files selected for processing (3)
  • packages/features/ee/workflows/api/scheduleSMSReminders.ts (3 hunks)
  • packages/prisma/migrations/20240508134359_add_retry_count_to_workflow_reminder/migration.sql (1 hunks)
  • packages/prisma/schema.prisma (1 hunks)
🔇 Additional comments (3)
packages/prisma/migrations/20240508134359_add_retry_count_to_workflow_reminder/migration.sql (1)

1-2: LGTM!

The migration correctly adds the retryCount column with appropriate constraints (NOT NULL with DEFAULT 0) to track retry attempts for workflow reminders.

packages/prisma/schema.prisma (1)

1000-1000: LGTM!

The retryCount field addition aligns with the database migration and follows the appropriate Prisma schema conventions.

packages/features/ee/workflows/api/scheduleSMSReminders.ts (1)

56-60: LGTM!

Extending the select to include retryCount and properly typing the result is correct.

Comment on lines 29 to 45
await prisma.workflowReminder.deleteMany({
where: {
method: WorkflowMethods.SMS,
scheduledDate: {
lte: dayjs().toISOString(),
},
OR: [
{
method: WorkflowMethods.SMS,
scheduledDate: {
lte: dayjs().toISOString(),
},
},
{
retryCount: {
gt: 1,
},
},
],
},
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Delete condition affects all reminder methods, not just SMS.

The retryCount > 1 condition (lines 39-41) doesn't filter by method, which means reminders of any type (EMAIL, WHATSAPP, SMS) with retryCount > 1 will be deleted. This could inadvertently delete non-SMS reminders that shouldn't be affected by this SMS-specific cleanup logic.

Apply this diff to scope the retry-based deletion to SMS reminders only:

     OR: [
       {
         method: WorkflowMethods.SMS,
         scheduledDate: {
           lte: dayjs().toISOString(),
         },
       },
       {
+        method: WorkflowMethods.SMS,
         retryCount: {
           gt: 1,
         },
       },
     ],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await prisma.workflowReminder.deleteMany({
where: {
method: WorkflowMethods.SMS,
scheduledDate: {
lte: dayjs().toISOString(),
},
OR: [
{
method: WorkflowMethods.SMS,
scheduledDate: {
lte: dayjs().toISOString(),
},
},
{
retryCount: {
gt: 1,
},
},
],
},
});
await prisma.workflowReminder.deleteMany({
where: {
OR: [
{
method: WorkflowMethods.SMS,
scheduledDate: {
lte: dayjs().toISOString(),
},
},
{
method: WorkflowMethods.SMS,
retryCount: {
gt: 1,
},
},
],
},
});
🤖 Prompt for AI Agents
In packages/features/ee/workflows/api/scheduleSMSReminders.ts around lines 29 to
45, the deleteMany filter currently deletes any reminder with retryCount > 1
regardless of method; narrow the second OR clause so it only matches SMS
reminders by adding method: WorkflowMethods.SMS to that object (i.e., make the
retryCount condition include method === WorkflowMethods.SMS) so only SMS
reminders are removed by this cleanup.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants