Overview
nodemailer is installed but never configured. Email is required for: password reset links, 2FA backup codes, maintenance due alerts, warranty expiry notifications, and scheduled report delivery. This issue creates the shared mail infrastructure.
Context
package.json has nodemailer@7.0.12
backend/.env.example already defines MAIL_FROM, SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASS
- Email sending must be async (enqueued via BullMQ from BE-04) so it never blocks HTTP responses
- Templates must be clean and branded — include AssetsUp name, relevant details, and a clear call-to-action
Acceptance Criteria
Overview
nodemaileris installed but never configured. Email is required for: password reset links, 2FA backup codes, maintenance due alerts, warranty expiry notifications, and scheduled report delivery. This issue creates the shared mail infrastructure.Context
package.jsonhasnodemailer@7.0.12backend/.env.examplealready definesMAIL_FROM,SMTP_HOST,SMTP_PORT,SMTP_SECURE,SMTP_USER,SMTP_PASSAcceptance Criteria
src/mail/mail.module.tsandsrc/mail/mail.service.tsusingnodemailer.createTransport()with SMTP config fromConfigServicesrc/mail/templates/directory with HTML string templates for:welcome.ts,password-reset.ts,otp-code.ts,maintenance-alert.ts,warranty-alert.tsMailService.sendMail({ to, subject, html })wraps the transporter and catches SMTP errors without crashing the appsrc/mail/mail.processor.ts) that dequeues and sends email jobs from theMAIL_QUEUEMailModuletoAppModuleimports and exportMailServicefor other modules to injectNODE_ENV=development, log the email content to the console instead of sending (use Ethereal Mail or similar for local testing)