Files
qihuaiflow/tests/astrbot-channel-optimization-test-case-report.md
T
qyyfw 78ff261b5a 初始提交: Qihu-AIFlow v2.0.1 完整项目
- 前端 React+TypeScript (源码+构建产物)
- 后端 Python FastAPI
- 数据库迁移 001-015
- Docker部署配置
- 微信ClawBot API频道绑定
- 项目文档 README.md
2026-07-02 14:40:46 +08:00

499 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 测试用例 — AstrBot频道优化(P0-P2 全部完成)
**测试日期**: 2026-06-01
**测试工程师**: 测试工程师
**测试依据**: 项目负责人指定的AstrBot频道优化需求 + 前后端代码分析
**需求范围**: 统一Webhook端点(6平台)、消息组件系统(5种组件)、平台注册机制(6个适配器)、MessageSession统一标识、Pipeline管道(5 Stage)、Redis事件总线、二维码localhost根因修复(config.py三级防护)
---
## 1. 需求依据
- PRD 路径: `/data/share/project/docs/PRD.md`
- 本轮优化范围(项目负责人指定):
1. 统一Webhook端点 — 为6个IM平台(企业微信/飞书/钉钉/Telegram/Slack/WhatsApp)提供统一的 `/webhook/{platform}` 入口
2. 消息组件系统 — 5种消息组件(Plain/Image/At/Reply/File),支持序列化/反序列化
3. 平台注册机制 — 使用 `@register_platform_adapter` 装饰器标准化注册6个适配器
4. MessageSession统一会话标识 — `platform:type:session_id` 格式
5. Pipeline管道 — 5 Stage 链式处理(WakingCheck→RateLimit→ContentSafety→Process→Respond)
6. Redis事件总线 — 基于Redis List的生产者-消费者消息队列
7. 二维码localhost根因修复 — `config.py` 三级防护(环境变量→.env→硬编码域名)
---
## 2. 代码功能模块概览
| 模块 | 职责 | 代码位置 |
|------|------|---------|
| Config配置模块 | APP_ACCESS_URL三级防护,全局配置管理 | `app/config.py:36-63` |
| Pipeline管道系统 | 5 Stage链式消息处理,PipelineScheduler调度器 | `app/pipeline.py` (349行) |
| Redis事件总线 | MessageEvent序列化,生产者-消费者模式 | `app/event_bus.py` (293行) |
| 消息组件系统 | 5种组件(Plain/Image/At/Reply/File),序列化工厂 | `app/message_components.py` (340行) |
| 平台注册机制 | @register_platform_adapter装饰器,全局注册表 | `app/platform_adapter.py` (126行) |
| 6个平台适配器 | wecom/feishu/dingtalk/telegram/slack/whatsapp | `app/platform_adapters/*.py` |
| MessageSession | 统一会话标识 platform:type:session_id | `app/message_session.py` (55行) |
| 统一Webhook端点 | POST /webhook/{platform},适配器+EventBus集成 | `app/api/channels.py:1453-1579` |
| 频道QR二维码 | 微信ClawBot API优先,本地qrcode库回退 | `app/api/channels.py:420-498` |
| Webhook平台列表 | GET /webhook/platforms 列出所有支持平台 | `app/api/channels.py:1582-1597` |
---
## 3. 需求与代码差异说明
### 3.1 PRD中未在代码中体现的内容
无。本轮优化的7个功能点在代码中均已有完整实现。
### 3.2 PRD中未覆盖但代码中存在的功能模块
| 编号 | 模块名称 | 代码位置 | 建议 |
|------|---------|---------|------|
| N1 | 旧版webhook处理函数(`_handle_*_webhook`) | `app/api/channels.py:1600-1918` | 与适配器模式重复,本次已统一到适配器架构 |
| N2 | Pipeline单元测试(自测代码) | `app/pipeline.py:202-347` | 内建9个单元测试,建议产品确认纳入CI |
| N3 | EventBus单元测试(自测代码) | `app/event_bus.py:182-292` | 内建7个单元测试,建议产品确认纳入CI |
| N4 | 频道消息组件与webhook解析的桥接 | 跨文件 | 适配器 `parse_webhook()` 返回dict而非BaseMessageComponent链,存在集成断点 |
---
## 4. 测试用例
### 4.1 统一Webhook端点 (Q1)
#### TC-WH-01 [P0] 验证统一Webhook端点存在且路径正确
- **前置条件**: 后端服务运行在18080端口
- **步骤**:
[1] 向 `POST /app/api/channels/webhook/{platform}` 各平台发送请求
[2] 验证返回404之外的HTTP状态码(400表示平台不支持但端点存在)
[3] 逐个平台验证:wecom/feishu/dingtalk/telegram/slack/whatsapp
- **预期结果**: 所有6个平台的webhook端点均可访问(返回400"不支持的平台"或正常响应)
- **备注**: 请求体为空时,FastAPI可能返回422(Body缺失),这也是端点存在的证明
#### TC-WH-02 [P0] 验证Webhook端点消息接收和记录
- **前置条件**: 已有活跃的微信频道
- **步骤**:
[1] 构造合法的微信平台webhook消息payload
[2] 发送POST到 `/app/api/channels/webhook/wecom`
[3] 验证返回 `code: 0` 且 `data.handled=true`
[4] 验证返回包含 `message_id`、`session` 和 `platform` 字段
[5] 检查数据库中 `channel_messages` 表存在对应记录
- **预期结果**: 消息成功接收并写入数据库;返回标准webhook响应格式
- **备注**: 验证从webhook入站到数据库记录的完整链路
#### TC-WH-03 [P0] 验证Webhook平台验证(飞书challenge/ Slack url_verification)
- **前置条件**: 后端服务运行
- **步骤**:
[1] 向 `/webhook/feishu` 发送 `{"challenge": "test_challenge_123"}` 的POST请求
[2] 验证返回 `{"challenge": "test_challenge_123"}`
[3] 向 `/webhook/slack` 发送 `{"type": "url_verification", "challenge": "slack_challenge_456"}`
[4] 验证返回 `{"challenge": "slack_challenge_456"}`
- **预期结果**: 飞书和Slack的URL验证正确返回challenge值
- **备注**: URL验证是各平台接入的第一步,必须正确处理
#### TC-WH-04 [P1] 验证Webhook对未注册平台的拒绝
- **前置条件**: 后端服务运行
- **步骤**:
[1] 向 `/webhook/unknown_platform` 发送POST请求
[2] 验证返回400状态码
[3] 验证错误消息包含"不支持的平台"和可用平台列表
- **预期结果**: 未注册平台被正确拒绝,返回明确错误
#### TC-WH-05 [P1] 验证无活跃频道时Webhook行为
- **前置条件**: 所有wecom频道已断开或删除
- **步骤**:
[1] 向 `/webhook/wecom` 发送消息payload
[2] 验证返回 `code: 0` 且 `data.handled=false`
[3] 验证消息包含"无活跃的wecom频道"
- **预期结果**: 优雅处理无活跃频道的情况,不报500错误
#### TC-WH-06 [P0] 验证Webhook支持平台列表接口
- **前置条件**: 6个适配器已注册
- **步骤**:
[1] 发送GET请求到 `/app/api/channels/webhook/platforms`
[2] 验证返回 `code: 0`
[3] 验证 `data.platforms` 包含6个平台条目
[4] 验证每个平台条目包含name/display_name/description/support能力字段
- **预期结果**: 返回完整的6个平台元数据
---
### 4.2 消息组件系统 (Q2)
#### TC-MC-01 [P0] 验证Plain文本组件序列化/反序列化
- **前置条件**: 消息组件系统代码可导入
- **步骤**:
[1] 创建 `Plain(text="你好世界")`
[2] 调用 `to_dict()` 序列化
[3] 验证返回 `{"type": "plain", "text": "你好世界"}`
[4] 调用 `Plain.from_dict(serialized)` 反序列化
[5] 验证 `plain_obj.text == "你好世界"`
- **预期结果**: Plain组件序列化/反序列化正确
#### TC-MC-02 [P0] 验证Image图片组件序列化/反序列化
- **前置条件**: 同上
- **步骤**:
[1] 创建 `Image(url="https://example.com/img.png", width=800, height=600)`
[2] 调用 `to_dict()` 验证url/width/height字段
[3] 调用 `Image.from_dict()` 反序列化验证
- **预期结果**: Image组件序列化/反序列化正确
#### TC-MC-03 [P0] 验证At提及组件序列化/反序列化
- **前置条件**: 同上
- **步骤**:
[1] 创建 `At(user_id="user_001", display_name="张三")`
[2] 序列化验证user_id和display_name
[3] 反序列化验证
[4] 测试不带display_name的场景
- **预期结果**: At组件正确处理user_id和可选的display_name
#### TC-MC-04 [P0] 验证Reply回复组件序列化/反序列化
- **前置条件**: 同上
- **步骤**:
[1] 创建 `Reply(message_id="msg_001", content_preview="原消息预览")`
[2] 序列化验证message_id和content_preview
[3] 反序列化验证
- **预期结果**: Reply组件序列化/反序列化正确
#### TC-MC-05 [P0] 验证File文件组件序列化/反序列化
- **前置条件**: 同上
- **步骤**:
[1] 创建 `File(filename="report.pdf", url="https://example.com/report.pdf", size=102400)`
[2] 序列化验证filename/url/size
[3] 验证不带size时的序列化
- **预期结果**: File组件序列化/反序列化正确
#### TC-MC-06 [P0] 验证消息链整体序列化/反序列化 (message_chain_to_dict/from_dict)
- **前置条件**: 同上
- **步骤**:
[1] 构建复合消息链: `[Reply(...), Plain(...), At(...), Image(...)]`
[2] 调用 `message_chain_to_dict(chain)` 生成字典列表
[3] 调用 `message_chain_from_dict(dict_list)` 恢复组件链
[4] 验证每个组件的类型和关键字段正确
- **预期结果**: 完整消息链循环序列化正确
#### TC-MC-07 [P1] 验证辅助提取函数
- **前置条件**: 同上
- **步骤**:
[1] 构建包含多个组件的消息链
[2] 测试 `extract_plain_text()` 正确拼接所有Plain文本
[3] 测试 `extract_image_urls()` 提取所有图片URL
[4] 测试 `extract_at_user_ids()` 提取所有@用户ID
[5] 测试 `has_component_type()` 对存在和不存在的类型
- **预期结果**: 所有辅助提取函数正确
#### TC-MC-08 [P1] 验证未知组件类型降级处理
- **前置条件**: 同上
- **步骤**:
[1] 构造 `[{"type": "unknown_type", "data": "test"}]` 传入 `message_chain_from_dict`
[2] 验证返回结果为Plain组件,text为原始dict的字符串表示
- **预期结果**: 未知类型优雅降级,不抛异常
---
### 4.3 平台注册机制 (Q3)
#### TC-PR-01 [P0] 验证6个适配器均已正确注册
- **前置条件**: 6个适配器文件已导入
- **步骤**:
[1] 从 `platform_adapter` 导入 `platform_registry` 和 `platform_cls_map`
[2] 验证 `len(platform_registry) == 6`
[3] 验证注册表包含所有6个平台: `{"wecom", "feishu", "dingtalk", "telegram", "slack", "whatsapp"}`
[4] 验证 `platform_cls_map` 中的每个类都是 `BasePlatformAdapter` 的子类
- **预期结果**: 6个适配器全部正确注册,name和class映射完整
#### TC-PR-02 [P0] 验证平台适配器工厂函数
- **前置条件**: 适配器已注册
- **步骤**:
[1] 对每个平台调用 `get_platform_adapter(name, config={})`
[2] 验证返回的实例是其对应适配器类的实例
[3] 验证每个适配器 `get_status()` 返回 "stopped"
[4] 调用 `start()` 后验证 `get_status()` 返回 "running"
- **预期结果**: 工厂函数正确创建适配器实例,状态管理正常
#### TC-PR-03 [P0] 验证平台元数据完整性
- **前置条件**: 适配器已注册
- **步骤**:
[1] 对每个平台获取 `platform_registry[name]`
[2] 验证元数据包含: name/display_name/description/icon/version
[3] 验证能力标记: support_streaming/support_image/support_file/support_voice
[4] 验证不同平台的能力标记符合实际情况: 飞书streaming=true, 企业微信streaming=false等
- **预期结果**: 所有平台元数据字段完整正确
#### TC-PR-04 [P0] 验证list_platforms API
- **前置条件**: 适配器已注册
- **步骤**:
[1] 调用 `list_platforms()`
[2] 验证返回6个PlatformMetadata实例
[3] 验证每个实例的name字段唯一且非空
- **预期结果**: 列出所有已注册平台
#### TC-PR-05 [P1] 验证未注册平台的错误处理
- **前置条件**: 适配器已注册
- **步骤**:
[1] 调用 `get_platform_adapter("unknown_platform", {})`
[2] 验证抛出 `ValueError` 异常
[3] 验证异常消息包含"未知平台"和可用平台列表
- **预期结果**: 未注册平台被正确拒绝,有清晰错误提示
#### TC-PR-06 [P1] 验证装饰器中非BasePlatformAdapter子类的拒绝
- **前置条件**: 适配器代码
- **步骤**:
[1] 确认代码中 `register_platform_adapter` 装饰器的类型检查逻辑存在
[2] 验证 `issubclass(cls, BasePlatformAdapter)` 检查在第93行
- **预期结果**: 装饰器强制类型约束,非适配器子类会抛出TypeError
---
### 4.4 MessageSession统一会话标识 (Q4)
#### TC-MS-01 [P0] 验证MessageSession创建和字符串化
- **前置条件**: message_session模块可用
- **步骤**:
[1] 创建 `MessageSession(platform_name="wecom", session_type=SessionType.GROUP, session_id="group_123")`
[2] 验证 `unified_msg_origin` 返回 `"wecom:group:group_123"`
[3] 创建 `MessageSession(platform_name="feishu", session_type=SessionType.FRIEND, session_id="user_456")`
[4] 验证 `unified_msg_origin` 返回 `"feishu:friend:user_456"`
- **预期结果**: 统一会话标识格式化为 `platform:type:session_id`
#### TC-MS-02 [P0] 验证from_str解析
- **前置条件**: 同上
- **步骤**:
[1] 调用 `MessageSession.from_str("telegram:friend:user_789")`
[2] 验证 platform_name="telegram", session_type=SessionType.FRIEND, session_id="user_789"
[3] 调用 `MessageSession.from_str("slack:channel:ch_001")`
[4] 验证 session_type=SessionType.CHANNEL
- **预期结果**: 正确从字符串解析,所有SessionType枚举值均支持
#### TC-MS-03 [P0] 验证from_channel_event自动推断
- **前置条件**: 同上
- **步骤**:
[1] 有group_id时: `from_channel_event("wecom", "ch_001", "user_001", group_id="grp_001")`
[2] 验证返回GROUP类型,session_id="grp_001"
[3] 无group_id时: `from_channel_event("feishu", "ch_002", "user_002")`
[4] 验证返回FRIEND类型,session_id="user_002"
- **预期结果**: 自动根据group_id判断会话类型
#### TC-MS-04 [P1] 验证hashable/equality行为
- **前置条件**: 同上
- **步骤**:
[1] 创建 `ms1 = MessageSession("wecom", SessionType.FRIEND, "user_001")`
[2] 创建 `ms2 = MessageSession("wecom", SessionType.FRIEND, "user_001")`
[3] 验证 `ms1 == ms2` 为True
[4] 验证 `hash(ms1) == hash(ms2)`
[5] 验证可以放入set去重: `len({ms1, ms2}) == 1`
- **预期结果**: MessageSession支持相等比较和哈希,可用作集合元素
#### TC-MS-05 [P1] 验证from_str格式错误处理
- **前置条件**: 同上
- **步骤**:
[1] 调用 `MessageSession.from_str("invalid_format")`
[2] 验证抛出 `ValueError` 异常
[3] 验证异常消息包含正确的格式说明
- **预期结果**: 格式错误的字符串被正确拒绝
---
### 4.5 Pipeline管道系统 (Q5)
#### TC-PL-01 [P0] 验证Pipeline默认5阶段按顺序执行
- **前置条件**: pipeline模块可用
- **步骤**:
[1] 创建 `PipelineScheduler()` 默认管道
[2] 构造完整上下文(含message/platform/sender_id/is_private等)
[3] 调用 `pipeline.execute(context)`
[4] 验证返回 `success=True`
[5] 验证 `pipeline_log` 包含5条记录,顺序为: waking_check → rate_limit_check → content_safety_check → process → respond
- **预期结果**: 5个阶段按正确顺序执行,pipeline_log记录完整
#### TC-PL-02 [P0] 验证WakingCheck阶段:私聊自动唤醒
- **前置条件**: 同上
- **步骤**:
[1] 创建私聊场景: `is_private=True`
[2] 执行WakingCheckStage.process()
[3] 验证 `should_respond=True`, `stop=False`
- **预期结果**: 私聊消息自动唤醒AI响应
#### TC-PL-03 [P0] 验证WakingCheck阶段:群聊@bot唤醒
- **前置条件**: 同上
- **步骤**:
[1] 创建群聊场景: `is_private=False`, message="@bot 帮我查询"
[2] 执行WakingCheckStage.process()
[3] 验证 `should_respond=True`, `stop=False`
- **预期结果**: 群聊中@bot后唤醒AI
#### TC-PL-04 [P0] 验证WakingCheck阶段:群聊不@bot则停止
- **前置条件**: 同上
- **步骤**:
[1] 创建群聊场景: `is_private=False`, message="今天天气不错"
[2] 执行WakingCheckStage.process()
[3] 验证 `should_respond=False`, `stop=True`
- **预期结果**: 群聊中未@bot时停止管道
#### TC-PL-05 [P0] 验证RateLimit阶段:限流生效
- **前置条件**: 同上
- **步骤**:
[1] 设置 `RateLimitCheckStage(max_per_minute=3)`
[2] 同一sender_id连续发送4次
[3] 验证前3次返回success=True
[4] 验证第4次返回success=False, error含"频繁", stop=True
- **预期结果**: 超过限制后被正确限流
#### TC-PL-06 [P1] 验证ContentSafety阶段:正常内容通过
- **前置条件**: 同上
- **步骤**:
[1] 发送内容为"正常的聊天内容"
[2] 验证success=True, stop=False
- **预期结果**: 正常内容不受影响
#### TC-PL-07 [P1] 验证Pipeline阶段异常处理
- **前置条件**: 同上
- **步骤**:
[1] 创建抛出异常的BrokenStage
[2] 执行PipelineScheduler(stages=[BrokenStage()])
[3] 验证返回success=False
[4] 验证error消息包含阶段名和异常信息
- **预期结果**: stage异常被正确捕获,返回结构化错误
#### TC-PL-08 [P1] 验证Pipeline阶段动态增删
- **前置条件**: 同上
- **步骤**:
[1] 创建空stages的管道
[2] 调用 `add_stage()` 添加WakingCheckStage
[3] 调用 `add_stage()` 插入到位置0
[4] 验证阶段顺序正确
[5] 调用 `remove_stage("waking_check")` 移除
[6] 验证移除后管道阶段列表正确
- **预期结果**: 动态增删阶段正常
---
### 4.6 Redis事件总线 (Q6)
#### TC-EB-01 [P0] 验证MessageEvent创建和序列化
- **前置条件**: Redis可用
- **步骤**:
[1] 创建MessageEvent(platform="feishu", channel_id="ch_001", content="测试", sender_id="user_001")
[2] 调用 `to_dict()` 序列化
[3] 验证返回字典包含所有9个字段
[4] 验证timestamp字段存在且为整数
- **预期结果**: MessageEvent序列化包含完整字段,含自动生成的timestamp
#### TC-EB-02 [P0] 验证MessageEvent反序列化
- **前置条件**: 同上
- **步骤**:
[1] 从to_dict结果调用 `MessageEvent.from_dict(dict_data)`
[2] 验证所有字段完全恢复
[3] 特别验证platform/channel_id/content/sender_id正确
- **预期结果**: 序列化→反序列化循环后数据一致
#### TC-EB-03 [P0] 验证RedisEventBus事件发布
- **前置条件**: Redis可用
- **步骤**:
[1] 创建RedisEventBus实例
[2] 创建MessageEvent并调用 `bus.publish(event)`
[3] 验证返回 `True`(发布成功)
[4] 调用 `bus.queue_size()` 验证队列长度 ≥1
- **预期结果**: 事件成功写入Redis List
#### TC-EB-04 [P0] 验证RedisEventBus事件消费
- **前置条件**: Redis可用
- **步骤**:
[1] 创建RedisEventBus并启动1个消费者
[2] 注册feishu平台的handler
[3] 发布一个feishu平台事件
[4] 等待1秒后验证handler被调用
[5] 验证handler接收到的事件字段正确
[6] 调用 `bus.stop()` 停止消费者
- **预期结果**: 事件被正确消费并分发给对应平台handler
#### TC-EB-05 [P0] 验证全局单例
- **前置条件**: 同上
- **步骤**:
[1] 调用 `get_event_bus()` 两次
[2] 验证两个引用指向同一个实例(`bus1 is bus2`)
- **预期结果**: 全局单例正确
#### TC-EB-06 [P1] 验证订阅通配符 `*`
- **前置条件**: Redis可用
- **步骤**:
[1] 注册 `*` 通配符handler
[2] 发布不同平台(feishu/wecom)的事件
[3] 验证通配符handler都能接收到
[4] 清理
- **预期结果**: 通配符订阅接收所有平台事件
#### TC-EB-07 [P1] 验证多消费者并发
- **前置条件**: Redis可用
- **步骤**:
[1] 启动2个消费者线程
[2] 发布多个事件
[3] 验证所有事件被消费,不重复不丢失
[4] 停止消费者
- **预期结果**: 多消费者并发正常工作
#### TC-EB-08 [P1] 验证Redis队列清理
- **前置条件**: Redis可用
- **步骤**:
[1] 清理测试key: `DEL aiflow:event_queue`
[2] 验证 `queue_size() == 0`
- **预期结果**: 队列清理后为空
---
### 4.7 二维码URL非localhost (Q7)
#### TC-QR-01 [P0] 验证config.py三级防护机制存在
- **前置条件**: config.py可读取
- **步骤**:
[1] 检查 `APP_ACCESS_URL` 赋值逻辑
[2] 验证第40-41行:首选环境变量 `os.getenv("APP_ACCESS_URL")`
[3] 验证第43-58行:临时域名检测(`team-coding`/`localhost`/`127.0.0.1`/`0.0.0.0`),检测到后从.env覆盖
[4] 验证第61-63行:最终兜底为 `https://bot.qihuyun.com`
- **预期结果**: 三级防护完整:环境变量→.env→硬编码正式域名
#### TC-QR-02 [P0] 验证二维码生成API返回非localhost的URL
- **前置条件**: 频道已创建
- **步骤**:
[1] 调用 `POST /app/api/channels/authorize/scan?platform=wechat` 生成二维码
[2] 验证返回的 `qr_url` 字段存在(base64 data URI)
[3] 通过API调用确认绑定URL使用 `APP_ACCESS_URL`,非localhost
[4] 验证API响应中的二维码图片不编码localhost地址
- **预期结果**: 二维码包含生产地址,不含localhost
#### TC-QR-03 [P1] 验证临时域名检测模式列表
- **前置条件**: config.py可读取
- **步骤**:
[1] 验证 `_TEMP_DOMAIN_PATTERNS` 包含: "team-coding", "localhost", "127.0.0.1", "0.0.0.0"
[2] 测试 "http://s-3686137677310083075-773.team-coding:8080" → 应被识别为临时
[3] 测试 "https://bot.qihuyun.com" → 不应被识别为临时
[4] 测试 "http://localhost:8080" → 应被识别为临时
- **预期结果**: 临时域名检测准确
#### TC-QR-04 [P1] 验证`.env`文件不存在的容错
- **前置条件**: 模拟场景
- **步骤**:
[1] 确认代码中 `.env` 读取在try-except块中
[2] 验证当 `.env` 不存在或读取失败时不抛异常
[3] 验证最终仍走到兜底域名
- **预期结果**: .env缺失不会导致启动失败
---
## 5. 测试用例统计
| 模块 | P0用例 | P1用例 | 合计 |
|------|--------|--------|------|
| Q1: 统一Webhook端点 | 4 | 2 | 6 |
| Q2: 消息组件系统 | 6 | 2 | 8 |
| Q3: 平台注册机制 | 4 | 2 | 6 |
| Q4: MessageSession | 3 | 2 | 5 |
| Q5: Pipeline管道 | 5 | 3 | 8 |
| Q6: Redis事件总线 | 5 | 3 | 8 |
| Q7: 二维码URL | 2 | 2 | 4 |
| **合计** | **29** | **16** | **45** |
---
> **文档状态**: 已完成
> **创建日期**: 2026-06-01
> **基于**: 后端代码功能分析 + 项目负责人指定优化范围