docs(architecture): adopt authorized single-pass purchase

This commit is contained in:
QiuSW
2026-08-04 16:25:34 +08:00
parent 8ba9b231f4
commit cfd5440ac0
23 changed files with 1264 additions and 1835 deletions
+24 -29
View File
@@ -9,13 +9,10 @@ cmbuyer 是一个自动化采购系统:**采购服务**(网页端,`admin/`
**采购工具**(桌面端,`client/`)驱动 Android 手机在拼多多完成找货和下单,
**付款始终由人完成**。
第一版 MVP 只做**任务自带商品链接**的情形,**分两趟跑**:
1. **第一趟试选**:桌面端定时领取 → 开商品 → 精确勾选颜色分类和尺码 → 读单价 →
截图 → **退出释放手机** → 回传。
2. **人工确认**:管理员在网页端看「机器选对了吗」,确认后签发授权并**锁定单价**。
3. **第二趟下单**:重新开商品 → 重新选同一规格 → **三道价格闸门** → 提交订单一次 →
任务转「待付款」,人在拼多多核对后付款。
第一版 MVP 只做**任务自带商品链接**的情形。创建任务不授权;管理员勾选 `DRAFT` 并点击
“开始采购(只创建待付款订单)”后,服务端锁定商品、规格、数量和最高总价并签发一次性授权。
采购工具领取后在**同一趟**完成精确选规格、三道价格闸门、数量复核、确认页、提交围栏和唯一一次
“提交订单”点击。中间不等待人工确认;订单创建后转待付款,由人核对和付款。
## 上下文读取
@@ -24,7 +21,7 @@ cmbuyer 是一个自动化采购系统:**采购服务**(网页端,`admin/`
1. [`01-vision.md`](01-vision.md):为什么做、为谁做、什么不做。
2. [`02-requirements.md`](02-requirements.md):MVP 要什么、怎么算达成。
3. [`03-tech-stack.md`](03-tech-stack.md):两端各自的技术选型与验证矩阵。
4. [`04-architecture.md`](04-architecture.md):双端职责、**两趟执行**、**三道价格闸门**、安全边界、数据模型。
4. [`04-architecture.md`](04-architecture.md):双端职责、**单趟执行**、**三道价格闸门**、安全边界、数据模型。
5. [`05-coding-rules.md`](05-coding-rules.md):写代码前必须遵守的规则。
6. [`06-tasks.md`](06-tasks.md):阶段路线图与建议拆分。
7. [`tasks/README.md`](tasks/README.md):任务文件约定。
@@ -61,7 +58,7 @@ cmbuyer 是一个自动化采购系统:**采购服务**(网页端,`admin/`
### 2. 安全边界只能收紧,不能放宽
[`04-architecture.md`](04-architecture.md) 第四节的硬约束(不付款、提交订单四条件与服务端围栏、
规格精确匹配、提交控件唯一、数量必须复核、三道价格闸门、第一趟不下单、外部支付停止、
规格精确匹配、提交控件唯一、数量必须复核、三道价格闸门、隔离能力不越界、外部支付停止、
安全校验停止、敏感信息不提取、授权一次性)**不得在任务中顺手放宽**。
确需变更时先改架构文档并说明理由,再动代码。任何「为了让流程跑通先放宽一下」的改动
@@ -77,11 +74,11 @@ cmbuyer 是一个自动化采购系统:**采购服务**(网页端,`admin/`
理由与三道闸门的定义见 [`04-architecture.md`](04-architecture.md) 第三节。
### 4. 第一趟绝不下单
### 4. 真机能力逐段取证、隔离开放
试选阶段只勾选规格和读价,**绝不点击「现在买」或任何进入下单流程的入口**。
第一趟的代码路径不得引用 `go_to_order_confirm()` 与 `submit_order()`,必须有测试
证明它们不可达。
T-103 的 `SkuSelectionFlow` 只允许证据绑定的受控入口、精确选择、读价和安全退出;不得引用
数量、确认页、提交围栏、提交或付款能力。T-105~T-107 分别取证后才可组合。生产单趟只有在全部
能力均获证据、三道闸门通过且服务端围栏明确许可后才能点击一次;支付能力永不开放。
## 当前阶段
@@ -90,19 +87,18 @@ cmbuyer 是一个自动化采购系统:**采购服务**(网页端,`admin/`
执行按任务依赖驱动,**不按 Phase 整段串行等待**。当前优先路径:
1. T-001~T-004 与 T-101~T-102 已完成,继续推进 **T-103 真机取证**。
2. T-103 进行时并行推进 T-201 管理会话 → T-202 `DRAFT` 建单与基础列表;两者不得启动试选,
也不得引入机器结果、规格面板单价或证据字段。
3. T-103 结论确认后,再推进 T-203 批量开始试选、T-204 试选证据详情、T-205~T-207,
并按依赖推进 T-104 → T-107 后续真机安全判据。
4. Phase 3:双端打通与**第一趟试选**端到端。
5. Phase 4:**第二趟下单**与收尾。
1. T-111 先冻结“开始采购授权”的单趟契约;同时主审并合入只创建 `DRAFT` 的 T-202。
2. T-111 完成后恢复 **T-103 真机取证**;按依赖推进 T-104 → T-107 的分段安全判据。
3. admin agent 先做 T-209 把旧两趟 schema / 状态机迁到单趟,再推进 T-203 服务端批量开始采购 /
一次性授权;两者不依赖页面选择器。T-205 起的 attempt 与证据字段等待 T-103。
4. Phase 3:双端打通与单趟围栏前 dry-run。
5. Phase 4:单趟真实提交、待付款、调和与收尾。
6. V2 及以后:图搜、Excel、ERP、订单自动核对、AI 辅助。
> **M2 是本项目的生死线**:真机能按链接打开商品、精确勾选颜色分类和尺码、
> **读到该 SKU 的单价**(T-103)。前序项目正是卡在选规格和读价。
> M2 不通过之前不要写**依赖真机可读字段或会启动试选**的 Phase 2 功能;T-201 与仅创建
> `DRAFT` 的 T-202 可以并行。原型只确认流程与信息架构,实际可读字段仍以真机证据为准。
> M2 不通过之前不要写**依赖真机可读字段的生产执行逻辑**;管理会话、`DRAFT` 建单和只锁定
> 已有任务字段的服务端授权事务可以并行。实际可读字段仍以真机证据为准。
## 领取任务规则
@@ -123,12 +119,11 @@ cmbuyer 是一个自动化采购系统:**采购服务**(网页端,`admin/`
只做:
- **手工填链接**建单、任务查询、勾选待开始任务后批量开始第一趟试选
- 桌面端**定时轮询**领取(试选与下单两类)
- 第一趟试选:精确勾选规格、读单价、截图、退出释放手机
- 人工确认「机器选对了吗」并签发授权(**锁定单价**)
- 授权超时与放弃,任务不会被永久锁死
- 第二趟下单:三道闸门全过后提交订单一次
- **手工填链接**建单、任务查询、勾选待开始任务后批量“开始采购”
- 点击开始采购即签发锁定商品、规格、数量和最高总价的一次性授权
- 桌面端定时轮询只领取已授权任务,在同一趟精确选规格、两次读价、复核数量和确认页金额
- 围栏前失败/过期可人工回到待开始;围栏后只能调和
- 三道闸门全过、服务端围栏明确许可后提交订单一次
- 真实点击前服务端原子建立提交围栏;围栏失败不点击,围栏后只调和同一提交记录
- 待付款展示订单截图,人核对付款后手工标记完成
- 失败分类与转人工
@@ -168,7 +163,7 @@ cmbuyer 是一个自动化采购系统:**采购服务**(网页端,`admin/`
| 采购服务页面 | `02-requirements.md` 验收 → `07-user-stories.md` → `08-interaction-checklist.md` → `routes.md` → `04-architecture.md` |
| 采购工具界面 | 同上,`routes.md` 看第三节桌面端结构 |
| 设备侧 API | `api.md` → `04-architecture.md` 数据模型与鉴权边界 |
| 真机自动化 | `04-architecture.md` 第三节两趟执行与三道闸门 → 第四节边界 → `api.md` 第三节模块合约 → **先真机取证** |
| 真机自动化 | `04-architecture.md` 第三节单趟执行与三道闸门 → 第四节边界 → `api.md` 第三节模块合约 → **先真机取证** |
| 数据模型 | `04-architecture.md` 第五节;schema 变化必须同步 `api.md` 和 `current-state.md` |
| 部署 / 运行 | `03-tech-stack.md` → `current-state.md` |