Files
012-kaopeilian/docs/规划/后端开发拆分策略/开发规范文档.md
111 998211c483 feat: 初始化考培练系统项目
- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
2026-01-24 19:33:28 +08:00

9.3 KiB
Raw Blame History

考培练系统后端开发规范

1. 代码规范

1.1 Python代码规范

  • 格式化工具:使用 Black 进行代码格式化,配置行长度为 88
  • 导入排序:使用 isort 进行导入排序
  • 类型检查:使用 mypy 进行静态类型检查
  • 代码检查:使用 flake8 进行代码质量检查

1.2 命名规范

# 文件名:使用小写字母和下划线
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 文档字符串规范

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状态码
# 好的例子
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 统一响应格式

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 必需字段

每个表必须包含以下字段:

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 自定义异常类

# 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 全局异常处理

# 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 结构化日志

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 日志格式配置

# 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 测试命名规范

# 测试文件名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 提交信息格式

<type>(<scope>): <subject>

<body>

<footer>

7.2 Type类型

  • feat: 新功能
  • fix: 修复bug
  • docs: 文档更新
  • style: 代码格式调整
  • refactor: 代码重构
  • test: 测试相关
  • chore: 构建过程或辅助工具的变动

7.3 示例

feat(user): 添加用户批量导入功能

- 支持Excel文件导入
- 支持CSV文件导入  
- 添加导入进度显示
- 添加错误信息导出

Closes #123

8. 代码审查清单

提交代码前,请确保:

基础检查

  • 代码通过 Black 格式化
  • 代码通过 isort 导入排序
  • 代码通过 mypy 类型检查
  • 代码通过 flake8 质量检查

功能检查

  • 所有函数都有完整的文档字符串
  • 所有函数都有类型注解
  • API响应格式符合统一标准
  • 错误处理使用统一的异常类

测试检查

  • 编写了相应的单元测试
  • 测试覆盖率符合要求
  • 所有测试通过

安全检查

  • 没有硬编码的密钥或密码
  • SQL查询使用参数化查询
  • 敏感操作有权限检查

性能检查

  • 数据库查询使用了适当的索引
  • 避免了N+1查询问题
  • 大量数据处理使用了分页或流式处理

日志检查

  • 关键操作有日志记录
  • 错误信息包含完整的上下文
  • 日志级别使用恰当