payment confirmation for renter after rental request approval, first listing celebration email, removed burstprotection for google places autocomplete, renamed email templates

This commit is contained in:
jackiettran
2025-10-28 22:23:41 -04:00
parent 502d84a741
commit d1cb857aa7
25 changed files with 2171 additions and 53 deletions

View File

@@ -404,6 +404,9 @@ router.put("/:id/status", authenticateToken, async (req, res) => {
status: "confirmed",
paymentStatus: "paid",
stripePaymentIntentId: paymentResult.paymentIntentId,
paymentMethodBrand: paymentResult.paymentMethod?.brand || null,
paymentMethodLast4: paymentResult.paymentMethod?.last4 || null,
chargedAt: paymentResult.chargedAt || new Date(),
});
const updatedRental = await Rental.findByPk(rental.id, {
@@ -423,7 +426,58 @@ router.put("/:id/status", authenticateToken, async (req, res) => {
});
// Send confirmation emails
await emailService.sendRentalConfirmationEmails(updatedRental);
// Send approval confirmation to owner with Stripe reminder
try {
await emailService.sendRentalApprovalConfirmationEmail(updatedRental);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental approval confirmation sent to owner", {
rentalId: updatedRental.id,
ownerId: updatedRental.ownerId,
});
} catch (emailError) {
const reqLogger = logger.withRequestId(req.id);
reqLogger.error("Failed to send rental approval confirmation email to owner", {
error: emailError.message,
rentalId: updatedRental.id,
ownerId: updatedRental.ownerId,
});
}
// Send rental confirmation to renter with payment receipt
try {
const renter = await User.findByPk(updatedRental.renterId, {
attributes: ["email", "firstName"],
});
if (renter) {
const renterNotification = {
type: "rental_confirmed",
title: "Rental Confirmed",
message: `Your rental of "${updatedRental.item.name}" has been confirmed.`,
rentalId: updatedRental.id,
userId: updatedRental.renterId,
metadata: { rentalStart: updatedRental.startDateTime },
};
await emailService.sendRentalConfirmation(
renter.email,
renterNotification,
updatedRental,
renter.firstName,
true // isRenter = true to show payment receipt
);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental confirmation sent to renter", {
rentalId: updatedRental.id,
renterId: updatedRental.renterId,
});
}
} catch (emailError) {
const reqLogger = logger.withRequestId(req.id);
reqLogger.error("Failed to send rental confirmation email to renter", {
error: emailError.message,
rentalId: updatedRental.id,
renterId: updatedRental.renterId,
});
}
res.json(updatedRental);
return;
@@ -464,7 +518,58 @@ router.put("/:id/status", authenticateToken, async (req, res) => {
});
// Send confirmation emails
await emailService.sendRentalConfirmationEmails(updatedRental);
// Send approval confirmation to owner (for free rentals, no Stripe reminder shown)
try {
await emailService.sendRentalApprovalConfirmationEmail(updatedRental);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental approval confirmation sent to owner", {
rentalId: updatedRental.id,
ownerId: updatedRental.ownerId,
});
} catch (emailError) {
const reqLogger = logger.withRequestId(req.id);
reqLogger.error("Failed to send rental approval confirmation email to owner", {
error: emailError.message,
rentalId: updatedRental.id,
ownerId: updatedRental.ownerId,
});
}
// Send rental confirmation to renter
try {
const renter = await User.findByPk(updatedRental.renterId, {
attributes: ["email", "firstName"],
});
if (renter) {
const renterNotification = {
type: "rental_confirmed",
title: "Rental Confirmed",
message: `Your rental of "${updatedRental.item.name}" has been confirmed.`,
rentalId: updatedRental.id,
userId: updatedRental.renterId,
metadata: { rentalStart: updatedRental.startDateTime },
};
await emailService.sendRentalConfirmation(
renter.email,
renterNotification,
updatedRental,
renter.firstName,
true // isRenter = true (for free rentals, shows "no payment required")
);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental confirmation sent to renter", {
rentalId: updatedRental.id,
renterId: updatedRental.renterId,
});
}
} catch (emailError) {
const reqLogger = logger.withRequestId(req.id);
reqLogger.error("Failed to send rental confirmation email to renter", {
error: emailError.message,
rentalId: updatedRental.id,
renterId: updatedRental.renterId,
});
}
res.json(updatedRental);
return;
@@ -958,6 +1063,40 @@ router.post("/:id/mark-return", authenticateToken, async (req, res) => {
actualReturnDateTime: actualReturnDateTime || rental.endDateTime,
notes: notes || null,
});
// Fetch full rental details with associations for email
const rentalWithDetails = await Rental.findByPk(rentalId, {
include: [
{ model: Item, as: "item" },
{
model: User,
as: "owner",
attributes: ["id", "username", "firstName", "lastName"],
},
{
model: User,
as: "renter",
attributes: ["id", "username", "firstName", "lastName"],
},
],
});
// Send completion emails to both renter and owner
try {
await emailService.sendRentalCompletionEmails(rentalWithDetails);
const reqLogger = logger.withRequestId(req.id);
reqLogger.info("Rental completion emails sent", {
rentalId,
ownerId: rental.ownerId,
renterId: rental.renterId,
});
} catch (emailError) {
const reqLogger = logger.withRequestId(req.id);
reqLogger.error("Failed to send rental completion emails", {
error: emailError.message,
rentalId,
});
}
break;
case "damaged":