email refactor

This commit is contained in:
jackiettran
2025-11-14 17:36:35 -05:00
parent 629f0055a1
commit 3a6da3d47d
25 changed files with 3176 additions and 2219 deletions

View File

@@ -3,7 +3,7 @@ const jwt = require("jsonwebtoken");
const { OAuth2Client } = require("google-auth-library");
const { User, AlphaInvitation } = require("../models"); // Import from models/index.js to get models with associations
const logger = require("../utils/logger");
const emailService = require("../services/emailService");
const emailServices = require("../services/email");
const crypto = require("crypto");
const {
@@ -117,7 +117,7 @@ router.post(
// Send verification email (don't block registration if email fails)
let verificationEmailSent = false;
try {
await emailService.sendVerificationEmail(user, user.verificationToken);
await emailServices.auth.sendVerificationEmail(user, user.verificationToken);
verificationEmailSent = true;
} catch (emailError) {
const reqLogger = logger.withRequestId(req.id);
@@ -558,7 +558,7 @@ router.post(
// Send verification email
try {
await emailService.sendVerificationEmail(user, user.verificationToken);
await emailServices.auth.sendVerificationEmail(user, user.verificationToken);
} catch (emailError) {
const reqLogger = logger.withRequestId(req.id);
reqLogger.error("Failed to resend verification email", {
@@ -726,7 +726,7 @@ router.post(
// Send password reset email
try {
await emailService.sendPasswordResetEmail(user, resetToken);
await emailServices.auth.sendPasswordResetEmail(user, resetToken);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Password reset email sent", {
@@ -868,7 +868,7 @@ router.post(
// Send password changed notification email
try {
await emailService.sendPasswordChangedEmail(user);
await emailServices.auth.sendPasswordChangedEmail(user);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Password changed notification sent", {
userId: user.id,

View File

@@ -3,7 +3,7 @@ const { Feedback, User } = require('../models');
const { authenticateToken } = require('../middleware/auth');
const { validateFeedback, sanitizeInput } = require('../middleware/validation');
const logger = require('../utils/logger');
const emailService = require('../services/emailService');
const emailServices = require('../services/email');
const router = express.Router();
// Submit new feedback
@@ -29,7 +29,7 @@ router.post('/', authenticateToken, sanitizeInput, validateFeedback, async (req,
// Send confirmation email to user
try {
await emailService.sendFeedbackConfirmation(req.user, feedback);
await emailServices.feedback.sendFeedbackConfirmation(req.user, feedback);
} catch (emailError) {
reqLogger.error("Failed to send feedback confirmation email", {
error: emailError.message,
@@ -41,7 +41,7 @@ router.post('/', authenticateToken, sanitizeInput, validateFeedback, async (req,
// Send notification email to admin
try {
await emailService.sendFeedbackNotificationToAdmin(req.user, feedback);
await emailServices.feedback.sendFeedbackNotificationToAdmin(req.user, feedback);
} catch (emailError) {
reqLogger.error("Failed to send feedback notification to admin", {
error: emailError.message,

View File

@@ -4,7 +4,7 @@ const { ForumPost, ForumComment, PostTag, User } = require('../models');
const { authenticateToken } = require('../middleware/auth');
const { uploadForumPostImages, uploadForumCommentImages } = require('../middleware/upload');
const logger = require('../utils/logger');
const emailService = require('../services/emailService');
const emailServices = require('../services/email');
const router = express.Router();
// Helper function to build nested comment tree
@@ -489,7 +489,7 @@ router.patch('/posts/:id/accept-answer', authenticateToken, async (req, res) =>
// Only send email if not marking your own comment as answer
if (comment && comment.authorId !== req.user.id) {
await emailService.sendForumAnswerAcceptedNotification(
await emailServices.forum.sendForumAnswerAcceptedNotification(
comment.author,
postAuthor,
post,
@@ -617,7 +617,7 @@ router.post('/posts/:id/comments', authenticateToken, uploadForumCommentImages,
// Send reply notification if not replying to yourself
if (parentComment && parentComment.authorId !== req.user.id) {
await emailService.sendForumReplyNotification(
await emailServices.forum.sendForumReplyNotification(
parentComment.author,
commenter,
postWithAuthor,
@@ -629,7 +629,7 @@ router.post('/posts/:id/comments', authenticateToken, uploadForumCommentImages,
} else {
// Send comment notification to post author if not commenting on your own post
if (postWithAuthor.authorId !== req.user.id) {
await emailService.sendForumCommentNotification(
await emailServices.forum.sendForumCommentNotification(
postWithAuthor.author,
commenter,
postWithAuthor,
@@ -662,7 +662,7 @@ router.post('/posts/:id/comments', authenticateToken, uploadForumCommentImages,
// Send thread activity notifications to all unique participants
for (const participant of participants) {
if (participant.author) {
await emailService.sendForumThreadActivityNotification(
await emailServices.forum.sendForumThreadActivityNotification(
participant.author,
commenter,
postWithAuthor,

View File

@@ -238,8 +238,8 @@ router.post("/", authenticateToken, requireVerifiedEmail, async (req, res) => {
// If first listing, send celebration email
if (ownerItemCount === 1) {
try {
const emailService = require("../services/emailService");
await emailService.sendFirstListingCelebrationEmail(
const emailServices = require("../services/email");
await emailServices.userEngagement.sendFirstListingCelebrationEmail(
itemWithOwner.owner,
itemWithOwner
);

View File

@@ -6,7 +6,7 @@ const { uploadMessageImage } = require('../middleware/upload');
const logger = require('../utils/logger');
const { emitNewMessage, emitMessageRead } = require('../sockets/messageSocket');
const { Op } = require('sequelize');
const emailService = require('../services/emailService');
const emailServices = require('../services/email');
const fs = require('fs');
const path = require('path');
const router = express.Router();
@@ -293,7 +293,7 @@ router.post('/', authenticateToken, uploadMessageImage, async (req, res) => {
attributes: ['id', 'firstName', 'lastName', 'email']
});
await emailService.sendNewMessageNotification(receiver, sender, message);
await emailServices.messaging.sendNewMessageNotification(receiver, sender, message);
} catch (emailError) {
// Log email error but don't block the message send
const reqLogger = logger.withRequestId(req.id);

View File

@@ -7,7 +7,7 @@ const RentalDurationCalculator = require("../utils/rentalDurationCalculator");
const RefundService = require("../services/refundService");
const LateReturnService = require("../services/lateReturnService");
const DamageAssessmentService = require("../services/damageAssessmentService");
const emailService = require("../services/emailService");
const emailServices = require("../services/email");
const logger = require("../utils/logger");
const router = express.Router();
@@ -302,7 +302,7 @@ router.post("/", authenticateToken, requireVerifiedEmail, async (req, res) => {
// Send rental request notification to owner
try {
await emailService.sendRentalRequestEmail(rentalWithDetails);
await emailServices.rentalFlow.sendRentalRequestEmail(rentalWithDetails.owner, rentalWithDetails.renter, rentalWithDetails);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental request notification sent to owner", {
rentalId: rental.id,
@@ -320,7 +320,7 @@ router.post("/", authenticateToken, requireVerifiedEmail, async (req, res) => {
// Send rental request confirmation to renter
try {
await emailService.sendRentalRequestConfirmationEmail(rentalWithDetails);
await emailServices.rentalFlow.sendRentalRequestConfirmationEmail(rentalWithDetails.renter, rentalWithDetails);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental request confirmation sent to renter", {
rentalId: rental.id,
@@ -444,7 +444,7 @@ router.put("/:id/status", authenticateToken, async (req, res) => {
// Send confirmation emails
// Send approval confirmation to owner with Stripe reminder
try {
await emailService.sendRentalApprovalConfirmationEmail(updatedRental);
await emailServices.rentalFlow.sendRentalApprovalConfirmationEmail(updatedRental.owner, updatedRental.renter, updatedRental);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental approval confirmation sent to owner", {
rentalId: updatedRental.id,
@@ -473,7 +473,7 @@ router.put("/:id/status", authenticateToken, async (req, res) => {
userId: updatedRental.renterId,
metadata: { rentalStart: updatedRental.startDateTime },
};
await emailService.sendRentalConfirmation(
await emailServices.rentalFlow.sendRentalConfirmation(
renter.email,
renterNotification,
updatedRental,
@@ -536,7 +536,7 @@ router.put("/:id/status", authenticateToken, async (req, res) => {
// Send confirmation emails
// Send approval confirmation to owner (for free rentals, no Stripe reminder shown)
try {
await emailService.sendRentalApprovalConfirmationEmail(updatedRental);
await emailServices.rentalFlow.sendRentalApprovalConfirmationEmail(updatedRental.owner, updatedRental.renter, updatedRental);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental approval confirmation sent to owner", {
rentalId: updatedRental.id,
@@ -565,7 +565,7 @@ router.put("/:id/status", authenticateToken, async (req, res) => {
userId: updatedRental.renterId,
metadata: { rentalStart: updatedRental.startDateTime },
};
await emailService.sendRentalConfirmation(
await emailServices.rentalFlow.sendRentalConfirmation(
renter.email,
renterNotification,
updatedRental,
@@ -686,7 +686,7 @@ router.put("/:id/decline", authenticateToken, async (req, res) => {
// Send decline notification email to renter
try {
await emailService.sendRentalDeclinedEmail(updatedRental, reason);
await emailServices.rentalFlow.sendRentalDeclinedEmail(updatedRental.renter, updatedRental, reason);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental decline notification sent to renter", {
rentalId: rental.id,
@@ -1060,7 +1060,9 @@ router.post("/:id/cancel", authenticateToken, async (req, res) => {
// Send cancellation notification emails
try {
await emailService.sendRentalCancellationEmails(
await emailServices.rentalFlow.sendRentalCancellationEmails(
updatedRental.owner,
updatedRental.renter,
updatedRental,
result.refund
);
@@ -1153,7 +1155,7 @@ router.post("/:id/mark-return", authenticateToken, async (req, res) => {
// Send completion emails to both renter and owner
try {
await emailService.sendRentalCompletionEmails(rentalWithDetails);
await emailServices.rentalFlow.sendRentalCompletionEmails(rentalWithDetails.owner, rentalWithDetails.renter, rentalWithDetails);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental completion emails sent", {
rentalId,
@@ -1221,7 +1223,9 @@ router.post("/:id/mark-return", authenticateToken, async (req, res) => {
});
// Send notification to customer service
await emailService.sendLostItemToCustomerService(updatedRental);
const owner = await User.findByPk(rental.ownerId);
const renter = await User.findByPk(rental.renterId);
await emailServices.customerService.sendLostItemToCustomerService(updatedRental, owner, renter);
break;
default: