Skip to content

feat(notifications): email on schedule auto-disable and 100% usage limit - #6038

Merged
TheodoreSpeaks merged 2 commits into
stagingfrom
feat/email-notify
Jul 31, 2026
Merged

feat(notifications): email on schedule auto-disable and 100% usage limit#6038
TheodoreSpeaks merged 2 commits into
stagingfrom
feat/email-notify

Conversation

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator

Summary

  • Email the workflow creator and workspace admins when Sim auto-disables a schedule — covers all nine disable paths, including the single-strike 401/403/404 ones that bypass the failure counter entirely
  • Fix the 100%-credits email skipping paid and org accounts: it was gated on isFreeUser plus scope === 'user', so a Pro user or an entire Team org got blocked at admission with no notice
  • Paid/org accounts get a new "raise your limit" email — upgrading to Pro isn't their remedy; free personal accounts keep the existing upgrade-framed one
  • Add !crosses100 to the paid 80% branch so one execution crossing both thresholds sends "reached" alone, not "nearing" and "reached" together

Notes

  • applyScheduleUpdate now returns { updated, status } and takes a disableReason. Passing a reason also adds a status <> 'disabled' guard — Postgres RETURNING yields the new row, so status === 'disabled' alone means "is disabled", not "just became disabled".
  • The stale-recovery sweep keeps its write inside the transaction and flushes notifications after commit, capped at 25 per tick.
  • One email per recipient, never a to: array — prepare.ts only checks to[0] for unsubscribe.
  • The 100% path still uses crossing detection, so it inherits the existing weaknesses (a failed send is lost; concurrent completions can double-send). Moving all four credit emails onto limit-notifications.ts's race-free claim is a follow-up.

Type of Change

  • New feature (schedule notification) + bug fix (credits gating)

Testing

  • 405 tests passing across the touched suites; new coverage for recipient resolution, the disable edge, the org fan-out, and both templates rendered for real
  • bun run lint, bun run type-check, check:api-validation:strict and the full audit suite pass
  • No migrations in this change

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 31, 2026 5:33pm

Request Review

@cursor

cursor Bot commented Jul 29, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches billing notification gating and schedule tick failure paths; email failures are isolated from ticks, but usage emails still use crossing detection without durable claim dedup (noted as follow-up).

Overview
Schedule auto-disable notifications email the schedule creator and workspace admins when Sim turns off a workflow or job schedule (repeated failures, auth/403/404, invalid schedule, etc.). Delivery goes through notifyScheduleAutoDisabled, with fan-out caps and post-commit sends during stale-recovery so mail does not run inside transactions holding locks.

Schedule failure writes are centralized on applyScheduleFailureUpdate and applyScheduleUpdate with disableReason: updates return whether the row just transitioned to disabled (status <> 'disabled' guard), and callers trigger email only on that edge. The schedule execute route and background job paths hook into this instead of duplicating failure SQL.

100% usage email fix: maybeSendUsageThresholdEmail no longer limits the exhaustion email to free personal accounts. Paid users and orgs get a new Usage limit reached template (raise limit / org billing CTA); free personal accounts still get credits-exhausted upgrade copy. Org scope fans out to admin members. Crossing 80% and 100% in one step sends only the reached email, not both warning and reached.

New React-email components, render helpers, preview routes, and tests cover templates and recipient resolution.

Reviewed by Cursor Bugbot for commit 76e6e4c. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds schedule auto-disable emails and fixes 100% usage-limit notices for paid and org accounts.

  • Notifies workflow/job creators and workspace admins when Sim auto-disables a schedule, covering consecutive-failure and single-strike (auth/authz/not-found/invalid) paths via a shared guarded update and notifyScheduleAutoDisabled
  • Detects the active→disabled edge with status <> 'disabled' plus RETURNING status; defers stale-recovery mail until after commit (cap 25)
  • Sends paid/org 100% “raise your limit” email (UsageLimitReachedEmail); free personal accounts keep credits-exhausted/upgrade copy
  • Suppresses the paid 80% warning when the same execution also crosses 100%

Confidence Score: 5/5

This PR appears safe to merge; no blocking failures remain from prior or current follow-up review.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/background/schedule-execution.ts Guaranteed disable-edge detection and optional notify on all disable-capable schedule updates; failure helper defers mail to callers.
apps/sim/lib/workflows/schedules/disable-notifications.ts Resolves creator plus workspace admins, caps fan-out, best-effort per-recipient send with fixed reason copy.
apps/sim/lib/billing/core/usage.ts 100% threshold for all plans/scopes with paid raise-limit template; 80% paid path skips when also crossing 100%.
apps/sim/app/api/schedules/execute/route.ts Setup-failure and stale-recovery paths call applyScheduleFailureUpdate and notify after disable / after commit.

Sequence Diagram

sequenceDiagram
  participant Tick as Schedule tick / job
  participant Apply as applyScheduleUpdate
  participant DB as workflow_schedule
  participant Notify as notifyScheduleAutoDisabled
  participant Mail as sendEmail

  Tick->>Apply: updates + disableReason
  Apply->>DB: "UPDATE ... status <> disabled RETURNING status"
  alt status became disabled and not deferred
    Apply->>Notify: scheduleId, reason
    Notify->>Mail: one message per recipient
  else deferred (failure helper / stale recovery)
    Tick->>Notify: after commit (capped batch)
    Notify->>Mail: one message per recipient
  end
Loading

Reviews (3): Last reviewed commit: "fix(notifications): keep partial recipie..." | Re-trigger Greptile

Comment thread apps/sim/lib/workflows/schedules/disable-notifications.ts
@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 10eb774. Configure here.

@gitguardian

gitguardian Bot commented Jul 31, 2026

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@greptile

@TheodoreSpeaks

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 76e6e4c. Configure here.

@TheodoreSpeaks
TheodoreSpeaks merged commit 648dd34 into staging Jul 31, 2026
27 checks passed
@TheodoreSpeaks
TheodoreSpeaks deleted the feat/email-notify branch July 31, 2026 20:34
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.

1 participant