docs: record one-click replacement contract and boundaries #258

This commit is contained in:
QiuSW
2026-09-10 15:52:03 +08:00
parent 3181302c16
commit 8cfd32babe
3 changed files with 48 additions and 6 deletions
+11 -2
View File
@@ -2,8 +2,8 @@
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Architecture-and-Code-Map
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Architecture-and-Code-Map.-
wiki_revision: 46a5f8234be2d55298779532058a0490a94d3167
synchronized_at: 2026-09-10T03:36:58Z
wiki_revision: 6c8866d6186d8d6cc022256f2f369cc3072e99b5
synchronized_at: 2026-09-10T07:50:14Z
<!-- gitea-wiki-mirror:end -->
# 架构与代码地图
@@ -411,3 +411,12 @@ Web 唯一展示位置为“采集采购 → SYB 同步记录”:列表状态
- 关联后读取现有采购准备;需要人工确认或不具备AI资格时停止自动链路并保留关联,其他情况调用原 AutoMatchMappings,沿用 #254 动态预算及原事务保存/上下文冲突保护。最后刷新实际处理阶段,不调用创建采购/订单接口。
- 运行期间冻结行、商品、手机;前端重复主动作禁用,切换偏好仍只影响未来操作。卸载或 keep-alive deactivated 令旧操作失效,禁止旧回调继续下一步;不声称已经取消服务端在途写入。异常仅有限GET回读和刷新,不自动重发POST。
- 验证命令:Server `go test -p 1 ./...`、`go build ./...`;Web `node --test tests/unit/syb-quick-link.test.cjs tests/unit/shopee-match-lifecycle.test.cjs`、`pnpm exec playwright test tests/e2e/syb-quick-link.spec.ts tests/e2e/shopee-match-lifecycle.spec.ts --workers=1`、受影响文件 ESLint、`pnpm build:prod`。SQLite 单连接并发测试不代替生产 MySQL 行锁验收;真实AI、生产数据、跨设备人工闭环待验证。
## SYB 行内一键替换(#258)
实现绑定 `2b01974`;部署与验收见 #258 发布证据。本节补充 #253,不改变原未关联入口。
- `syb-products/quick-link.js` 复用分体按钮、设备偏好和匹配/回读流程;已关联且允许处理阶段时同位置显示一键替换。先只读预览,固定任务、目标商品及规格版本;不同商品一次确认,同商品不重绑。
- `shopeeproduct/latest_collection.go` 在原 latestCollection 增加可选 replacement 模式。预览和提交均短事务锁定 SYB、Shopee、原PDD、设备、来源采集与目标PDD,核对旧关联及上下文。提交按预览 taskId 读取,不重新挑选后来采集的商品。
- Admin 路由注入 `purchase.ValidateQuickReplacement`,在事务内复用采购准备数据集及处理阶段计算,不调用 AI。缺少校验函数拒绝替换;客户端密钥不注入且仍拒绝 latestCollection。无新路由、权限、表或迁移。
- 关联完成后才执行现有 AI 匹配,不在数据库事务中等待 Provider;同一 SYB 正式采购创建与替换共用 SYB 行锁。历史采购快照不变。SQLite 合成测试覆盖冲突与串行并发请求,不能替代生产 MySQL 多连接锁验收。
+12 -2
View File
@@ -2,8 +2,8 @@
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Business-Rules-and-Glossary
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Business-Rules-and-Glossary.-
wiki_revision: 31d2dbd24acd8ac119dfd0d538c12d0525a2764f
synchronized_at: 2026-09-10T06:54:35Z
wiki_revision: d016609062586a278560226600b5a1443c6fb442
synchronized_at: 2026-09-10T07:50:17Z
<!-- gitea-wiki-mirror:end -->
# 业务规则与术语
@@ -560,3 +560,13 @@ Web 唯一展示位置为“采集采购 → SYB 同步记录”:列表状态
- 先保存关联,再复用现有颜色/尺码自动匹配及保存。有效已确认映射保留;普通部分匹配保存合格结果,AI故障不提交本轮新映射,但已保存关联保留。后续可从“去匹配”或详情人工继续。failed 且无人工/AI确认时不能自动跳过人工解析;uncertain 不统一拦截,仍以原采购准备规则为准。
- 操作完成不保证立即可采购,必须刷新现有处理阶段;缺规格、缺映射、解析需确认或其他原资格不满足时继续显示真实待处理阶段。不自动创建采购任务、不下单、不支付。
- 请求超时/网络中断只做有限回读,不重复提交;读回失败明确结果未确认,避免无限转圈。离开页面不代表后端停止或回滚。普通用户沿用现有采购员权限,无新管理员专属开关。
## SYB 已关联商品的一键替换(#258)
实现绑定 `2b01974`;部署与验收见 #258 发布证据。
- 复用一键关联及小箭头的位置,保留原查看 PDD 商品。PDD 待采集、采集失败、停用或缺价格的对应处理阶段可替换;采集中、已创建/运行采购、成功或结果未知不开放。服务端提交时再次检查,不能只相信按钮。
- 复用每用户/浏览器/API环境的手机偏好;首次选择继续当前行,小箭头仅切换偏好。预览仅选所选手机最新 completed/completed_partial 临时采集,部分成功或不可用不回退旧商品。确认后固定来源任务和目标,不改用新采集;来源状态、设备、目标规格或旧关联改变时拒绝。
- 不同商品显示一次确认,包含旧/新商品、手机和共享蝦皮档案影响;取消不写入。同商品不弹替换确认且不重写关联,只继续匹配。共享该蝦皮档案的 SYB 明细使用新关联,历史采购任务快照不改。
- 沿用既有更换关联和有效映射检查,再复用自动匹配保存。部分匹配、AI失败或解析需人工处理时保留已保存关联,显示真实处理阶段,不保证立即可采购、不自动创建采购。
- 网络异常只有限回读,区分目标商品、仍为原商品和其他关联,不把“已有某个关联”误报为本次替换成功;不自动重发写请求。没有新增后台作业、订单或付款操作。
+25 -2
View File
@@ -2,8 +2,8 @@
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
wiki_page: Android-Agent-API-Contract
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Android-Agent-API-Contract.-
wiki_revision: 23160c055e8f6185a4108e284afc8216b41373e5
synchronized_at: 2026-09-10T03:37:18Z
wiki_revision: a96638c0b97eac622d53b04420da7ca35a1c010d
synchronized_at: 2026-09-10T07:50:35Z
<!-- gitea-wiki-mirror:end -->
# MVP 共享 API 契约
@@ -1093,3 +1093,26 @@ requestId 沿用 UUID 约定,不增加批次表或全局幂等缓存。既有
- `/api/client/v1/.../link-pdd` 带 latestCollection 时返回403 FORBIDDEN,不扩大API Key授权模块;原手动 pddProductId 模式行为不变。
- Web 先GET详情及 #254 autoMatchTimeoutSeconds,再提交关联;关联响应中的冻结版本交给现有 auto-match。其匹配仍自动保存,无额外“保存修改”写请求。普通请求/回读每次10秒,auto-match 单独使用派生前端预算2T+20秒;业务拒绝直接提示,网络/匹配失败至多一次详情回读,再刷新准备状态,禁止自动POST重试。
- Server/Web 需配套更新并包含 #254;无需迁移/Android升级。现有人工关联、匹配阈值、规格/采购资格、任务与支付边界不变。
## Admin 一键替换最近采集候选(#258)
实现绑定 `2b01974`;仅补充 Admin,Android/API Key 不变。沿用 `POST /api/admin/v1/shopee-products/{productId}/link-pdd` 和原权限,不新增路由或迁移。
先请求只读预览(仍需 UUID requestId):
```json
{"requestId":"UUID","latestCollection":{"sybProductId":1,"deviceId":2,"specContextVersion":"当前详情版本","replacement":{"preview":true,"expectedPddProductId":3}}}
```
响应 `product` 保持原关联,`collectionSource` 返回 taskId、deviceId、pddProductId、requiresSpecConfirmation,并增加 targetVersion、title、goodsId、previousTitle、previousGoodsId、deviceName。预览没有关联写入。
确认提交沿用同一 SYB/设备/详情版本与原商品ID,replacement 改为:
```json
{"preview":false,"expectedPddProductId":3,"taskId":4,"targetPddProductId":5,"targetVersion":"预览返回值"}
```
- 提交按指定 taskId 核对临时采集来源、设备、completed/finishedAt、目标ID、可用规格及 targetVersion;不重新选择最新任务。旧关联、旧/目标规格版本变更返回现有409上下文冲突;阶段不再允许返回409 PDD_LINK_CONFLICT;来源不可用409 LATEST_COLLECTION_UNAVAILABLE;缺字段422。
- 不同商品条件更新旧关联,返回更新后的 product.specContextVersion;同商品不更新关联及 last_update_request_id,但仍返回用于后续匹配的当前版本。请求不是持久化重放协议;客户端超时只回读、不自动重发。
- 预览与提交都校验当前允许阶段;采集中拒绝。复用现有人工更换关联的映射语义,后续 auto-match 自动保存及预算沿用 #254。部分匹配/AI故障不回滚已提交关联。
- 不提供 replacement 时 #253 行为不变;`/api/client/v1` 携带 latestCollection(包括 replacement)仍403,不扩大客户端密钥授权。