docs(auth): 完善邮件注册模块注释与说明
为以下新增文件补充详细的文件头注释: - EmailVerification entity: 验证流程、字段说明、清理策略 - EmailLog entity: 审计日志、状态枚举、provider 说明 - EmailCodeService: Redis 缓存层职责、Key 模式、降级机制 - IEmailProvider: 已实现 Provider 列表、切换逻辑、扩展说明 - IEmailVerificationRepository: 关键方法说明 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9473512530
commit
ff558ab77f
|
|
@ -1,3 +1,23 @@
|
||||||
|
// ============================================================
|
||||||
|
// EmailLog Entity — 邮件发送审计日志
|
||||||
|
//
|
||||||
|
// 表名: email_logs
|
||||||
|
// 职责: 记录每一次邮件发送的完整信息,用于运营分析、问题排查、
|
||||||
|
// 以及监管合规(金融类 App 通常需要留存通信记录)。
|
||||||
|
//
|
||||||
|
// 与 SmsLog 结构对称,provider 字段区分发送渠道:
|
||||||
|
// - 'gmail' : 通过 GmailProvider (SMTP) 真实发送
|
||||||
|
// - 'console' : 开发模式 ConsoleEmailProvider(打印到控制台)
|
||||||
|
//
|
||||||
|
// providerId: Gmail 返回的 Message-ID,可用于追踪邮件投递状态。
|
||||||
|
// errorMsg: 发送失败时记录错误详情,便于排查 SMTP 配置问题。
|
||||||
|
//
|
||||||
|
// 状态枚举:
|
||||||
|
// PENDING → 刚创建(理论上不应长期停留此状态)
|
||||||
|
// SENT → Provider 成功返回,邮件已提交 SMTP
|
||||||
|
// FAILED → Provider 返回错误,邮件未发送
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Entity,
|
Entity,
|
||||||
Column,
|
Column,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,26 @@
|
||||||
|
// ============================================================
|
||||||
|
// EmailVerification Entity — 邮件验证码持久化记录
|
||||||
|
//
|
||||||
|
// 表名: email_verifications
|
||||||
|
// 职责: 持久化邮件验证码,支持多种业务场景(注册/登录/重置密码/换绑邮箱)。
|
||||||
|
// 与 SmsVerification 结构完全对称,便于统一管理和扩展。
|
||||||
|
//
|
||||||
|
// 验证流程 (Redis 快速路径 + DB 兜底):
|
||||||
|
// 1. 发送时 → create() + Redis.setCode() 同步写入
|
||||||
|
// 2. 验证时 → 先查 Redis;miss 则查 DB (findLatestValid)
|
||||||
|
// 3. 验证成功 → markVerified() + Redis.del()
|
||||||
|
// 4. 失败计数 → incrementAttempts(),超过 maxAttempts 后拒绝
|
||||||
|
//
|
||||||
|
// 关键字段:
|
||||||
|
// - code: 明文存储的 6 位数字(发送前已由 SmsCode.generate() 生成)
|
||||||
|
// - expiresAt: 过期时间(默认 300 秒)
|
||||||
|
// - verifiedAt: 验证成功时间(null = 未验证,非 null = 已使用)
|
||||||
|
// - attempts: 错误尝试次数(防爆破)
|
||||||
|
//
|
||||||
|
// 清理策略: 过期且已验证的记录由定时任务 (deleteExpired) 清理,
|
||||||
|
// 默认保留 24 小时宽限期,防止迁移/回放场景丢失记录。
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Entity,
|
Entity,
|
||||||
Column,
|
Column,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,17 @@
|
||||||
|
// ============================================================
|
||||||
|
// IEmailVerificationRepository — 邮件验证码仓储接口
|
||||||
|
//
|
||||||
|
// 与 ISmsVerificationRepository 完全对称。
|
||||||
|
// 实现: EmailVerificationRepository (TypeORM + PostgreSQL)
|
||||||
|
//
|
||||||
|
// 关键方法说明:
|
||||||
|
// create() — 写入新验证记录(每次发送新码)
|
||||||
|
// findLatestValid() — 查找最新的未过期未验证记录(DB 路径验证)
|
||||||
|
// save() — 更新 attempts/verifiedAt 字段
|
||||||
|
// getDailySendCount() — 今日发送次数,用于日限额检查
|
||||||
|
// deleteExpired() — 清理过期记录(可由定时任务调用)
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
import { EmailVerification, EmailVerificationType } from '../entities/email-verification.entity';
|
import { EmailVerification, EmailVerificationType } from '../entities/email-verification.entity';
|
||||||
|
|
||||||
export interface IEmailVerificationRepository {
|
export interface IEmailVerificationRepository {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,24 @@
|
||||||
|
// ============================================================
|
||||||
|
// IEmailProvider — 邮件发送 Provider 抽象接口
|
||||||
|
//
|
||||||
|
// 设计原则: 与 ISmsProvider 完全对称,便于扩展多渠道。
|
||||||
|
//
|
||||||
|
// 已实现的 Provider:
|
||||||
|
// GmailProvider — Gmail SMTP (production)
|
||||||
|
// 需要: GMAIL_USER + GMAIL_APP_PASSWORD
|
||||||
|
// ConsoleEmailProvider — 控制台打印 (development)
|
||||||
|
// EMAIL_ENABLED=false 时自动使用
|
||||||
|
//
|
||||||
|
// 切换逻辑 (auth.module.ts):
|
||||||
|
// process.env.EMAIL_ENABLED === 'true'
|
||||||
|
// ? GmailProvider : ConsoleEmailProvider
|
||||||
|
//
|
||||||
|
// 未来可扩展:
|
||||||
|
// SendGridProvider — 适合高并发营销邮件
|
||||||
|
// SESProvider — AWS SES,成本最低
|
||||||
|
// AliyunEmailProvider — 阿里云邮件推送(与现有 SMS 账号统一管理)
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
import { EmailVerificationType } from '../../domain/entities/email-verification.entity';
|
import { EmailVerificationType } from '../../domain/entities/email-verification.entity';
|
||||||
|
|
||||||
export interface EmailDeliveryResult {
|
export interface EmailDeliveryResult {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,24 @@
|
||||||
|
// ============================================================
|
||||||
|
// EmailCodeService — 邮件验证码 Redis 缓存层
|
||||||
|
//
|
||||||
|
// 职责: 作为 email_verifications 表的快速缓存前置层。
|
||||||
|
// - 发送验证码时: setCode() 写入 Redis,TTL = codeExpireSeconds
|
||||||
|
// - 验证时: verifyAndDelete() 先查 Redis(O(1),亚毫秒级)
|
||||||
|
// - Redis miss 时: EmailService 回退到 DB 查询(保障可靠性)
|
||||||
|
//
|
||||||
|
// Key 模式: auth:email:{TYPE}:{email}
|
||||||
|
// 示例: auth:email:REGISTER:user@example.com
|
||||||
|
// auth:email:LOGIN:user@example.com
|
||||||
|
//
|
||||||
|
// 与 SmsCodeService 完全对称,keyPrefix 改为 'auth:email:'。
|
||||||
|
// Redis 实例与 SmsCodeService 共享相同的 Redis 服务器但各自独立连接。
|
||||||
|
//
|
||||||
|
// 设计原则:
|
||||||
|
// - Redis 是缓存层,不是主存储,故障时降级到 DB 验证(不影响可用性)
|
||||||
|
// - verifyAndDelete 原子性保证验证码一次性消费
|
||||||
|
// - retryStrategy: 指数退避,最大重试间隔 2 秒
|
||||||
|
// ============================================================
|
||||||
|
|
||||||
import { Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
import { Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
||||||
import Redis from 'ioredis';
|
import Redis from 'ioredis';
|
||||||
import { EmailVerificationType } from '../../domain/entities/email-verification.entity';
|
import { EmailVerificationType } from '../../domain/entities/email-verification.entity';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue