# SMS 服务文档技术栈合规性修正 **日期**: 2026-01-29 **类型**: 文档更新 **影响范围**: `docs/requirements/backend/04-services/user/sms-service.md` --- ## 变更概述 修正短信验证码服务文档,使其完全符合 jointo-tech-stack 规范,包括异步编程、依赖注入、错误处理、日志记录和测试规范。 --- ## 主要变更 ### 1. 修正导入和类型错误 **问题**: 缺少 `timezone` 导入,导致 `datetime.now(timezone.utc)` 无法使用 **修正**: ```python from datetime import datetime, timedelta, timezone # 添加 timezone from app.core.logging import logger # 添加日志记录 ``` ### 2. 优化依赖注入 **问题**: Service 层直接创建 Redis 和 HTTP 客户端,违反依赖注入原则 **修正前**: ```python def __init__(self, session: AsyncSession): self.redis_client = Redis.from_url(settings.REDIS_URL) self.http_client = httpx.AsyncClient(timeout=10.0) ``` **修正后**: ```python def __init__(self, session: AsyncSession, redis_client: Redis): self.redis_client = redis_client # 由依赖注入提供 self._http_client: Optional[httpx.AsyncClient] = None # 懒加载 @property def http_client(self) -> httpx.AsyncClient: """懒加载 HTTP 客户端""" if self._http_client is None: self._http_client = httpx.AsyncClient(timeout=10.0) return self._http_client ``` ### 3. 添加资源管理 **问题**: 缺少异步上下文管理器,资源清理不规范 **修正**: ```python async def __aenter__(self): """异步上下文管理器入口""" return self async def __aexit__(self, exc_type, exc_val, exc_tb): """异步上下文管理器退出,清理资源""" if self._http_client is not None: await self._http_client.aclose() ``` ### 4. 增强错误处理和日志 **Service 层**: ```python async def send_verification_code(...) -> dict: try: # 业务逻辑 logger.info("验证码已发送", extra={...}) return result except (RateLimitError, ValidationError): raise except Exception as e: logger.error(f"发送验证码失败: {str(e)}", exc_info=True) raise ValidationError("发送验证码失败,请稍后重试") ``` **Repository 层**: ```python async def create(self, code: SmsVerificationCode) -> SmsVerificationCode: try: self.session.add(code) await self.session.commit() await self.session.refresh(code) return code except SQLAlchemyError as e: await self.session.rollback() logger.error(f"创建验证码失败: {str(e)}", exc_info=True) raise DatabaseError("创建验证码失败") ``` ### 5. 完善 Schema 层 **问题**: 缺少 `ConfigDict` 配置和字段验证 **修正**: ```python class SmsCodeSendRequest(BaseModel): model_config = ConfigDict(populate_by_name=True) phone: str = Field(..., min_length=11, max_length=11, description="手机号") country_code: str = Field(default="+86", alias="countryCode", description="国家代码") purpose: SmsPurposeEnum = Field(default=SmsPurposeEnum.LOGIN, description="用途") @field_validator("phone") @classmethod def validate_phone(cls, v: str) -> str: if not v.isdigit(): raise ValueError("手机号必须为纯数字") return v ``` ### 6. 补充 API 路由层 **新增内容**: - 完整的 FastAPI 路由实现 - 依赖注入配置(`get_session`、`get_redis_client`) - 统一的 `ApiResponse` 响应格式 - 完整的 API 文档注释 ```python @router.post( "/sms/send", response_model=ApiResponse[SmsCodeSendResponse], summary="发送短信验证码" ) async def send_sms_code( request: Request, body: SmsCodeSendRequest, session: AsyncSession = Depends(get_session), redis_client = Depends(get_redis_client) ): service = SmsService(session, redis_client) # ... return ApiResponse.success(data=result) ``` ### 7. 添加测试规范 **新增章节**: - 单元测试示例(`test_sms_service.py`) - 集成测试示例(`test_sms_api.py`) - 测试运行命令 **测试覆盖**: - ✅ 生成验证码 - ✅ 发送验证码成功 - ✅ IP 限流 - ✅ 手机号限流 - ✅ 验证验证码成功 - ✅ 验证码错误 - ✅ 验证码过期 - ✅ API 集成测试 ### 8. 统一响应格式 **修正前**: ```json { "code": 200, "message": "Success", "data": {...} } ``` **修正后**: ```json { "code": 200, "message": "Success", "data": {...}, "timestamp": "2026-01-29T10:30:00Z" } ``` --- ## 技术栈合规性检查 ### ✅ 已符合规范 - [x] 异步编程(`async/await`、`AsyncSession`、`asyncpg`) - [x] UUID v7 主键(`generate_uuid`) - [x] 枚举类型(`IntEnum` + `SMALLINT`) - [x] 仓储模式(Service/Repository 分层) - [x] 时间戳字段(`TIMESTAMPTZ` + `timezone.utc`) - [x] 索引设计(单列、组合、条件索引) - [x] 无物理外键 - [x] Redis 异步客户端 - [x] HTTP 异步客户端 ### ✅ 新增合规项 - [x] 依赖注入(Redis 客户端由 FastAPI 提供) - [x] 资源管理(异步上下文管理器) - [x] 错误处理(`try-except` + 异常转换) - [x] 日志记录(结构化日志 + `extra` 字段) - [x] Schema 配置(`ConfigDict` + `populate_by_name`) - [x] 字段验证(`@field_validator`) - [x] API 路由层(完整实现) - [x] 统一响应格式(`ApiResponse` + `timestamp`) - [x] 测试规范(单元测试 + 集成测试) --- ## 文档结构优化 ### 新增章节 1. **API 路由层实现** - 完整的 FastAPI 路由代码 2. **依赖注入配置** - `get_session` 和 `get_redis_client` 3. **测试规范** - 单元测试和集成测试示例 ### 优化章节 1. **服务实现** - 添加文档字符串、错误处理、日志记录 2. **Schema 层** - 添加 `ConfigDict` 和字段验证 3. **Repository 层** - 添加异常处理和事务回滚 4. **API 接口** - 添加响应示例和 `timestamp` 字段 --- ## 影响评估 ### 文档变更 - **文档版本**: v2.0 → v3.0 - **最后更新**: 2026-01-26 → 2026-01-29 - **新增内容**: ~200 行代码示例和测试用例 ### 代码影响 - **无破坏性变更**: 文档修正不影响现有代码 - **建议同步**: 实际代码应参考文档进行相应优化 --- ## 后续建议 ### 1. 代码实现同步 建议按照文档规范更新实际代码: - 优化依赖注入 - 添加结构化日志 - 完善错误处理 - 补充单元测试 ### 2. 性能优化 - 考虑使用 Redis Pipeline 批量操作 - 添加验证码发送成功率监控 - 优化数据库查询索引 ### 3. 安全增强 - 添加验证码尝试次数限制 - 实现验证码加密存储 - 添加异常 IP 黑名单机制 --- ## 相关文档 - [jointo-tech-stack Skill](../../.claude/skills/jointo-tech-stack/SKILL.md) - [后端测试规范](../../.claude/skills/jointo-tech-stack/references/testing.md) - [API 设计规范](../../.claude/skills/jointo-tech-stack/references/api-design.md) - [用户管理服务](../../requirements/backend/04-services/user/user-service.md) --- **变更作者**: Kiro AI **审核状态**: 待审核 **文档版本**: v1.0