Files
cmbuyer/docs/current-state.md
T

164 lines
10 KiB
Markdown
Raw Normal View History

# 当前实现状态
> 本文是可覆盖的**项目级快照**,记录代码与任务的现实状态。
> 执行记录写进各任务文件(`docs/tasks/T-<编号>.md`)的 `## 执行记录`,不在本文重复维护。
## 职责边界
- [`tasks/`](tasks/README.md):任务规格、依赖、状态(frontmatter)和执行记录,一任务一文件。
- [`06-tasks.md`](06-tasks.md):只读路线图,维护阶段划分、里程碑和待办池。
- `current-state.md`:当前快照,可覆盖更新。
## 当前快照
- 日期:2026-08-03
2026-08-03 18:55:32 +08:00
- 阶段:**Phase 0 · 地基(两端骨架、核心数据模型与统一入口已完成,尚无真机采购业务代码)**
- MVP 形态:手工填链接建单 → 批量开始试选 → 定时轮询 → **第一趟试选** → 人工确认 → **第二趟下单** → 待付款
- 技术栈:已定。采购服务(`admin/`)使用 Go 1.23+ / gin / SQLite;采购工具(`client/`)
使用 Python 3.11+ / uiautomator2 / PySide6。
详见 [`03-tech-stack.md`](03-tech-stack.md)
2026-08-03 18:55:32 +08:00
- 生产代码:`admin/` 已有最小 Go 服务、健康检查、核心领域模型、SQLite 迁移与任务状态机;
2026-08-03 19:28:39 +08:00
`client/` 已有 Python 包、PySide6 最小入口、运行目录与日志脱敏策略,以及显式 serial 的 ADB
连接边界与本地基线取证 CLI;尚无真机采购流程
- 测试:采购服务已覆盖健康检查、核心模型、迁移与状态机等离线包级测试;采购工具 30 项离线单元测试
2026-08-03 19:28:39 +08:00
(全部 mock,不连接真机)
2026-08-03 18:55:32 +08:00
- 数据:SQLite 核心表与迁移已落成;无业务实例数据
- 标准启动路径:Windows PowerShell 运行 `./init.ps1`,Unix shell 运行 `./init.sh`。Windows 入口
优先使用合规的既有 venv;仅在其缺失时才从 Python Launcher 已安装版本中选择最高的 Python 3.11+,
并且不覆盖低版本环境;成功后打印真实启动命令。
- 标准验证路径:`./init.ps1` 已实际跑通 admin 的 mod download / test / vet / build、client 的
editable install / 包导入 / unittest / compileall,以及仓库上下文校验。可单独运行两端命令诊断。
- 当前 blocker:无外部 blocker。T-101 已完成人工 USB/WiFi 双通道验收;下一步落成并领取 T-102,
验证按链接打开商品详情页。桌面 GUI 与后续真机采购流程尚未验收。
## 当前目录要点
| 路径 | 状态 | 说明 |
| --- | --- | --- |
| `docs/` | 已有 | 项目规范化文档,本次已完整生成 |
| `docs/tasks/` | 已有(T-001~T-004、T-005~T-009、T-101) | T-001~T-004、T-101 已完成;下一任务为 T-102 |
2026-08-03 17:47:22 +08:00
| `docs/design/` | 已有(6 个原型) | web 登录 / 建单 / 工作台 / 详情,desk 采购执行 / 配置;均已人工确认 |
| `scripts/` | 已有 | 上下文门禁、Vikunja 单向导出与 MCP 启动包装 |
2026-08-03 18:55:32 +08:00
| `admin/` | 已初始化 | Go 1.23+ / gin / SQLite,含核心模型、迁移与状态机;无真机采购执行 |
2026-08-03 19:28:39 +08:00
| `client/` | 已初始化 | Python 3.11+ 包、依赖源、PySide6 最小入口、显式 serial 的设备基线取证、离线测试与 wheel 元数据检查;无采购流程 |
2026-08-03 18:55:32 +08:00
| `init.ps1` / `init.sh` | 已完成 | 统一安装与离线验证入口;PowerShell 优先复用合规 venv,缺失时自动选择最高的 Python 3.11+,Unix 缺工具链明确失败 |
## 任务状态
任务状态以 `docs/tasks/` 各任务文件 frontmatter 的 `status` 为准。本节只写项目级摘要:
2026-08-03 17:47:22 +08:00
- 已完成:T-005(采购服务交互原型)、T-006(采购工具交互原型)、T-007(产品名称与
源码目录契约)、T-008(Vikunja 任务权威与单向导出)、T-009(MVP 关键路径与并行波次),
以及 T-001(采购服务 Go 骨架)。
2026-08-03 18:55:32 +08:00
- 已完成:T-002(采购工具 Python 骨架)、T-003(双端统一初始化与验证入口)、
T-004(核心数据模型)、T-101(真机环境盘点与 USB/WiFi 双通道人工验收)。下一步推进
T-102 → T-103。
2026-08-03 17:47:22 +08:00
- T-103 是当前最高优先级和 MVP 生死线。通过前不开发依赖真机可读字段的 Phase 2 生产页面。
- 已确认原型继续只作信息架构依据;原型假数据不调用真实接口、不驱动真机。真机结论改变
可读字段时必须先回修原型与交互清单。
## 当前可运行内容
2026-08-03 18:55:32 +08:00
Windows 统一安装、离线验证与启动命令提示已可运行:
2026-08-03 18:55:32 +08:00
```powershell
.\init.ps1
```
2026-08-03 18:55:32 +08:00
它会在成功后输出以下真实启动命令,而不自动启动或连接设备:
2026-08-03 18:55:32 +08:00
```text
采购服务:cd admin; go run ./cmd/server
采购工具:cd client; .\.venv\Scripts\python.exe -m cmbuyer_client
```
采购工具当前可运行的离线验证与 wheel 元数据检查:
```powershell
cd client
2026-08-03 18:55:32 +08:00
.\.venv\Scripts\python.exe -m unittest discover -s tests -t .
.\.venv\Scripts\python.exe -m compileall -q src tests scripts
$wheelDir = Join-Path $env:TEMP ('cmbuyer-client-wheel-' + [guid]::NewGuid())
New-Item -ItemType Directory -Path $wheelDir | Out-Null
2026-08-03 18:55:32 +08:00
.\.venv\Scripts\python.exe -m pip wheel --no-deps . --wheel-dir $wheelDir
.\.venv\Scripts\python.exe scripts/verify_wheel_metadata.py (Get-ChildItem $wheelDir -Filter '*.whl').FullName
```
采购工具规范安装与本地开发入口:
```powershell
2026-08-03 18:55:32 +08:00
# 在仓库根执行统一初始化;成功后再进入 client/
.\init.ps1
cd client
.\.venv\Scripts\python.exe -m cmbuyer_client
```
`client/requirements.txt` 是唯一依赖来源,`client/pyproject.toml` 动态读取它生成 wheel 的
`Requires-Dist`。Python 3.12 与 3.14 均已验证离线测试、编译与 wheel 元数据;完整运行时依赖安装
2026-08-03 18:55:32 +08:00
(`pip install -e .`)已通过。`init.ps1` 优先使用合规既有 venv,缺失时自动选择最高的 Python 3.11+;
本机 Python 3.12 与 3.14 均已验证,主工作区当前选择 Python 3.14。桌面 GUI 与真机流程未作为 T-003
验收执行。
2026-08-03 19:28:39 +08:00
T-101 的人工真机验收命令(先把手机切到不含收货地址、手机号、支付信息或其他无关隐私的安全页面;
必须从 `adb devices -l` 手工复制在线 serial,不能留空或自动选择):
```powershell
# 仓库根目录;USB 和 WiFi 分开执行,每次只保留一个通道在线
D:\Portable\adb\adb.exe devices -l
.\client\.venv\Scripts\python.exe client\scripts\capture_device_baseline.py --serial <USB_SERIAL> --output-dir "$env:LOCALAPPDATA\cmbuyer\artifacts\T-101\usb-baseline" --timeout 10 --adb D:\Portable\adb\adb.exe
# WiFi 必须由人先建立通道、断开 USB 后再手工粘贴在线 WiFi serial;脚本不自动 connect/reconnect
.\client\.venv\Scripts\python.exe client\scripts\capture_device_baseline.py --serial <WIFI_SERIAL> --output-dir "$env:LOCALAPPDATA\cmbuyer\artifacts\T-101\wifi-baseline" --timeout 10 --adb D:\Portable\adb\adb.exe
```
脚本只读取非敏感设备元数据、拼多多版本、截图和完整 XML;不会打开商品或写页面判据。它对同机双
通道、身份读取失败、offline、unauthorized、超时或 serial 不存在均 fail closed。成功目录的
`manifest.json` 只记录元数据、产物路径和 SHA-256,不记录 XML 页面正文或原始 serial。T-101 已由人
完成两次验收并确认原始证据不含敏感信息;`--timeout` 约束 ADB 命令、ADB socket 以及截图/节点树的
公开 JSON-RPC 调用,uiautomator2 初始化仍有上游固定启动上限。截图/XML 只保留在本地,执行记录只写
路径和 SHA-256,原始证据不得提交 Git。
2026-08-03 19:28:39 +08:00
## 关键背景
本项目是 `cmroubao`(Go 后端 + Android AccessibilityService)与 `cmpdd`
(Python + uiautomator2)两个前序项目的合并重启。
- 取 `cmroubao` 的后端任务生命周期、设备侧 API 形状、下单授权状态机、ERP 对接、管理 Web。
- 取 `cmpdd` 的 uiautomator2 真机自动化、按维度精确选规格、订单确认页读取、付款闸门。
- 丢弃自研 Android APK 与 AccessibilityService 感知层。
**前序项目是设计依据,不是事实来源。** 其中的结论(尤其是拼多多页面判据)必须在本项目
用真机重新验证,且记录取证时的拼多多 App 版本。
## 已知风险(开工前须知)
1. **M2 是生死线**:真机能按链接打开商品、精确勾选颜色分类和尺码、**读到该 SKU 单价**
(T-103)。Phase 1 不通过之前不要写生产页面;Phase 0 原型只确认流程和信息架构,真机
结论改变字段时必须回修。
2. **拼多多页面结构随版本变化**,已观察到详情页无独立规格入口、价格节点被拆分等情况。
3. **授权卡死**:前序项目出现过 `EXECUTING` 授权永不推进导致任务锁死。本项目在 T-207
实现围栏前超时 / 放弃,在 T-208 实现围栏后调和;围栏后不得释放或重试。
4. **规格面板单价位置未取证**:闸门一依赖它,T-103 必须一并取证。若读不可靠,
确认页设计要改。
5. **MVP 已收窄**:只做手工填链接、批量开始第一趟试选和两趟执行。Excel、ERP、图搜、
批量顺序编排 / 暂停接管、订单自动核对、AI 辅助全部推到 V2(见 `06-tasks.md` 的
T-501~T-508)。
6. **App 版本必须 fail closed**:运行时拼多多版本与本项目已取证版本不一致就停止领取,
不允许用旧判据继续跑。
## 开始编码前检查
1. 读 [`../AGENTS.md`](../AGENTS.md)。
2. 读 [`00-ai-start-here.md`](00-ai-start-here.md),特别是「本项目的四条特有纪律」。
3. 读 [`05-coding-rules.md`](05-coding-rules.md),特别是第 1 节红线。
4. 在 `docs/tasks/` 找 `status: TODO` 且依赖均 `DONE` 的任务文件;暂无时先按
[`06-tasks.md`](06-tasks.md) 落成任务文件。
5. 在独立分支 / worktree 把任务改为 `DOING` 后再改生产代码。
## 维护规则
实际代码状态变化时同步更新本文:新增或移动入口文件、初始化框架、新增可运行命令、
发现文档与代码不一致、阶段或 blocker 变化。
任务长期状态改在对应任务文件的 frontmatter;每轮执行记录、验证命令、阻塞点和关键决策
写进该任务文件的 `## 执行记录`。本文只保留当前快照,不保留完整历史。