# 考培练系统后端开发规范 ## 1. 代码规范 ### 1.1 Python代码规范 - **格式化工具**:使用 Black 进行代码格式化,配置行长度为 88 - **导入排序**:使用 isort 进行导入排序 - **类型检查**:使用 mypy 进行静态类型检查 - **代码检查**:使用 flake8 进行代码质量检查 ### 1.2 命名规范 ```python # 文件名:使用小写字母和下划线 user_service.py # 类名:使用大驼峰命名法 class UserService: pass # 函数和变量:使用小写字母和下划线 def get_user_by_id(user_id: int) -> User: pass # 常量:使用大写字母和下划线 MAX_RETRY_COUNT = 3 # 私有成员:使用单下划线前缀 def _validate_input(data: dict) -> bool: pass ``` ### 1.3 文档字符串规范 ```python def create_user( username: str, email: str, password: str, role: UserRole = UserRole.TRAINEE ) -> User: """ 创建新用户 Args: username: 用户名,长度3-20个字符 email: 用户邮箱,必须是有效的邮箱格式 password: 密码,最少8个字符 role: 用户角色,默认为学员 Returns: User: 创建成功的用户对象 Raises: ValidationError: 输入参数验证失败 DuplicateError: 用户名或邮箱已存在 """ pass ``` ## 2. API开发规范 ### 2.1 RESTful API设计原则 - 使用名词而非动词 - 使用复数形式 - 使用标准HTTP方法 - 合理使用HTTP状态码 ```python # 好的例子 GET /api/v1/users # 获取用户列表 GET /api/v1/users/{id} # 获取单个用户 POST /api/v1/users # 创建用户 PUT /api/v1/users/{id} # 更新用户 DELETE /api/v1/users/{id} # 删除用户 # 错误的例子 GET /api/v1/getUsers # 不要使用动词 POST /api/v1/user/create # 不要在URL中包含动作 ``` ### 2.2 统一响应格式 ```python from typing import Optional, Any from pydantic import BaseModel class ResponseModel(BaseModel): """统一API响应模型""" code: int = 200 message: str = "success" data: Optional[Any] = None class ErrorResponse(BaseModel): """错误响应模型""" code: int message: str details: Optional[str] = None trace_id: Optional[str] = None # 成功响应示例 { "code": 200, "message": "success", "data": { "id": 1, "username": "张三", "email": "zhangsan@example.com" } } # 错误响应示例 { "code": 400, "message": "参数验证失败", "details": "用户名长度必须在3-20个字符之间", "trace_id": "abc123def456" } ``` ### 2.3 API版本控制 - 使用URL路径进行版本控制:`/api/v1/`, `/api/v2/` - 保持向后兼容,避免破坏性更改 - 废弃的API需要提前通知并设置过渡期 ## 3. 数据库规范 ### 3.1 表命名规范 - 使用复数形式:`users`, `courses`, `exams` - 关联表使用下划线连接:`user_courses`, `exam_questions` - 避免使用MySQL保留字 ### 3.2 字段命名规范 - 使用蛇形命名法:`user_name`, `created_at` - 主键统一使用 `id` - 外键使用 `表名_id` 格式:`user_id`, `course_id` ### 3.3 必需字段 每个表必须包含以下字段: ```sql id BIGINT PRIMARY KEY AUTO_INCREMENT -- 主键 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 创建时间 updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新时间 created_by BIGINT -- 创建人ID(可选) updated_by BIGINT -- 更新人ID(可选) is_deleted BOOLEAN DEFAULT FALSE -- 软删除标记(如需要) ``` ### 3.4 索引规范 - 为外键字段创建索引 - 为经常查询的字段创建索引 - 避免创建过多索引影响写入性能 - 索引命名:`idx_表名_字段名` ## 4. 异常处理规范 ### 4.1 自定义异常类 ```python # app/core/exceptions.py class BaseAPIException(Exception): """API异常基类""" def __init__( self, code: int, message: str, details: str = None ): self.code = code self.message = message self.details = details super().__init__(message) class ValidationError(BaseAPIException): """参数验证异常""" def __init__(self, message: str, details: str = None): super().__init__(400, message, details) class NotFoundError(BaseAPIException): """资源不存在异常""" def __init__(self, resource: str): super().__init__(404, f"{resource}不存在") class PermissionError(BaseAPIException): """权限不足异常""" def __init__(self, message: str = "权限不足"): super().__init__(403, message) ``` ### 4.2 全局异常处理 ```python # app/core/middleware.py from fastapi import Request from fastapi.responses import JSONResponse async def global_exception_handler(request: Request, exc: Exception): """全局异常处理器""" if isinstance(exc, BaseAPIException): return JSONResponse( status_code=exc.code, content={ "code": exc.code, "message": exc.message, "details": exc.details, "trace_id": request.state.trace_id } ) # 记录未预期的异常 logger.error(f"未处理的异常: {exc}", exc_info=True) return JSONResponse( status_code=500, content={ "code": 500, "message": "服务器内部错误", "trace_id": request.state.trace_id } ) ``` ## 5. 日志规范 ### 5.1 日志级别使用 - **DEBUG**: 调试信息,仅在开发环境使用 - **INFO**: 一般信息,如API请求、重要业务操作 - **WARNING**: 警告信息,如已废弃的API调用 - **ERROR**: 错误信息,需要关注但不影响系统运行 - **CRITICAL**: 严重错误,可能导致系统无法正常运行 ### 5.2 结构化日志 ```python import structlog logger = structlog.get_logger() # 使用结构化日志 logger.info( "用户登录成功", user_id=user.id, username=user.username, ip_address=request.client.host, user_agent=request.headers.get("user-agent") ) # 记录错误信息 logger.error( "数据库连接失败", error=str(e), database_url=settings.DATABASE_URL, retry_count=retry_count, exc_info=True # 包含完整堆栈信息 ) ``` ### 5.3 日志格式配置 ```python # app/core/logger.py import structlog def configure_logging(): structlog.configure( processors=[ structlog.stdlib.filter_by_level, structlog.stdlib.add_logger_name, structlog.stdlib.add_log_level, structlog.stdlib.PositionalArgumentsFormatter(), structlog.processors.TimeStamper(fmt="iso"), structlog.processors.StackInfoRenderer(), structlog.processors.format_exc_info, structlog.processors.UnicodeDecoder(), structlog.processors.JSONRenderer() ], context_class=dict, logger_factory=structlog.stdlib.LoggerFactory(), cache_logger_on_first_use=True, ) ``` ## 6. 测试规范 ### 6.1 测试文件组织 ``` tests/ ├── unit/ # 单元测试 │ ├── test_services/ │ └── test_utils/ ├── integration/ # 集成测试 │ ├── test_api/ │ └── test_database/ └── e2e/ # 端到端测试 └── test_workflows/ ``` ### 6.2 测试命名规范 ```python # 测试文件名:test_模块名.py test_user_service.py # 测试类名:Test + 被测试类名 class TestUserService: pass # 测试方法名:test_应该_做什么_当什么条件 def test_should_create_user_when_valid_data(self): pass def test_should_raise_error_when_duplicate_username(self): pass ``` ### 6.3 测试覆盖率要求 - 核心业务逻辑:≥ 90% - API接口:≥ 80% - 工具函数:≥ 70% - 总体覆盖率:≥ 80% ## 7. Git提交规范 ### 7.1 提交信息格式 ``` ():