Skip to content

Comments

feat: add tasker integration for proration email notifications#27247

Merged
sean-brydon merged 11 commits intomainfrom
feat/proration-tasker-integration
Feb 3, 2026
Merged

feat: add tasker integration for proration email notifications#27247
sean-brydon merged 11 commits intomainfrom
feat/proration-tasker-integration

Conversation

@sean-brydon
Copy link
Member

@sean-brydon sean-brydon commented Jan 26, 2026

What does this PR do?

Add task handlers for proration billing email flow:

  • sendProrationInvoiceEmail: Sends invoice email and schedules 7-day reminder
  • sendProrationReminderEmail: Sends reminder if invoice still unpaid
  • cancelProrationReminder: Cancels scheduled reminder on payment success

Also adds:

  • ProrationEmailService class to encapsulate email sending logic
  • findForEmail repository method with selective field fetching
  • i18n translation keys for email plain-text bodies

Usage

The calling job should trigger these tasks:

  1. After MonthlyProrationService.createProrationForTeam() succeeds with invoice:
await tasker.create("sendProrationInvoiceEmail", {
  prorationId,
  teamId,
  isAutoCharge
});
  1. After handleProrationPaymentSuccess() to cancel reminder:
await tasker.create("cancelProrationReminder", { prorationId });

Depends on: #27246

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. N/A - internal billing feature
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Verify task handlers are registered correctly in packages/features/tasker/tasks/index.ts
  • Verify reminder scheduling works (7 days delay)
  • Verify reminder cancellation on payment success
  • Type check passes (yarn type-check:ci)

Human Review Checklist

  • Verify the tasker import pattern uses { default: tasker } (fixed during merge conflict resolution)
  • Verify i18n translation keys in common.json match usage in email templates
  • Verify ProrationEmailService dynamic imports resolve correctly at runtime

Link to Devin run: https://app.devin.ai/sessions/5cb6b29d86024b0599fe41e3f99a5b29
Requested by: unknown ()

@sean-brydon sean-brydon force-pushed the feat/proration-email-templates branch from 8f29823 to 9f69f09 Compare January 26, 2026 14:17
@sean-brydon sean-brydon force-pushed the feat/proration-tasker-integration branch from 08d3c7c to a2231c2 Compare January 26, 2026 14:18
@sean-brydon sean-brydon force-pushed the feat/proration-email-templates branch from 9f69f09 to fea5046 Compare January 26, 2026 14:20
@sean-brydon sean-brydon force-pushed the feat/proration-tasker-integration branch from a2231c2 to 3e59fae Compare January 26, 2026 14:20
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>
@sean-brydon sean-brydon force-pushed the feat/proration-email-templates branch from fea5046 to b23fdaa Compare January 26, 2026 14:26
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>
@sean-brydon sean-brydon force-pushed the feat/proration-tasker-integration branch from 3e59fae to 49c35ca Compare January 26, 2026 14:27
Base automatically changed from feat/proration-email-templates to main January 27, 2026 09:28
@sean-brydon sean-brydon marked this pull request as ready for review January 27, 2026 11:03
@graphite-app graphite-app bot added consumer core area: core, team members only labels Jan 27, 2026
@graphite-app graphite-app bot requested a review from a team January 27, 2026 11:04
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

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.

@github-actions
Copy link
Contributor

Devin AI is resolving merge conflicts

This PR has merge conflicts with the main branch. A Devin session has been created to automatically resolve them.

View Devin Session

Devin will:

  1. Merge the latest main into this branch
  2. Resolve any conflicts intelligently
  3. Run lint/type checks to ensure validity
  4. Push the resolved changes

If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself.

@graphite-app graphite-app bot requested a review from a team January 29, 2026 14:38
@sean-brydon sean-brydon marked this pull request as draft January 29, 2026 14:38
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

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.

@github-actions
Copy link
Contributor

Devin AI is addressing Cubic AI's review feedback

A Devin session has been created to address the issues identified by Cubic AI.

View Devin Session

@devin-ai-integration
Copy link
Contributor

Cubic AI Review Feedback Analysis

I reviewed the two issues identified by Cubic AI in the latest review:

  1. cancelProrationReminder.ts:15 - runs.list pagination concern

    • Confidence score: 7/10
  2. ProrationEmailService.ts:40 - Non-auto-charge reminder scheduling concern

    • Confidence score: 6/10

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.

@sean-brydon sean-brydon marked this pull request as ready for review February 2, 2026 08:48
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 27 files

eunjae-lee
eunjae-lee previously approved these changes Feb 2, 2026
Copy link
Contributor

@eunjae-lee eunjae-lee left a comment

Choose a reason for hiding this comment

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

working well !

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

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.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 2, 2026

Devin AI is addressing Cubic AI's review feedback

A Devin session has been created to address the issues identified by Cubic AI.

View Devin Session

@github-actions github-actions bot marked this pull request as draft February 2, 2026 14:09
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 <>
@sean-brydon sean-brydon marked this pull request as ready for review February 2, 2026 14:26
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 28 files

@sean-brydon sean-brydon merged commit 52f3dda into main Feb 3, 2026
53 checks passed
@sean-brydon sean-brydon deleted the feat/proration-tasker-integration branch February 3, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

consumer core area: core, team members only ready-for-e2e size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants