Files
cmautobuy/client/AGENTS.md
T
chengmaandClaude Opus 5 4f920f9d8b docs: 排除蝦皮原始报表,并同步主按钮文案
raw_data 不进 Git
原始报表含逐商品台币销售额等商业数据,进了 Git 就是永久历史。
- .gitignore 排除 raw_data/
- 改掉三处"仓库里有一份样本"的失真表述,改为向项目负责人索取
- 06 §2.1 相应加强:既然大样本不进库,admin/testdata/ 下的脱敏小样本
  就必须提交,否则别人拉下来测试跑不了;并写明脱敏做法

主按钮文案 开始自动获取 → 获取任务 ⇄ 停止获取
只改按钮标签。"自动获取"作为功能名保留(状态栏、Tab 顺序、
协调器开关等处不动),05 §4.1 加了一句说明两者不是一回事。

已知遗留:pdd_ui.py 自身仍不一致——构造时用「获取任务」,
但状态机 485/487 行仍是「开始自动获取」/「停止自动获取」,
会覆盖掉构造时的文字。该文件有未提交改动,本次未触碰,
差异已记入 02 §3.1,需另开工单修。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 15:58:09 +08:00

118 lines
7.5 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.
# Client 子项目规则
本文件适用于 `client/` 下的全部代码和测试,并继承仓库根目录 `AGENTS.md` 的工作流、Git、安全、文档和初级程序员维护规则。
## 开始工作前
- 从仓库根目录执行 Client 任务时,也必须先读取本文件。
- 第一次接手本项目,先看这两份:
- 环境和运行:[00 上手指南](../docs/client/00-getting-started.md)
- 看不懂的词:[00 术语表](../docs/client/00-glossary.md)
- 只读取与当前任务有关的长期基线,不必每次加载全部文档:
- 需求边界:[01 产品需求基线](../docs/client/01-requirements.md)
- 模块和线程:[02 系统架构](../docs/client/02-architecture.md)
- SQLite 与 JSON:[03 数据模型](../docs/client/03-data-model.md)
- Admin 对接:[04 接口契约](../docs/client/04-admin-api-contract.md)
- 页面和交互:[05 界面规范](../docs/client/05-ui-specification.md)
- 测试和采购安全:[06 质量与安全](../docs/client/06-quality-security.md)
- 文档仍是草案或存在未决事项时,不得自行选择会改变业务结果的答案,应按根目录工单流程确认。
## 技术栈
- 固定使用 **Python 3.10 + PyQt5 + Qt Widgets + PyQt-Fluent-Widgets**。
- 界面组件优先使用 `qfluentwidgets`;没有合适组件时再使用 PyQt5 标准控件。
- 只有两者都无法满足明确需求时才创建自定义控件,并说明原因。
- 不得混用 PyQt6、PySide2 或 PySide6,也不得安装其他 Qt 绑定对应的 Fluent Widgets 包。
- 当前开发和验证解释器为 `C:/Python310/python.exe`。
- 依赖及版本以 `client/requirements.txt` 为准,版本必须固定。
- 新增或升级依赖前先检查准确版本、许可证和打包影响,并经过工单确认;确认后同步更新 `requirements.txt`。
## 代码分层
- 界面层只负责显示和输入转发,不直接调用 Admin、SQLite 长查询或 uiautomator2。
- `src/ui_main.py` 负责应用和窗口装配;页面界面放 `src/<页面>_ui.py`,事件绑定放 `src/<页面>_ui_event.py`(当前有 `pdd_ui` / `settings_ui` 两组)。
- 每个文件顶部的模块 docstring 写明了该文件的约束,动手前先读那几行。
- 领域模型不导入 Qt、uiautomator2 或具体 HTTP 客户端。
- Admin 通过 Gateway 接口隔离,Mock 和 HTTP 实现必须遵守相同契约。
- SQLite 通过 Repository 访问,不在页面或自动化函数中散落业务 SQL。
- PDD 页面识别、采集和采购函数放在 PDD 适配层;演示脚本不得被正式流程直接导入。
- 类和函数骨架遵循根目录的初级程序员维护规则,优先补全现有清晰边界,不随意重做架构。
## 数据与接口
- 数据库字段、任务状态和 `pdd_data` 结构以 `docs/client/03-data-model.md` 为准。
- Admin 路径、字段和幂等语义以 `docs/client/04-admin-api-contract.md` 为准;Admin 未完成时使用 Mock,不臆造正式响应。
- Client 与 Admin 只有三个调用:领取、提交结果、提交失败。**不得新增"向 Admin 查询状态"类接口。**
- 金额使用人民币分整数,时间使用带时区 ISO 8601,稳定任务编号不得使用表格行号代替。
- 文件路径一律通过 `data_dir()`(可写数据)和 `app_dir()`(只读资源)获取,见 [03 数据模型 §2.2](../docs/client/03-data-model.md)。**不许硬编码路径,不许用 `os.getcwd()` 或 `__file__` 直接拼**,打包成 exe 后会失效。
- PDD 结果必须先写入 SQLite,再通过 Outbox 提交 Admin。
- 任务领取后中途不查 Admin 状态;Admin 取消或重派一律不感知,做完照常提交。
## 线程与自动化
- QWidget 只能在 Qt 主线程创建和访问。
- 禁止在主线程执行 Admin 请求、uiautomator2/ADB、`time.sleep()`、轮询、大型 XML 解析或文件批量写入。
- 长任务统一使用 `QObject` + `moveToThread` 的 Worker 写法,模板见 [02 架构 §5.1](../docs/client/02-architecture.md);不得混用 `QThread` 子类、`QRunnable` 或 `threading`。
- 后台结果通过信号回到主线程;窗口关闭时按 [02 架构 §5.2](../docs/client/02-architecture.md) 断开连接,防止迟到结果访问已销毁控件。
- 一个 Android 设备同一时间只由一个工作线程控制,不跨线程共享 uiautomator2 Device 对象。
- 自动化任务必须处理启动、运行、安全停止、成功、失败、取消、超时、设备断开和迟到结果。
- 窗口或页面销毁后,后台回调不得再访问对应控件。
## 采购安全
- 真实下单开关默认关闭;未满足质量文档中的采购安全门禁不得启用。
- 高风险点击前必须使用最新页面状态重新校验商品、规格、数量、价格和目标坐标。
- 进入不可逆下单阶段前先持久化执行步骤。
- 不可逆阶段发生崩溃或结果不确定时,只能核对订单或转人工处理,禁止自动重新下单。
- 多个订单候选、验证码、登录失效、未知弹窗、价格超限或规格不确定时停止自动执行。
## 界面规则
- 顶级模块保持为“PDD 任务”和“设置”,页面使用唯一且稳定的 `objectName`。
- 优先使用 `FluentWindow`、Fluent 导航、主题和图标;不得使用表情符号充当结构图标。
- 使用布局、尺寸策略和伸缩项,不用固定坐标排列常规界面。
- 任务表格使用模型/视图和稳定任务编号,不把完整 `pdd_data` 放入隐藏列,也不为每个单元格创建常驻 QWidget。
- “获取任务”(启动后变为“停止获取”)是界面上唯一会产生外部后果的命令;其余操作只读本地数据库。
- 本地只保存已领取的任务,不缓存 Admin 任务池;已完成任务永久保留,不得清理。
- 普通成功更新页面状态即可;可恢复错误使用 `InfoBar`,只有必须阻断决策时才使用模态对话框。
- 主要流程必须支持键盘;表单具有可见标签;状态和错误不能只依赖颜色。
- 验证浅色、深色、Windows 贴靠和 100%–200% 显示缩放。
- 避免全局 QSS 覆盖 Fluent 控件;局部样式必须保留悬停、按下、焦点和禁用状态。
## 验证
全部命令从 `client/` 目录执行,可直接复制。
**1. 语法检查**(改了哪个文件就换成哪个)
```powershell
C:/Python310/python.exe -m py_compile src/ui_main.py
```
**2. 界面离屏冒烟测试**(不弹窗口,跑完自动退出,CI 和本地都用这条)
```powershell
$env:QT_QPA_PLATFORM="offscreen"
C:/Python310/python.exe -c "from src.ui_main import MainWindow; from PyQt5.QtWidgets import QApplication; app=QApplication([]); w=MainWindow(); print('OK'); app.quit()"
Remove-Item Env:QT_QPA_PLATFORM
```
打印 `OK` 即通过。
**3. 手动看界面**
```powershell
C:/Python310/python.exe buyer_main.py
```
当前 `buyer_main.py` 只装配并显示窗口,**不连接设备、不执行任何自动化**,可以随时运行。
将来“获取任务”接上真实设备后,**启动自动化的命令会产生真实外部操作,届时不得作为普通冒烟测试运行**;那时的日常验证仍以第 2 条离屏测试为准。
**4. 其他情况**
- 修改数据库时测试首次建库和从上一版本迁移。
- 修改 Admin Gateway 时运行 Mock 与 HTTP 共用的契约测试。
- 修改 PDD 解析时优先使用脱敏 XML 固件;真实设备测试必须单独标记并说明是否执行真实下单。
- 交付时说明已运行的命令、结果、未验证的设备行为和新增依赖。