Files
cmautobuy/AGENTS.md
T

296 lines
19 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.
# 项目协作规则
## 红线
下面五条**任何情况下都不要自行改动,也不要论证它的可行性**。
需要突破其中任何一条时,**停下来问用户**,不要先给方案、不要先评估成本。
1. **Qt 绑定固定 PyQt5。** 不得改用 PyQt6 / PySide2 / PySide6,也不得安装其他绑定对应的 Fluent Widgets 包。
2. **Admin 新建采购任务固定为真实下单(不支付)。** Admin 提交创建表单即表示创建真实采购任务,不再重复要求风险复选框或确认短语;任务只能分配给已授权并声明 live 能力的 Client。Client 仍须通过设备绑定、商品/规格/数量/价格复核、不可逆标记和单次提交门禁。
3. **不绕过拼多多的验证码、风控和安全机制**,不自动注册登录,不自动付款。
4. **凭据(token、Cookie、密码)不得写入** `data/`、日志、数据库、Gitea 工单和 `docs/task`。
5. **任务一旦进入不可逆阶段**(`task_runs.irreversible_action_at` 有值),**只准核对订单,绝不重新下单**。
改动看起来再合理,只要碰到上面任意一条,先停下来告诉用户。
> **动代码之前,先读对应子项目的 AGENTS.md**,那里有技术栈、分层和硬性规则,本文件不重复:
>
> | 你要改的东西在 | 先读 | 技术栈 |
> |---|---|---|
> | `client/` 桌面客户端 | [client/AGENTS.md](client/AGENTS.md) | Python + PyQt5 |
> | `admin/` 管理端 | [admin/AGENTS.md](admin/AGENTS.md) | Go + Gin + HTML 模板 |
>
> **两个子项目技术栈完全不同,规则不通用,不要拿一边的经验套另一边。**
>
> 第一次接手,先看对应的上手指南和术语表:
> [Client](docs/client/00-getting-started.md) · [Admin](docs/admin/00-getting-started.md)
## 需求、缺陷与任务工作流
本流程适用于新需求、缺陷修复、重构以及会改变程序行为的任务。正式工单采用 **史诗级大工单(Epic)→ 最小可行产品工单(MVP)→ 单元任务工单** 三级结构。Gitea 工单是实施期间的事实来源,本地 `docs/task` 是任务完成后的最终归档。
工单和归档直接使用 [docs/templates/task.md](docs/templates/task.md) 里的模板,不要每次自拟结构。
### 0. 小改动直通
**不改变程序行为**的改动可以直接提交,不必建工单、不必归档,只需在提交信息里写清改了什么:
- 错别字、注释、文档措辞;
- 代码格式、导入排序、变量改名(不跨文件、不改公开接口);
- 补充类型标注、补充文档字符串;
- 删除确认无人使用的死代码。
只要满足下面任意一条,就**不属于**小改动,必须走完整流程:
- 改了数据库结构、Admin 接口、任务状态或 `pdd_data` 结构;
- 改了采购、下单、幂等、崩溃恢复或线程相关代码;
- 改了界面上用户能看出来的东西;
- 你不确定它算不算小改动。
### 0.1 Gitea 使用约定
- **地址:** <http://ilaer.eicp.net:8418>
- **仓库:** `chengma/cmautobuy`
- **工单层级靠标题前缀区分**,不使用标签和里程碑(当前两者均未启用,
也不要去建——`AGENTS.md` §1 已说明阶段用章节和清单表达,不加正式层级):
| 前缀 | 含义 |
|---|---|
| `[Epic]` | 大工单 |
| `[MVP]` | MVP 工单 |
| 无前缀 | 单元任务 |
- **跨子项目:** Admin 的工单标题加 `Admin:` 前缀;Client 的不加前缀。
### 0.2 没有工单不许改代码
`[必须]` **正式实施前必须有 Gitea 工单号。** 聊天里的工单草稿**不算工单**——
它没有编号,提交引用不了,后续也追溯不到。
`[必须]` Gitea 连不上或信息缺失时,按 §3.6 输出完整草稿并说明阻塞,
然后**每次都明确询问用户是否授权本次直通**。
- **不得默认直通。**
- **不得因为上一次直通过,就默认这次也可以。**
### 0.3 防呆:看到工单链接就说明 Gitea 可用
`[必须]` **只要在任何地方看到本仓库的 Gitea 工单链接**——用户消息、提交信息、
`docs/task` 归档、代码注释——就说明 Gitea 是通的。此时必须:
1. 立刻回填 §0.1 缺失的信息(地址和仓库名从工单 URL 里就能拿到);
2. **停止使用直通路径**,改回正常的建单流程。
**这条是有代价换来的。** 曾经发生过:用户已经给出
`http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/12`,
地址和仓库名就在 URL 里,但助手没识别出那就是自己一直在要的信息,
继续拿"Gitea 未配置"当理由跳过建单,还在提交信息里写下
"Gitea 尚未配置,本次无对应工单号"——而同一个提交的标题里就引用着 `(#12)`。
`[必须]` 提交信息里**不得出现"Gitea 未配置 / 无工单号"这类说法**,
除非你在同一次回复里已经明确向用户说明阻塞并得到了直通授权。
### 1. 工单层级与职责
```text
史诗级大工单(Epic)
├── MVP 工单
│ ├── 阶段 1:单元任务工单
│ ├── 阶段 2:单元任务工单
│ └── MVP 集成验收
└── MVP 之后:后续版本的单元任务工单
```
- **大工单:**记录完整产品目标、总体范围与非目标、总体架构、阶段路线、全局风险、所有已知任务索引和最终完成标准。
- **MVP 工单:**记录首个可交付版本的范围与非范围、阶段计划、单元任务清单、集成风险和 MVP 验收标准。MVP 是大工单的可交付子集,不等同于普通开发阶段。
- **单元任务工单:**唯一的实际执行单位,记录具体问题、方案、修改范围、依赖、验收标准、实施记录和测试结果。
- **阶段:**默认使用大工单或 MVP 工单中的章节、清单或 Gitea 里程碑表达,不增加正式工单层级。只有阶段需要独立负责人、独立验收或复杂协调时才单独建工单。
- 原则上不再增加比单元任务更深的工单层级;复杂任务应拆成多个可独立验证的同级任务。
### 2. 需求讨论与总体方案确认
1. 用户提出需求、现象或缺陷,助手先复述目标并检查相关代码、日志和运行环境。
2. 助手按照软件开发规范分析并提出总体方案,明确:
- 已确认事实与仍待验证的假设;
- 根因或需求边界;
- 目标、非目标、建议方案和影响范围;
- MVP 边界以及 MVP 之后的内容;
- 阶段拆分、已知单元任务和依赖顺序;
- 风险、兼容性、回退方式和总体验证方法。
3. 用户审核总体方案,双方继续讨论和修订,直到用户明确确认最终方案。
4. 最终方案确认前默认只允许阅读、诊断、实验性验证和方案整理;不得提前实施正式代码、创建工单、提交 Git 或扩大范围,除非用户明确要求某项操作。
**这条和"类和函数骨架"的边界:** 用户自己写骨架不受本条限制,那是用户在表达需求。本条约束的是助手——方案确认前,助手不写实现代码、不提交 Git。用户已经写好骨架并要求补全时,视为该部分方案已确认,助手可以直接补全,但仍不得越出骨架范围新增功能。
### 3. 创建大工单、MVP 工单与单元任务
1. 用户确认总体方案后,先创建大工单,并写入完整目标、总体方案、阶段路线和所有已知任务索引。
2. 再创建 MVP 工单,在其中定义首个可交付范围、排除项、阶段、验收标准和 MVP 单元任务清单,同时与大工单双向关联。
3. 准备实施某个阶段前,先为其中已具备明确边界的工作创建单元任务工单,再把工单编号更新到 MVP 和大工单的任务清单。
4. 不必为尚不明确的远期工作提前创建空泛的单元工单;先在大工单中保留规划项,待范围清晰后再建单。
5. 每个 Gitea 工单必须使用自己的工单号作为唯一追踪编号,后续分支、提交、进度记录和本地归档都引用对应编号。
6. 如果 Gitea 暂时不可用,应先输出完整工单草稿并说明阻塞;未经用户同意,不得绕过建单直接进入正式实施。
### 4. 各层工单内容规范
大工单和 MVP 工单至少包含:
- 背景、目标、非目标和范围边界;
- 已确认总体方案和关键架构决策;
- 阶段或里程碑;
- 子工单清单及当前状态;
- 依赖、全局风险和回退策略;
- 集成及最终验收标准。
单元任务工单直接套用 [模板 A](docs/templates/task.md),必填项只有 6 条:
1. 基本信息(类型、父级大工单、所属 MVP/版本、阶段);
2. 要解决什么(缺陷附复现步骤);
3. 做什么 / 不做什么;
4. 已确认的实现方案(含预计修改文件);
5. 可逐项打勾的验收标准;
6. 验证方式(可复制的命令;需要真机时写明)。
"风险和回退"为选填,但改动涉及采购下单、数据库迁移或 Admin 接口时必填。
### 5. 单元任务拆分标准
单元任务不按固定数量机械拆分。每个任务应满足:
- 目标单一、边界清晰且可以独立理解;
- 具有明确输入、输出和可逐项检查的验收标准;
- 能够独立开发、测试、提交和回退;
- 修改文件和依赖范围可控,不混入顺手重构或无关修复;
- 一个提交或一组紧密相关的提交可以完成;
- 如果仍包含多个互不依赖的交付结果,应继续拆分为同级任务。
### 6. 新增工单与父工单同步
1. 出现新需求、缺陷、遗漏工作或技术债时,先判断它属于当前 MVP、MVP 后续版本,还是改变大工单总体范围。
2. 先创建新的单元任务工单,并填写父级大工单、所属 MVP/版本、阶段和依赖关系。
3. 属于当前 MVP 时,同时更新 MVP 工单和大工单的任务清单;不属于当前 MVP 时,只更新大工单和对应的后续版本/里程碑,不得擅自扩大 MVP。
4. 新工单会改变已确认范围、交付结果、验收标准或时间安排时,必须先更新父工单并交由用户重新审核,确认后才能实施。
5. 详细分析和实施记录只保存在单元工单;MVP 工单只维护交付进度和集成状态;大工单只维护总体路线和范围,避免三处复制同一正文。
### 7. Git 准备与任务实施
1. 只有单元任务工单已建立、方案和验收标准明确后,才能进入正式实施。
2. 开始前检查工作区和当前分支,保留用户已有及与任务无关的改动。
3. 严格按照单元工单范围实施;不得把其他工单、顺手重构或无关修复混入当前任务。
4. 只有存在与工单相关的实际文件变更时才提交 Git,不得为了流程创建空提交。
5. 提交信息应简洁描述变更并引用单元工单号,例如 `fix: 修复规格匹配 (#123)`。
6. 实现过程中执行与风险相称的检查和测试,把关键进度、测试结果和提交哈希记录到单元工单。
### 8. 实施中的变更管理
- 范围、技术方案、接口、数据结构、依赖、验收标准、测试计划、风险或交付时间发生变化时,必须先更新单元工单。
- 变化影响 MVP 工单或大工单时,还必须同步更新对应父工单的范围、风险、计划或任务索引。
- 会改变用户已确认方案或交付结果的实质性变化,必须先写入工单并再次交由用户审核,确认后才能继续实施。
- 不改变外部行为的普通实现细节可以继续推进,但应在单元工单的实施记录中说明重要取舍。
- 阻塞、失败方案、新发现的根因或无法完成的验收项必须及时更新工单,不得只保留在聊天记录或代码注释中。
- 工单状态必须与实际进度一致:待确认、待实施、进行中、阻塞、待验收、已完成。
### 9. 单元任务完成与本地归档
1. 完成实现后,先按单元工单的验收标准执行验证,记录实际结果和未验证内容。
2. 将实现代码按可理解、可验证的粒度提交,所有提交都引用单元工单号。
3. 更新单元工单,写明最终实现、与原方案的差异、测试结果、实现提交和遗留问题。
4. 将完整单元任务归档为 `docs/task/<工单号>-<简短名称>.md`,目录不存在时创建。
5. 本地任务文档直接套用 [模板 B](docs/templates/task.md),必填项只有 6 条:
1. 头部信息(工单号、标题、类型、父级、版本、状态、日期、Gitea 链接);
2. 背景与目标;
3. 最终方案(与建单方案有出入时写清差异和原因);
4. 改了哪些文件;
5. 验收结果(逐项);
6. 测试:执行的命令、结果、**未验证到的部分**。
第 6 条的"未验证到的部分"不允许留空,没有就写"无"。"遗留问题"为选填。
6. 单独提交本地归档文档,例如 `docs: 归档任务 #123`,并把归档提交哈希和文档路径回写到单元工单。
7. 用户验收通过或明确同意后关闭单元工单,并立即更新 MVP 工单和大工单的任务清单及汇总状态。
### 10. MVP 工单与大工单的完成顺序
1. 单元任务逐个完成、归档、验收和关闭。
2. MVP 范围内所有任务完成后执行集成、回归和 MVP 验收,记录跨任务测试结果。
3. MVP 验收通过后,在 `docs/task` 创建对应的 MVP 总结文档,提交并回写 Gitea,然后关闭 MVP 工单。
4. 大工单规划的所有版本和最终验收完成后,创建大工单总结文档,提交并回写 Gitea,最后关闭大工单。
5. 不得因为单元任务已完成而提前关闭 MVP 工单,也不得因为 MVP 已完成而提前关闭仍有后续范围的大工单。
### 11. 记录与安全原则
- Gitea 单元工单保留详细讨论、决策、进度和变更历史;MVP 工单和大工单保留汇总;`docs/task` 保存与最终代码版本对应的结论。
- 聊天记录不能替代 Gitea 工单或本地任务文档。
- 父工单使用 `- [ ] #工单号` / `- [x] #工单号` 等清单维护子工单索引,不复制子工单全文。
- 工单和归档中的命令、日志与截图必须去除密码、访问令牌、浏览器 Cookie、个人数据及其他敏感信息。
- 每个 Git 提交必须可理解、可验证、可追溯,且不得包含无关文件。
## 面向初级程序员的开发与文档规则
本项目默认由初级程序员阅读和维护。设计、代码、注释、文档和交付说明都应以容易理解、容易调试和容易继续修改为优先目标。
新人从这两份开始读,不要一上来啃基线文档:
- [docs/client/00-getting-started.md](docs/client/00-getting-started.md) —— 装环境、跑起来、常见报错
- [docs/client/00-glossary.md](docs/client/00-glossary.md) —— 专业术语一句话解释
### 类和函数骨架
- 初级程序员可以先创建类或函数骨架,再由助手按照已确认工单补全实现。
- 骨架应尽量写明名称、职责、参数、返回值和可能的错误;暂未实现的部分使用清晰的 `TODO`,不得伪装成已经完成。
- 助手补全骨架前先理解原有命名和职责,能在现有边界内完成时不要随意重命名、移动文件或重做架构。
- 如果骨架存在明显职责混乱、线程错误或安全风险,先解释问题并提出最小调整方案;涉及已确认方案变化时按工单流程重新审核。
- 补全后删除已经完成的 `TODO`,保留仍未完成且有明确原因的事项。
### 代码可读性
- 优先使用直白、常见的 Python 写法,不为减少几行代码使用晦涩技巧、元编程或过深继承。
- 类和函数保持单一职责;函数过长或同时处理界面、网络、数据库和自动化时,应按职责拆分。
- 名称应表达业务含义,避免无意义缩写以及 `data1`、`temp2`、`handle` 等模糊名称。
- 公共类、函数和复杂业务规则应提供简短中文文档字符串,说明“做什么、输入什么、返回什么、何时失败”。
- 注释重点解释“为什么这样做”和风险约束,不逐行翻译代码。
- 使用类型标注、枚举和小型数据对象表达边界;避免到处传递结构不明的字典。
- 错误应返回或抛出明确类型和信息,不使用裸 `except`,不静默忽略失败。
- 除非确实需要扩展点,不提前设计复杂抽象;出现第二个真实实现后再考虑提取通用层。
- 修改现有代码时保持风格一致,并尽量提供一个最小调用示例或对应测试。
### 文档编写
- 文档使用简洁、自然的中文,先说明用途和结论,再写必要步骤和规则。
- 一个文档只解决一个主要问题;使用短段落和短列表,避免堆叠大段理论说明。
- 专业术语统一收录在 [docs/client/00-glossary.md](docs/client/00-glossary.md)。新词要么在术语表里加一条,要么在正文用一句话解释,两者至少做一个;不能翻译的类名、字段名、命令和协议名保持原样。
- 命令和示例必须可以直接复制,并说明从哪个目录执行、预期看到什么结果。
- 数据结构、状态对应关系和接口字段优先使用小型表格或短示例;关系简单时不要绘制复杂架构图。
- 文档只记录稳定需求、使用方法和关键约束,不复制容易与代码失去同步的内部实现细节。
- 进度、临时方案和待办写入 Gitea 工单;完成记录写入 `docs/task`,不反复修改长期基线文档。
- 修改已有长文档时应顺便删除重复和过时内容,但不得为了缩短文档丢失安全、数据和验收约束。
- 文档末尾只列真正未解决、需要用户决定的问题,不添加泛化的“未来可优化”清单。
### 助手交付说明
- 面向初级程序员说明改了什么、为什么、从哪里开始读以及怎样运行验证。
- 优先给出最短可行操作,不一次列出大量可选方案;存在重要取舍时再解释替代方案。
- 报错分析应指出具体位置、直接原因、修复方法和验证方式,不只给出修改后的完整代码。
- 不假设维护者熟悉 Qt 线程、SQLite 事务、Admin 幂等或 uiautomator2 控件树;涉及这些概念时给出一句话背景。
## 子项目
本仓库有两个子项目,**技术栈完全不同,规则各自独立**:
| 子项目 | 是什么 | 规则文件 | 基线文档 |
|---|---|---|---|
| `client/` | Windows 桌面客户端,控制安卓设备执行采集和采购 | [client/AGENTS.md](client/AGENTS.md) | [docs/client/](docs/client/) |
| `admin/` | 本地 Web 管理端,管理商品、订单、任务和客户端 | [admin/AGENTS.md](admin/AGENTS.md) | [docs/admin/](docs/admin/) |
- 处理某个子项目下的需求、代码、测试或文档前,必须读取并遵循它的 `AGENTS.md`。
- 从仓库根目录启动时也不能跳过(本文件开头已重复提醒一次)。
- 按当前任务只读取相关文档,清单见 [文档索引](docs/README.md)。
- 子项目专用的技术栈、分层、安全和验证规则不在根文件重复维护。
### 两者的接口边界
Admin 和 Client 通过四个 HTTP 接口交互,**契约以 Client 侧文档为准**:
[docs/client/04-admin-api-contract.md](docs/client/04-admin-api-contract.md)。
改动接口时,两边的文档必须在同一个工单里同步更新,不允许只改一边。