Files
cps-develop-docs/ref/drfstd.md
2026-04-01 11:12:48 +08:00

27 KiB
Raw Permalink Blame History

GTCO_AI Django REST Framework(DRF) 后端开发规范指南

版本: 2.16

适用对象: Python 后端开发团队

目标: 明确技术选型,统一代码风格,降低维护成本,保障系统高可扩展性。

执行策略: 本规范采用“限制优先”原则。默认不提供多实现方案,优先固定实现路径;未在本文明确允许的做法,一律视为不允许。

文档定位: 本文件是开发规范的唯一基准文档。若与其它开发文档冲突,以本文件为准。

配套文档入口: docs/development/index.md

专项规范:

  1. 文档管理:docs/development/documentation_standards.md
  2. Dify 代理:docs/development/dify_proxy_standards.md
  3. 代码审查:docs/development/code_review_guidelines.md

0.0 项目红线 (不可变约束)

以下为当前仓库的强制架构约束,默认长期有效:

  1. 版本唯一:仅允许 v1 命名空间,必须通过 NamespaceVersioning 解析版本;禁止新增未命名空间路由。
  2. 认证唯一入口:仅允许 SmartHeaderAuthentication + GTCOAIJWTAuthentication 组合;禁止在 View 层读取 Authorization / X-API-Key 做分流。
  3. 认证冲突硬拒绝:同一请求同时携带 Bearer 与 X-API-Key 时必须拒绝,禁止降级兼容。
  4. 响应统一封装:仅允许 StandardResponseRenderer 统一包装 code/message/data;禁止在业务 View 手动拼装统一响应壳。
  5. 异常统一出口:仅允许 gtcoai_exception_handler 输出错误结构;禁止各模块自定义返回格式。
  6. 组织作用域强隔离凡组织级数据user/externals查询必须绑定 request.user.current_organization;禁止跨组织默认可见。
  7. 权限链路固定:涉及外部资源访问时,必须遵循“系统动作策略 -> 组织角色/成员 -> 用户组授权”顺序,禁止跳步放行。
  8. 写操作服务化:复杂写操作必须下沉到 Service 层View 层仅做编排、参数校验、权限决策。
  9. 代理链路无状态Dify 透明代理禁止落库业务状态,禁止在代理层引入账号同步、审批等副作用逻辑。
  10. 变更必须可验证:涉及权限、认证、代理路径改动时,必须补齐自动化测试并执行真实路由脚本验证。
  11. 门禁入口唯一:合并前质量检查仅允许通过 scripts/ci/quality_gate.sh 执行,禁止自定义临时命令替代。

0. 技术栈清单 (Tech Stack)

本规范强制使用以下库与工具:

分类 选定库 用途
包管理 uv Rust 编写的 Python 包管理器,用于替代 pip/poetry
配置管理 django-split-settings 多环境配置拆分
代码质量 Ruff 格式化、排序、检查三合一工具
类型检查 VS Code (Pylance) 编辑器实时检查 (CI 不强制 Mypy)
异步视图 adrf DRF 的异步扩展 (Async Django REST Framework)
异步任务 Celery 后台任务队列
消息/缓存 Redis Celery Broker / Backend 及 Django Cache
性能调试 django-debug-toolbar SQL 查询分析 (开发环境)
性能监测 nplusone N+1 问题自动检测
日志系统 Loguru JSON 结构化日志
认证授权 drf-simplejwt JWT 认证
目录认证 django-auth-ldap LDAP 认证(生产环境)
API 文档 drf-spectacular OpenAPI 3.0 Schema 生成
测试框架 pytest-django 测试运行器
测试数据 factory_boy 测试数据生成
并行测试 pytest-xdist 多进程测试加速

1. 工程化规范 (Engineering)

1.1 依赖管理

  • 工具: 统一使用 uv。
    • 常用命令: uv pip compile (锁定), uv sync (同步)。
  • 版本锁定: 生产环境必须存在 uv.lock 文件。
  • Python 版本: 强制版本为 Python 3.11 及以上(与 pyproject.toml 保持一致)。

1.2 配置管理 (Settings)

禁止将所有配置写在单个 settings.py 中。必须使用 django-split-settings。

目录结构要求

settings/  
    \_\_init\_\_.py  \# 入口逻辑  
    base.py      \# 通用配置  
    components/  \# 模块化配置 (logging.py, drf.py, celery.py)  
    environments/\# 环境差异化配置 (local.py, prod.py)
  • 安全要求: 密钥 (SECRET_KEY, DB_PASSWORD) 必须从环境变量 (.env) 读取,严禁硬编码。

1.3 代码规范 (Linting)

工具: 统一使用 Ruff

  • 配置要求:
    • 格式化: ruff format
    • 检查: ruff check --fix
    • 行长: 120 (严禁使用默认的 88)
  • 类型检查:
    • 开发人员需确保 VS Code (Pylance) 无红色报错。
    • CI 流水线不运行 Mypy。

2. 命名与风格 (Naming & Style)

2.1 命名表

对象 规范 示例
App 全小写,复数 users, orders
Model PascalCase单数 User, ProductCategory
Field snake_case created_at
Serializer Model + Serializer UserSerializer
View Resource + Action UserViewSet
URL kebab-case /api/v1/user-profiles/

2.2 编码习惯

  • 布尔值: 必须使用 is_, has_, allow_ 前缀。
  • 集合变量: 必须使用复数形式 (users, items)。

3. 模型层规范 (Models)

3.1 基础模型

严禁使用公共抽象基类(如 BaseModel进行隐式继承。所有业务 Model 必须直接继承 django.db.models.Model显式定义所有需要的字段,包括主键和审计字段。

这种“各写各的”策略是为了保证每个 Model 的定义清晰、独立,便于后续的迁移和重构,避免基类变更带来的全局副作用。

class MyModel(models.Model):
# 1. 主键:根据实际需求显式定义,强制使用 UUID 或 BigAutoField
id = models.BigAutoField(primary_key=True)

\# 2\. 业务字段  
name \= models.CharField(max\_length=100, help\_text="名称")  
  
\# 3\. 审计字段:必须显式书写,严禁省略  
created\_at \= models.DateTimeField(auto\_now\_add=True, help\_text="创建时间")  
updated\_at \= models.DateTimeField(auto\_now=True, help\_text="更新时间")

class Meta:  
    verbose\_name \= "我的模型"  
    verbose\_name\_plural \= verbose\_name

3.2 字段定义

  • Choices: 强制使用 TextChoices / IntegerChoices 枚举。
  • Null/Blank: 字符型字段禁止 null=True必须设为 default=''。
  • Help Text: 所有字段必须填写 help_text (用于生成文档)。
  • Related Name: 外键必须指定 related_name。

3.3 数据库约束

  • Code First: 严禁手动直连数据库修改结构,一切变更必须通过 Migrations。
  • 索引要求: 凡是涉及 filter, order_by, ForeignKey 的字段,必须加索引。
  • 删除策略: 默认优先使用物理删除;仅当业务明确要求“可恢复”或“审计追溯”时才引入软删除字段。
  • 唯一约束: 若启用软删除,必须使用带条件的唯一约束 (Conditional Unique Constraint)。

class Meta:
constraints = [
models.UniqueConstraint(
fields=['username'],
name='unique_active_username',
condition=models.Q(is_deleted=False)
)
]

3.4 外部服务凭证与账号模型规范 (Externals Credentials & Accounts)

适用于第三方代理场景(如 Dify、OpenAI、内部网关等

  • 用户-凭证关系: 必须为一对多(一个用户可维护多个外部凭证)。
  • 凭证核心字段: 至少包含 servicecredential_typenamesecretis_active
  • 凭证命名: name 必须用于业务可读标识如“生产Dify主Key”
  • 唯一约束: 同一用户下,(service, credential_type, name) 必须唯一。
  • 密钥存储: 明文密钥字段必须加密存储(字段级加密或等效方案),禁止日志打印完整密钥。
  • 账号绑定: 若用户直接绑定外部账号,必须与凭证分表管理。账号表用于身份与连接状态,凭证表用于请求鉴权材料。
  • 转发读取原则: 代理请求阶段只按需求读取目标凭证,不在转发层混入账号同步、授权刷新等重逻辑。

4. 序列化层规范 (Serializers)

4.1 编写规范

  • 选型: 统一使用 ModelSerializer。
  • 字段: 禁止使用 fields = '__all__',必须显式列出。
  • 参数: 使用 Meta.extra_kwargs 定义字段参数,保持代码简洁。

4.2 职责边界

  • 定位: 仅负责数据结构转换和基础格式验证。
  • 禁止: save/create/update 方法中严禁包含发送邮件、复杂计算、外部调用等业务逻辑。

4.3 性能规范

  • 列表接口: 严禁在列表页使用深层嵌套的 Serializer强制定义 SimpleSerializer。
  • 预加载: 包含外键的 SerializerView 层必须配合 select_related / prefetch_related。
  • 聚合计算: 严禁在 SerializerMethodField 中执行 SQL 聚合 (count/sum)。必须在 View 层使用 annotate 计算完成后传入。

5. 视图与业务层规范 (Views & Logic)

5.1 ViewSet 选型与分层

核心原则: 精准控制与逻辑分层

  • 选型:
    • 标准 CRUD 强制使用 ModelViewSet。
    • 定制化业务场景强制选用 GenericViewSet 配合 Mixins 按需组合。
    • 严禁直接使用裸的 ViewSet。
    • APIView 仅允许用于“非标准资源形态接口”(如 Dify 透明代理、缓存刷新、健康检查);必须补充 @extend_schema 且在类注释中说明无法使用 ViewSet 的原因。
    • 权限控制边界:只读接口绝不暴露 CreateModelMixin 或 DestroyModelMixin。
  • 方法职责表:
方法 核心职责 规范要求
get_queryset 查数据 + 优化 必须实现权限隔离 (如 filter(user=request.user)) 与预加载 (select_related),杜绝 N+1。
get_serializer_class 定格式 (读写分离) 必须区分场景list 用极简版create 用校验版retrieve 用全量版。
get_permissions 定权限 (动作分离) 必须区分动作:如 create 允许匿名destroy 必须管理员。
perform_create/update 写业务 (逻辑下沉) 仅处理关联逻辑 (如绑定 request.user) 或调用 Service 层。

5.2 Service 层模式

View 层仅作为路由与调度的纯粹枢纽,写操作及复杂查询必须封装到 Service 层。

严禁重写 create, update, destroy 等主方法来堆砌业务逻辑。

# views.py
def create(self, request, *args, **kwargs):
# 错误:不要重写 create 方法,破坏了 DRF 标准流
...

def perform_create(self, serializer):
# 正确:使用钩子调用 Service
create_order_service(
user=self.request.user,
data=serializer.validated_data
)

5.3 返回与响应规范 (Return & Response)

规则 1: 标准 CRUD 不重写 Return

对于标准的 create, list, retrieve 等方法,严禁重写其 return 逻辑。DRF 父类已处理好序列化和状态码。

规则 2: 自定义 Action 规范

对于 @action 装饰的方法:

  • 状态码: 必须导入 rest_framework.status 使用常量,严禁使用魔术数字 (200, 404)。
  • 返回: 必须显式返回 Response 对象。

from rest_framework import status
from rest_framework.decorators import action

@action(detail=True, methods=['post'])
def approve(self, request, pk=None):
order = self.get_object()
# 业务逻辑...
return Response(serializer.data, status=status.HTTP_200_OK)

规则 3: 错误处理 (Raise, Don't Return)

遇到业务错误,严禁手动 return Response(error)。

必须直接 raise Exception (如 ValidationError, PermissionDenied)。全局异常处理器会将异常统一格式化。

规则 4: 统一响应包装

严禁在每个 View 中手动构建 { "code": 0, "data": ... } 结构。

必须编写自定义 Renderer 对全局响应进行统一包装。View 层只返回纯粹的业务数据。

相关实现文件位置apps/common/renderers.py。

5.4 认证分流规范 (Authentication Routing)

  • 单一职责: 鉴权头分流必须在认证层处理,固定入口为 apps.common.authentication.SmartHeaderAuthentication,禁止在 View 层手动判断 Header。
  • Header 约定:
    • JWT: Authorization: Bearer <token>
    • API Key: X-API-Key: <raw_api_key>
  • 冲突请求: 同时携带 JWT 与 API Key 的请求必须拒绝,固定抛出 ValidationError,禁止“优先 JWT”或“优先 API Key”兼容策略。
  • 错误一致性: 认证失败响应必须统一由全局异常处理器格式化,禁止各认证类返回不同结构。
  • 日志可观测性: 中间件应可区分 jwt/api_key/anonymous 三类请求并记录认证失败401/403上下文。

5.5 LDAP 接入规范 (LDAP Integration)

  • 接入方式: 通过 Django Authentication Backend 接入 LDAP禁止在 View/Serializer 直接发 LDAP 请求。
  • 配置来源: LDAP 地址、绑定 DN、密码、搜索过滤器必须来源于环境变量。
  • 登录模式: 登录接口应支持 local/ldap/auto 模式切换,默认由配置控制优先级。
  • 身份落库: LDAP 登录成功后,需将本地用户标记为 auth_type=ldap,并按配置同步基础属性。
  • 平台差异: Windows 开发环境可不强制安装 python-ldap,但 Linux 生产环境必须验证 LDAP 依赖可用。

6. 接口设计规范 (API Design)

6.1 URL 路由

📌 命名空间与版本控制 (Namespace & Versioning)

全局强制采用 DRF 的 NamespaceVersioning 机制。DRF 仅通过读取路由的 namespace 属性来判断当前 API 版本,若配置缺失,会导致 request.version 为空,进而被权限控制层直接拦截返回 404 Not Found

强制执行标准:

  1. 根路由 (urls.py):
    挂载业务路由时include() 必须包含版本号命名空间(namespace="v1")。当前项目固定结构如下:
    # gtco_ai/urls.py

    api_v1_patterns = [
    path("user/", include("apps.user.urls")),
    path("external/", include("apps.externals.urls")),
    ]

    urlpatterns = [
    path("api/v1/", include((api_v1_patterns, "api"), namespace="v1")),
    ]

  2. 子路由 (apps/xxx/urls.py):
    每个 APP 的路由文件必须定义 app_name 变量,否则 Django 无法正确注册命名空间。
    # apps/user/urls.py
    app_name = "user" # 必须存在且在项目中唯一

    urlpatterns = [
    # ...
    ]

  3. 反向解析 (Reverse):
    在代码中生成 URL 时,必须带上版本前缀。
    # 正确
    reverse("v1:user:user-detail", args=[user.id])
    # 错误
    reverse("user:user-detail", args=[user.id])

📌 路径设计规范

  • 路由前缀:所有 API 路由必须以 /api/{version}/ 开头(例如 /api/v1/)。
  • 末尾斜杠:统一保留 URL 末尾斜杠 /,与 DRF DefaultRouter 默认行为保持一致。
  • 内部自研接口规范
    • 资源命名URL 路径必须使用 kebab-case短横线连接风格例如 /api/v1/user-profiles/。资源集合统一使用名词复数形式。
    • 层级结构URL 层级不超过 3 层,禁止过深嵌套。标准结构:/api/v1/{resource}/{id}/{sub-resource}/。
  • 【特批豁免】第三方代理接口 (Proxy API) 规范
    • 背景:当代理外部系统(如 Dify 知识库等)接口,且前端需复用官方 SDK 或完全对照第三方官方文档时适用。
    • 1:1 映射优先:允许豁免单复数、命名风格和层级深度的限制,必须保证字面路径的 1:1 映射(例如:允许使用 snake_case 的 child_chunks允许单数 document允许嵌套深度超过 4 层的 /datasets/{id}/documents/{id}/segments/{id}/child_chunks/)。
    • 架构底线约束:即便进行字面映射,底层代码实现仍必须严格依赖 Django / DRF 的标准路由调度体系(利用 DefaultRouter 处理扁平结构,利用 path + as_view() 显式分发深层嵌套)。

6.2 响应格式与状态码 (Response & Status Codes)

统一响应结构:

{
"code": 20000, // 业务状态码 (5位)
"message": "success", // 提示信息
"data": { ... } // 业务数据
}

📌 业务状态码设计原则 (A-BB-CC 5位高可扩展标准)

随着业务的演进与微服务化,状态码需要具备极高的可扩展性与清晰的域划分。本系统严格执行 A-BB-CC 5位数标准

  • A (1位): 错误级别 / HTTP 语义映射。
    • 2 = 成功 (Success)
    • 4 = 客户端错误 / 业务校验阻断 (Client Error)
    • 5 = 服务端异常 / 第三方依赖崩溃 (Server Error)
  • BB (2位): 业务模块 / 子域划分 (00~99),最高支持 100 个核心模块。
    • 00 = Common (全局基础)
    • 01 = User / Auth (用户与认证)
    • 02 = Dify (Dify 代理相关的各个模块集合,含知识库、工作流等)
    • 【扩展策略】:如果未来某个超大型模块的错误类型极其复杂、超出了 99 种,允许为该大模块分配相邻的多个 BB 号段
  • CC (2位): 具体错误分类序号 (00~99)。
    • 00 = 该模块的“默认通用错误”或“成功”。
    • 01~99 = 具体的精细化业务异常。

📌 状态码扩展与开发强制规约

  1. 禁止过度分配 (泛化 vs 特化)
    • 禁止为每一个表单字段的“必填项校验”单独分配 Code。普通的输入参数异常统一使用 40000 (全局 Bad Request),并在 message 或 data 节点中动态告知前端具体的字段校验失败原因。
    • 分配底线:只有当前端代码需要利用此 Code 进行特殊的交互逻辑跳转时才予以分配。例如40102 (账号被冻结) 前端检测到后需要弹出特殊申诉弹窗40201 (Dify API Key未配置) 前端检测到后需要引导至设置页面。
  2. 代码物理隔离 (分治策略)
    • 禁止单文件膨胀:禁止把所有业务 Code 全部堆在 apps/common/status_code.py 中。
    • 规范要求apps/common/status_code.py 仅存放 00 模块的基础状态码。各个业务线独有的状态码,必须存放于各自 App 的文件内(例如 apps/dify/knowledge/status_code.py

6.3 分页

  • 默认分页: 统一采用 LimitOffsetPagination。
  • 大数据分页: 当前仓库未批准引入 Cursor/Keyset 替代方案作为默认行为;所有常规列表接口必须先落地 LimitOffsetPagination。
  • 流式分页: 对于瀑布流场景,统一使用 CursorPagination。

6.4 API 文档注解规范 (drf-spectacular / extend_schema)

  • 强制要求: 所有对外接口(尤其是 @action 自定义动作和代理接口)必须显式使用 @extend_schema
  • 最低字段: summarydescriptionrequestresponses 必须完整声明。
  • 响应说明: 对透传接口应使用 OpenApiResponse 明确说明“上游原样透传”,避免文档误导前端。
  • 禁止事项: 禁止仅依赖自动推断导致关键请求字段(如 methodroutepath_params)在文档中缺失。

7. 性能与异步规范 (Performance & Async)

7.1 数据库查询

  • N+1 问题: 开发环境必须安装 nplusone 插件CI 检测到 N+1 报错即为不合格。
  • 批量操作: 循环插入/更新必须使用 bulk_create / bulk_update。
  • 迭代: 遍历大表必须使用 .iterator()。

7.2 异步视图

  • 场景限制: 仅在 高并发 I/O 密集型 (如聚合多个第三方 API) 场景下使用。
  • 实现方案: 统一使用 adrf 库。
  • 禁止事项: 严禁在 async def 中运行 CPU 密集型任务 (Pandas/图片处理)。严禁混用同步 ORM 方法。

7.3 异步任务

  • 选型: 统一使用 Celery + Redis。
  • 剥离标准: 耗时 > 200ms 的逻辑 (邮件、报表、AI推理) 必须剥离到后台任务。
  • 事务安全: 必须使用 transaction.on_commit 触发任务。

7.4 缓存

  • 组件: 统一使用 django-redis。
  • 策略: 强制使用 Cache-Aside (旁路缓存) 策略。

8. 日志与异常规范 (Logs)

8.1 异常处理

配置:

  1. 必须在 settings.py 中配置 EXCEPTION_HANDLER 指向 apps.common.exceptions.gtcoai_exception_handler
  2. 异常处理器需将所有 DRF 异常 (APIException) 和 未知异常 (Exception) 统一转化为标准 JSON 响应结构。

8.2 日志配置

工具: 统一使用 Loguru。

配置要求:

  1. 拦截: 必须通过 InterceptHandler 接管 Django 原生日志。
  2. 输出:
    • 控制台: 彩色文本。
    • 文件: JSON 格式 (serialize=True),便于采集。

9. 认证与权限规范 (Auth)

9.1 认证架构 (Authentication Strategy)

核心方案:采用 JWT (JSON Web Token) 作为无状态认证标准,库选型锁定 djangorestframework-simplejwt。

单点登录 (SSO) 集成

架构选型:强制使用 django-allauth 处理 OAuth 协议握手,配合 dj-rest-auth 暴露 REST 接口。严禁手写 OAuth2 流程。

交互流程:采用 "Authorization Code" 模式。前端仅负责获取第三方(如 Google/GitHub的 code后端负责用 code 换取用户信息并颁发本系统的 JWT。严禁后端直接信任前端传来的第三方用户信息。

账号融合:强制实施“基于邮箱的自动关联”策略。无论用户是通过账号密码注册,还是通过 SSO 登录,只要邮箱一致,必须关联到同一个 User 实体,确保用户身份唯一性。

9.2 Token安全与管理 (Token Engineering)

载荷 (Payload) 规范

最小化原则Token 内仅允许携带非敏感的身份标识(如 user_id, role, username

扩展方式:必须通过继承 TokenObtainPairSerializer 并重写 get_token 方法注入自定义声明。严禁修改库源码或在 View 层手动拼凑 Token。

生命周期管理

双 Token 机制:强制启用 Access Token 与 Refresh Token 分离。

  • Access Token 有效期:固定 24 小时(与 settings/components/drf.py 保持一致)。
  • Refresh Token 有效期:固定 7 天

黑名单机制:生产环境必须启用 Blacklist 应用,确保用户注销或修改密码后,旧的 Refresh Token 立即失效。

9.3 权限分层治理 (Permission Governance)

默认策略:实施 "Default Deny" (默认拒绝) 策略。全局配置 (DEFAULT_PERMISSION_CLASSES) 必须设为 IsAuthenticated仅对特定公开接口如注册、登录、健康检查显式配置 AllowAny。

在 ViewSet 中,严禁使用静态的 permission_classes 列表覆盖所有方法。

动作级权限 (Action-Based)

实现规范:必须重写 get_permissions() 方法,根据 self.action如 create, list, destroy动态分配权限例如所有人可注册登录用户可查看仅管理员可删除

系统动作策略优先 (System Policy First):当接口涉及“资源 + 动作”权限时,必须先校验系统级资源动作策略(资源支持动作 + 系统禁用动作),再进入组织角色与成员授权判断。严禁仅依赖成员授权直接放行不受系统支持的动作。

对象级权限 (Object-Level)

涉及“只能操作自己的数据”或“组内可见”的场景,严禁在 View 的业务逻辑中写 if user == owner。

实现规范:必须自定义继承自 BasePermission 的权限类,并重写 has_object_permission 方法,将鉴权逻辑与业务逻辑物理隔离。

9.4 安全加固 (Security Hardening)

CSRF 防护:所有 POST/PUT/PATCH/DELETE 请求必须包含 CSRF Token全局配置 (CSRF_COOKIE_HTTPONLY) 设为 True。

防爆破 (Throttling):所有认证相关接口(登录、注册、刷新 Token、SSO 回调)必须配置高强度的限流策略(如 AnonRateThrottle防止暴力破解。

错误模糊化:认证失败时,统一返回“用户名或密码错误”或“认证失败”,严禁明确提示“用户不存在”或“密码错误”,防止用户信息泄露。

10. 测试规范 (Testing)

10.1 工具链

  • Runner: 统一使用 pytest + pytest-django。
  • Data: 统一使用 factory_boy。
  • Client: 统一使用 APIClient (DRF)。
  • Coverage: 统一使用 pytest-cov。

10.2 编写规范

  • Fixture: 通用对象定义在 conftest.py。
  • Mock: 外部 API 调用必须 Mock禁止在测试中发起真实网络请求。
  • 真实链路验证例外: 对 apps/externals 的代理/权限链路改动,允许并要求使用 scripts/external/ 下脚本做“联调验证”,但该验证不替代 pytest。
  • 提交门禁: 上述改动在合并前必须同时满足“脚本联调通过 + 相关 pytest 用例通过”。
  • 执行: CI 环境需开启 pytest-xdist 并行执行。

10.3 当前项目固定测试命令 (提交前最低要求)

  1. 外部资源治理与代理相关改动:必须运行 pytest apps/externals/tests.py
  2. 用户/组织/认证相关改动:必须运行 pytest apps/user/tests.py
  3. 同时改动 user + externals:必须同时运行以上两组用例,禁止只跑局部单测后直接提交。

10.4 CI 固定执行链路 (禁止绕过)

  1. 本仓库唯一质量门禁脚本:scripts/ci/quality_gate.sh
  2. 脚本执行顺序固定为:ruff format --check -> ruff check -> pytest apps/user/tests.py -> pytest apps/externals/tests.py
  3. 当前阶段Docker 开发流程)提交前必须本地执行该脚本;任一步失败不得提交。
  4. CI 启用后,流水线必须在构建前执行该脚本;任一步失败即阻断后续阶段。
  5. 禁止在本地或 CI 中通过 || true、跳过测试参数、或删改步骤顺序绕过门禁。

10.5 提交审查规范

代码审查流程与输出模板统一见:

docs/development/code_review_guidelines.md

11. 文档管理规范 (Documentation)

本章节拆分为独立文档,减少主规范长度并便于专项维护。

详见:docs/development/documentation_standards.md

最低强制要求:

  1. 核心业务改动必须同步更新测试与文档。
  2. OpenAPI 注解必须完整(@extend_schema)。
  3. 文档冲突时以 docs/development/standards.md 为准。

12. Dify 代理模块规范 (Dify Proxy Module)

本章节拆分为独立文档,避免主规范过长。

详见:docs/development/dify_proxy_standards.md

最低强制要求:

  1. 代理层无状态、无业务存储。
  2. 路由常量统一由 interfaces.py 维护,禁止硬编码 URL。
  3. 保持全异步链路并统一错误处理。

13. 全局权限治理落地文档

权限治理的可执行实施方案角色矩阵、Scope 规范、分阶段改造、验收清单)见:

docs/plans/permission_governance_plan.md