[INTS26] Set up Mailer/Send Bulk Rejection Emails - #77
Open
OwenChen07 wants to merge 1 commit into
Open
Conversation
mxc-maggiechen
marked this pull request as ready for review
August 5, 2026 01:09
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Notion ticket link
Set up Mailer/Send Bulk Rejection Emails
Implementation description
emailService.ts) rather than switching providers, and extended it withsendBulkEmail, which sends in batches of 10 and never rejects for individual failures — it returns{ sent, failed }so one bad address can't abort a whole rejection run.emails/templates/*.html+emails/index.ts) using Handlebars. Each email type is one HTML file with{{placeholders}}plus one typed builder function (e.g.buildRejectionEmail), so future devs can add new templates without touching the sending logic.bulkUpdateApplicantRecordsStatusmutation: after the status update transaction commits, any records set toREJECTEDget a templated rejection email fetched with theirApplicantdata. This is fire-and-forget — email failures are logged but never roll back the already-committed status change, and the mutation doesn't wait on send completion.invalid_grant/Testing-mode-7-day-expiry gotcha) and "how to add a new email template" indocs/mailer.md.Steps to test
cd backend/typescript && npx jest emails emailService.test applicantRecordService.test(6 tests covering template rendering, bulk-send partial failure handling, and the rejection hook's message-building/error-resilience)."""
npx ts-node -e 'import { buildRejectionEmail } from "./emails";
const { html } = buildRejectionEmail({ firstName: "Owen", position: "Developer", term: "Fall 2026" });
require("fs").writeFileSync("/tmp/rejection-preview.html", html);'
open /tmp/rejection-preview.html
"""
*The credentials in .env have expired, so I can send you the new credentials I created on Discord if you want.
"""
docker exec -i recruitment_platform_ts_backend npx ts-node -e '
import EmailService from "./services/implementations/emailService";
import nodemailerConfig from "./nodemailer.config";
import { buildRejectionEmail } from "./emails";
const svc = new EmailService(nodemailerConfig, "UW Blueprint Recruitment");
const { subject, html } = buildRejectionEmail({ firstName: "Owen", position: "Developer", term: "Fall 2026" });
svc.sendEmail("owenchenyp@gmail.com", subject, html).then(() => console.log("sent!")).catch(console.error);'
"""
What should reviewers focus on?
Checklist