27 KiB
GTCO_AI Django REST Framework(DRF) 后端开发规范指南
版本: 2.16
适用对象: Python 后端开发团队
目标: 明确技术选型,统一代码风格,降低维护成本,保障系统高可扩展性。
执行策略: 本规范采用“限制优先”原则。默认不提供多实现方案,优先固定实现路径;未在本文明确允许的做法,一律视为不允许。
文档定位: 本文件是开发规范的唯一基准文档。若与其它开发文档冲突,以本文件为准。
配套文档入口: docs/development/index.md
专项规范:
- 文档管理:
docs/development/documentation_standards.md - Dify 代理:
docs/development/dify_proxy_standards.md - 代码审查:
docs/development/code_review_guidelines.md
0.0 项目红线 (不可变约束)
以下为当前仓库的强制架构约束,默认长期有效:
- 版本唯一:仅允许
v1命名空间,必须通过NamespaceVersioning解析版本;禁止新增未命名空间路由。 - 认证唯一入口:仅允许
SmartHeaderAuthentication + GTCOAIJWTAuthentication组合;禁止在 View 层读取Authorization/X-API-Key做分流。 - 认证冲突硬拒绝:同一请求同时携带 Bearer 与
X-API-Key时必须拒绝,禁止降级兼容。 - 响应统一封装:仅允许
StandardResponseRenderer统一包装code/message/data;禁止在业务 View 手动拼装统一响应壳。 - 异常统一出口:仅允许
gtcoai_exception_handler输出错误结构;禁止各模块自定义返回格式。 - 组织作用域强隔离:凡组织级数据(user/externals)查询必须绑定
request.user.current_organization;禁止跨组织默认可见。 - 权限链路固定:涉及外部资源访问时,必须遵循“系统动作策略 -> 组织角色/成员 -> 用户组授权”顺序,禁止跳步放行。
- 写操作服务化:复杂写操作必须下沉到 Service 层;View 层仅做编排、参数校验、权限决策。
- 代理链路无状态:Dify 透明代理禁止落库业务状态,禁止在代理层引入账号同步、审批等副作用逻辑。
- 变更必须可验证:涉及权限、认证、代理路径改动时,必须补齐自动化测试并执行真实路由脚本验证。
- 门禁入口唯一:合并前质量检查仅允许通过
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、内部网关等)。
- 用户-凭证关系: 必须为一对多(一个用户可维护多个外部凭证)。
- 凭证核心字段: 至少包含
service、credential_type、name、secret、is_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。
- 预加载: 包含外键的 Serializer,View 层必须配合 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:
- 冲突请求: 同时携带 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。
强制执行标准:
-
根路由 (urls.py):
挂载业务路由时,include() 必须包含版本号命名空间(namespace="v1")。当前项目固定结构如下:
# gtco_ai/urls.pyapi_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")),
] -
子路由 (apps/xxx/urls.py):
每个 APP 的路由文件必须定义 app_name 变量,否则 Django 无法正确注册命名空间。
# apps/user/urls.py
app_name = "user" # ✅ 必须存在且在项目中唯一urlpatterns = [
# ...
] -
反向解析 (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 = 具体的精细化业务异常。
📌 状态码扩展与开发强制规约
- 禁止过度分配 (泛化 vs 特化):
- 禁止为每一个表单字段的“必填项校验”单独分配 Code。普通的输入参数异常统一使用 40000 (全局 Bad Request),并在 message 或 data 节点中动态告知前端具体的字段校验失败原因。
- 分配底线:只有当前端代码需要利用此 Code 进行特殊的交互逻辑跳转时,才予以分配。例如:40102 (账号被冻结) 前端检测到后需要弹出特殊申诉弹窗;40201 (Dify API Key未配置) 前端检测到后需要引导至设置页面。
- 代码物理隔离 (分治策略):
- 禁止单文件膨胀:禁止把所有业务 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。 - 最低字段:
summary、description、request、responses必须完整声明。 - 响应说明: 对透传接口应使用
OpenApiResponse明确说明“上游原样透传”,避免文档误导前端。 - 禁止事项: 禁止仅依赖自动推断导致关键请求字段(如
method、route、path_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 异常处理
配置:
- 必须在 settings.py 中配置 EXCEPTION_HANDLER 指向
apps.common.exceptions.gtcoai_exception_handler。 - 异常处理器需将所有 DRF 异常 (APIException) 和 未知异常 (Exception) 统一转化为标准 JSON 响应结构。
8.2 日志配置
工具: 统一使用 Loguru。
配置要求:
- 拦截: 必须通过 InterceptHandler 接管 Django 原生日志。
- 输出:
- 控制台: 彩色文本。
- 文件: 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 当前项目固定测试命令 (提交前最低要求)
- 外部资源治理与代理相关改动:必须运行
pytest apps/externals/tests.py。 - 用户/组织/认证相关改动:必须运行
pytest apps/user/tests.py。 - 同时改动
user + externals:必须同时运行以上两组用例,禁止只跑局部单测后直接提交。
10.4 CI 固定执行链路 (禁止绕过)
- 本仓库唯一质量门禁脚本:
scripts/ci/quality_gate.sh。 - 脚本执行顺序固定为:
ruff format --check->ruff check->pytest apps/user/tests.py->pytest apps/externals/tests.py。 - 当前阶段(Docker 开发流程)提交前必须本地执行该脚本;任一步失败不得提交。
- CI 启用后,流水线必须在构建前执行该脚本;任一步失败即阻断后续阶段。
- 禁止在本地或 CI 中通过
|| true、跳过测试参数、或删改步骤顺序绕过门禁。
10.5 提交审查规范
代码审查流程与输出模板统一见:
docs/development/code_review_guidelines.md
11. 文档管理规范 (Documentation)
本章节拆分为独立文档,减少主规范长度并便于专项维护。
详见:docs/development/documentation_standards.md
最低强制要求:
- 核心业务改动必须同步更新测试与文档。
- OpenAPI 注解必须完整(
@extend_schema)。 - 文档冲突时以
docs/development/standards.md为准。
12. Dify 代理模块规范 (Dify Proxy Module)
本章节拆分为独立文档,避免主规范过长。
详见:docs/development/dify_proxy_standards.md
最低强制要求:
- 代理层无状态、无业务存储。
- 路由常量统一由
interfaces.py维护,禁止硬编码 URL。 - 保持全异步链路并统一错误处理。
13. 全局权限治理落地文档
权限治理的可执行实施方案(角色矩阵、Scope 规范、分阶段改造、验收清单)见:
docs/plans/permission_governance_plan.md