═══════════════════════════════════════════════════════════════════════ CHANGES TO YOUR EXISTING `mails` MODULE (additions only — remove nothing) ═══════════════════════════════════════════════════════════════════════ This `email-settings/` folder is the NEW standalone module. Drop it under `src/` so it sits next to your `mails/` folder: src/ email-settings/ ← this folder mails/ ← your existing module Then make 3 edits inside your existing mails module. ─────────────────────────────────────────────────────────────────────── 1) mails.service.ts — add these 2 imports at the top ─────────────────────────────────────────────────────────────────────── import { EmailSettingsService } from '../email-settings/email-settings.service'; import { EmailSettingsEntity } from '../email-settings/email-settings.entity'; (If email-settings/ and mails/ aren't siblings, fix the relative paths.) ─────────────────────────────────────────────────────────────────────── 2) mails.service.ts — add cache field + inject service in the constructor ─────────────────────────────────────────────────────────────────────── private transporter: nodemailer.Transporter; // per-user transporters, keyed by config id private readonly userTransportCache = new Map< number, { transporter: nodemailer.Transporter; from: string; signature: string } >(); constructor( private readonly emailSettings: EmailSettingsService, ) { this.transporter = this.createTransporter(); // unchanged } ─────────────────────────────────────────────────────────────────────── 3) mails.service.ts — add these 2 methods before the final closing } ─────────────────────────────────────────────────────────────────────── async sendAsUser( userId: number | null, opts: { to: string | string[]; subject: string; html?: string; text?: string; cc?: string | string[]; bcc?: string | string[]; replyTo?: string; attachments?: nodemailer.SendMailOptions['attachments']; }, ): Promise { const cfg = userId ? await this.emailSettings.getRawForUser(userId) : null; if (!cfg) { await this.transporter.sendMail({ from: this.getFromAddress(), ...opts }); this.logger.log( `Email sent via DEFAULT sender (user_id=${userId ?? 'none'}) — "${opts.subject}"`, ); return; } const { transporter, from } = this.getUserTransport(cfg); try { await transporter.sendMail({ from, ...opts }); this.logger.log( `Email sent as ${cfg.from_email} (user_id=${userId}) — "${opts.subject}"`, ); } catch (err: any) { this.userTransportCache.delete(cfg.id); this.logger.error(`sendAsUser failed via ${cfg.from_email}: ${err.message}`); throw err; } } private getUserTransport(cfg: EmailSettingsEntity) { const signature = `${cfg.smtp_host}|${cfg.smtp_port}|${cfg.smtp_username}|${ cfg.updated_at ? new Date(cfg.updated_at).getTime() : 0 }`; const cached = this.userTransportCache.get(cfg.id); if (cached && cached.signature === signature) return cached; const port = Number(cfg.smtp_port); const enc = (cfg.smtp_encryption || '').toLowerCase(); const secure = port === 465 || enc === 'ssl'; // 465=SSL, 587=STARTTLS const transporter = nodemailer.createTransport({ host: cfg.smtp_host, port, secure, auth: { user: cfg.smtp_username, pass: cfg.smtp_password }, ...(secure ? {} : { requireTLS: true }), }); const name = (cfg.from_name || '').trim(); const from = name ? `"${name}" <${cfg.from_email}>` : cfg.from_email; const entry = { transporter, from, signature }; this.userTransportCache.set(cfg.id, entry); return entry; } ─────────────────────────────────────────────────────────────────────── 4) mails.module.ts — import EmailSettingsModule ─────────────────────────────────────────────────────────────────────── import { Module } from '@nestjs/common'; import { MailsService } from './mails.service'; import { EmailSettingsModule } from '../email-settings/email-settings.module'; @Module({ imports: [EmailSettingsModule], providers: [MailsService], exports: [MailsService], }) export class MailsModule {} ─────────────────────────────────────────────────────────────────────── 5) app.module.ts — register the new module ─────────────────────────────────────────────────────────────────────── Add EmailSettingsModule to your AppModule `imports: [...]` so its controller (/email-settings routes) is active. ─────────────────────────────────────────────────────────────────────── BEFORE IT RUNS — confirm: • The 'scheme_dbs' connection name (in email-settings.entity.ts injection and email-settings.module.ts forFeature) is the DB that actually holds the email_settings table. Your screenshot shows it in `tqs`. • email_settings.user_id values match the userId you pass to sendAsUser(). • nodemailer is installed: npm i nodemailer (+ npm i -D @types/nodemailer)