feat: add tasker integration for proration email notifications#27247
feat: add tasker integration for proration email notifications#27247sean-brydon merged 11 commits intomainfrom
Conversation
8f29823 to
9f69f09
Compare
08d3c7c to
a2231c2
Compare
9f69f09 to
fea5046
Compare
a2231c2 to
3e59fae
Compare
Add email templates for monthly proration billing notifications: - ProrationInvoiceEmail: Sent when invoice is created for additional seats - ProrationReminderEmail: Sent 7 days later if invoice remains unpaid Includes: - React email templates using V2BaseEmailHtml - BaseEmail classes for rendering - Billing email service functions - Translation keys for email content Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
fea5046 to
b23fdaa
Compare
Add task handlers for proration billing email flow: - sendProrationInvoiceEmail: Sends invoice email and schedules reminder - sendProrationReminderEmail: Sends reminder if invoice still unpaid - cancelProrationReminder: Cancels scheduled reminder on payment success The calling job should trigger these tasks after: 1. MonthlyProrationService.createProrationForTeam() succeeds with invoice 2. handleProrationPaymentSuccess() is called (to cancel reminder) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3e59fae to
49c35ca
Compare
There was a problem hiding this comment.
4 issues found across 12 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/features/tasker/tasks/sendProrationReminderEmail.ts">
<violation number="1" location="packages/features/tasker/tasks/sendProrationReminderEmail.ts:19">
P2: Add a `select` clause so the proration query only retrieves the fields used by the reminder email logic.</violation>
</file>
<file name="packages/emails/templates/proration-reminder-email.ts">
<violation number="1" location="packages/emails/templates/proration-reminder-email.ts:68">
P2: The plain-text email body is hard-coded in English and does not use the existing translation keys (e.g., `proration_reminder_message`), so localized users will receive untranslated content. Please fetch the copy through `this.user.t(...)` like the HTML template does.</violation>
</file>
<file name="packages/emails/templates/proration-invoice-email.ts">
<violation number="1" location="packages/emails/templates/proration-invoice-email.ts:75">
P2: The plain-text body is hard-coded in English and ignores the provided translation function, so recipients won’t get this email localized. Please move the string into a translation handled via t().</violation>
</file>
<file name="packages/features/tasker/tasks/sendProrationInvoiceEmail.ts">
<violation number="1" location="packages/features/tasker/tasks/sendProrationInvoiceEmail.ts:22">
P2: Prisma query fetches all columns but only uses 4 fields. Add a `select` clause to fetch only the required fields (`invoiceId`, `monthKey`, `netSeatIncrease`, `proratedAmount`) for better performance and reduced data exposure.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Devin AI is resolving merge conflictsThis PR has merge conflicts with the Devin will:
If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself. |
Co-Authored-By: unknown <>
There was a problem hiding this comment.
2 issues found across 17 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/features/ee/billing/service/proration/tasker/trigger/cancelProrationReminder.ts">
<violation number="1" location="packages/features/ee/billing/service/proration/tasker/trigger/cancelProrationReminder.ts:15">
P2: `runs.list` only returns the first page; this cancels reminders only from that page and can miss scheduled runs beyond the initial page. Use auto-pagination (`for await`) or manual pagination to ensure all matching runs are checked.</violation>
</file>
<file name="packages/features/ee/billing/service/proration/ProrationEmailService.ts">
<violation number="1" location="packages/features/ee/billing/service/proration/ProrationEmailService.ts:40">
P2: Non-auto-charge invoices no longer schedule the 7‑day reminder when `sendProrationInvoiceEmail` runs. After sending the invoice email, the method returns without any reminder scheduling, and the task wrapper only calls this method, so reminders are skipped for workflows that call the task directly.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
packages/features/ee/billing/service/proration/tasker/trigger/cancelProrationReminder.ts
Outdated
Show resolved
Hide resolved
Devin AI is addressing Cubic AI's review feedbackA Devin session has been created to address the issues identified by Cubic AI. |
Cubic AI Review Feedback AnalysisI reviewed the two issues identified by Cubic AI in the latest review:
Both issues have confidence scores below the 9/10 threshold required for automated fixes. These should be reviewed manually by a human reviewer to determine if they are valid concerns that need to be addressed. |
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="packages/features/ee/teams/repositories/TeamRepository.ts">
<violation number="1" location="packages/features/ee/teams/repositories/TeamRepository.ts:624">
P1: The added JOIN reuses alias `u`, which makes the raw SQL invalid and will throw at runtime. Remove the duplicate join or use a distinct alias if you need both tables.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Devin AI is addressing Cubic AI's review feedbackA Devin session has been created to address the issues identified by Cubic AI. |
The raw SQL query had two INNER JOINs using the same alias 'u':
- INNER JOIN "users" u ON m."userId" = u.id
- INNER JOIN "User" u ON m."userId" = u.id
This would cause a SQL error at runtime. Removed the duplicate JOIN
with incorrect table name ("User" instead of "users").
Fixes issue identified by Cubic AI review.
Co-Authored-By: unknown <>
What does this PR do?
Add task handlers for proration billing email flow:
sendProrationInvoiceEmail: Sends invoice email and schedules 7-day remindersendProrationReminderEmail: Sends reminder if invoice still unpaidcancelProrationReminder: Cancels scheduled reminder on payment successAlso adds:
ProrationEmailServiceclass to encapsulate email sending logicfindForEmailrepository method with selective field fetchingUsage
The calling job should trigger these tasks:
MonthlyProrationService.createProrationForTeam()succeeds with invoice:handleProrationPaymentSuccess()to cancel reminder:Depends on: #27246
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
packages/features/tasker/tasks/index.tsyarn type-check:ci)Human Review Checklist
{ default: tasker }(fixed during merge conflict resolution)common.jsonmatch usage in email templatesProrationEmailServicedynamic imports resolve correctly at runtimeLink to Devin run: https://app.devin.ai/sessions/5cb6b29d86024b0599fe41e3f99a5b29
Requested by: unknown ()