# 给 Trae 的开发交接说明 > 你(Trae)接手"采购主链RPA一期 · 状态中心"的后续开发。本文是你的入口,先读这份,再读下面点名的文件。写代码前把"硬规则"和"你不做什么"看完,别越界。 ## 一、你要干什么(一句话) 做**状态中心**:一个 Python(FastAPI)+ MySQL 的后台 + 配套网页。它负责"每一单跑到哪步、出错派给谁、存状态和证据、画步骤树状图给业务看"。它**自己不去点任何外部系统页面**——点页面是艺赛旗 RPA 的活,通过 HTTP 回调跟你交互。 ## 二、先读这几个文件(按顺序) 1. `资料/采购主链RPA一期需求文档_三方会审版.md` —— 业务规则(节点N01~N10、字段、异常)。 2. `资料/采购主链RPA一期设计文档.md` —— 技术设计(表结构、状态机、接口契约、对码引擎)。 3. `资料/采购主链RPA一期实施与验收规范.md` —— **每个节点的操作步骤 + 验收标准(代码+业务两栏)**,你做完对着这里勾。 4. `state_center/README.md` —— 已有代码怎么起、怎么验。 ## 三、技术栈(已定,别改) - 后台:Python 3 + FastAPI - 库:MySQL 8(状态中心自己的库,建库脚本 `sql/schema.sql` 已给) - 对码货品主数据:在 **Oracle**,只读直连查,**不要复制成本地表** - OCR:本地 Python 服务(PaddleOCR),仅线下手工单用 - 前端:Vue 或 React(待办页 + 步骤树状图 + 整单查询) - RPA 下层:艺赛旗 iS-RPA(不是你做,你只跟它的 HTTP 回调对接) ## 四、已经写好的(别重写,在这上面接着做) `state_center/` 里已有可跑的第1步骨架: | 文件 | 已实现 | 状态 | | --- | --- | --- | | `sql/schema.sql` | 8张表建库脚本 | 完成 | | `app/config.py` | MySQL/Oracle 连接、Oracle表名列名占位 | 完成 | | `app/db.py` | MySQL 访问(pymysql) | 完成 | | `app/match_engine.py` | 对码引擎:两级命中+规格标准化+Oracle取数函数 | 完成,单测6/6过 | | `app/main.py` | 建单 + start/complete/fail 三回调(含幂等/乱序拒绝)+ 合同审批等待 + 整单查询 | 骨架完成 | | `tests/test_match_engine.py` | 对码单测 | 通过 | > 状态机流转已通(**13 节点 = 11 主 + 2 条件** 显式转移表、业务编号回写、回调幂等、乱序拒绝 409、合同审批等待态、M5质管缺失→FAILED_MANUAL、M5不自动保存),用假回调能把一个 job 从头走到尾。 > > 节点数口径:主链 11 步每单都走;`OCR_EXTRACT`(仅线下单)、`SOURCE_ADD`(仅缺货源)是条件节点,不满足自动跳过。代码 `NODE_ORDER` 列全 13 个,`TRANSITIONS` 定转移,`NODE_EXECUTOR` 标执行方(STATE_CENTER/RPA/HUMAN)。 ## 五、你的任务清单(按顺序做,每步对着验收规范勾) ### 任务1:把骨架在真 MySQL 上跑通 - 建库、起服务,按 README 的 curl 把一个 job 用假回调走完主链(线上单会自动跳过 OCR_EXTRACT/SOURCE_ADD 条件节点)。 - 验收:`GET /api/jobs/{id}` 能看到完整节点轨迹和状态。 ### 任务2:对码接口 + Oracle 真连 - 拿到 Oracle 连接串/表名列名后,填 `config.py`,`pip install oracledb`。 - **骨架已写好**(`main.py`),你主要是接真数据、补前置: - `POST /api/match/reload-goods`:开工从 Oracle 全量拉货品主数据装进内存引擎(依赖 ORACLE_* 配置)。 - `POST /api/jobs/{id}/match/run`:对该 job 的 `order_item` 跑对码 → 落 `product_match`;MULTI/NONE 建 `user_task` 转 WAITING_USER,全命中推进下一节点。**前置:`order_item` 要先落库**(建单/ORDER_FETCH 后把明细写进来),否则 run 会 400。 - `POST /api/match/{matchId}/confirm`:人工确认一条,回写 product_match + 沉淀 `mapping_config` 累积别名(下次自动 ALIAS 命中),全部解决后自动推进。 - 已补齐的关键边界: - 对码重跑幂等:`product_match(job_id,order_item_id)` 当前态唯一,`match/run` upsert 结果并重建 OPEN 待办。 - 货源判定:`goods_id` 明确后,按历史 `supplier_name + goods_id` 判断是否已有货源;缺货源会写 `product_match.source_add_needed/job.needs_source_add` 并创建 `SOURCE_ADD` 聚合待办。 - alias 沉淀:同一 `config_key` 先失效旧 active,再插新 active;装载时按固定顺序取当前结果。 - 你要补的:① 订单明细落 `order_item` 的入口;② `GET /api/jobs/{id}/match/unmatched`(列未命中给前端);③ H5 待办提交入口(把 `SOURCE_ADD` 完成动作接到 `nodes/SOURCE_ADD/complete`)。 - **只写 mapping_config 累积别名,绝不回写 Oracle 主数据**(主数据只读)。 - 验收:喂真实订单,命中率有数字,未命中进待办,确认后能自动往下走。 ### 任务3:待办 + 人工提交 - `GET /api/tasks/my?roleCode=&status=open`、`POST /api/tasks/{id}/submit`。 - 动作:SELECT_CANDIDATE(对码选候选)/CONFIRM_AND_CONTINUE/RETRY_CURRENT_NODE/TRANSFER_MANUAL/TERMINATE_JOB。 - 幂等:task_id + submit_token 防重复提交。 ### 任务4:前端网页 - 步骤树状图(样式见实施规范第三部分)、待办页、整单查询页。 - 验收:业务打开能看到每单跑到哪、卡在哪、去处理按钮跳待办。 ### 任务5:证据 + 事件流 + 企业微信 - 证据落盘(job_artifact),事件流已有基础(job_event)。 - 企业微信推待办、H5 身份换 JWT。 ### 任务6:调度与重试 - 定时触发建单(跑前一天订单)、系统类错误自动重试1-2次、CONTRACT_APPROVE_WAIT 轮询(别死等)、超时升级。 ## 六、硬规则(红线,违反就是错的) 1. **对码表在 Oracle,只读,绝不复制成本地表、绝不回写 Oracle**。累积别名写自己的 mapping_config。 2. **M5 质管资料缺失(errorCode=M5_QC_MISSING)→ 不重试、不等质管,直接 FAILED_MANUAL 转人工**。已在 main.py 实现,别改成重试。 3. **M5 一期不自动保存/签订**(auto_save_enabled 默认0),做成开关,阶段二才放开。别默认自动。 4. **关键送审在返利中心(REBATE_SUBMIT),不是合同系统**。不送审 M5 带不出协议,是硬阻断。 5. **签约日期 = 订单日期**(不是今天),合同建单时按订单日期填。 6. **医药城同供应商同日合同合并成一个PDF**再上传(传第二份会覆盖),小药药不上传。 7. **返利细单备注必填订单号、特定补偿必填0**。 8. **对码未命中/返利重复编码 = 单条挂起,整批继续**;不是停整批。 9. **所有写接口必须鉴权**;RPA 回调校验 X-Agent-Token + 幂等键,禁止无认证暴露。 10. 节点失败不覆盖历史,attempt_no+1 新建 job_node 行。 ## 七、你不做什么(边界) - **不写点外部系统页面的代码**(登录/导Excel/建合同/M5录入)——那是艺赛旗,你只收它的 HTTP 回调。 - 不做招财平台(一期不纳入)。 - 不做加单/拆单全自动重做(先记录父订单号,转人工)。 - 不做返利重复编码全自动重建(规则未定,先转人工)。 - 遇到文档里标 `【待确认】` 的(订单状态过滤、OCR部署方式等),别自己拍板,先留 TODO 问项目负责人。 ## 八、回调契约(艺赛旗会这样调你,已实现) ``` POST /api/jobs/{jobId}/nodes/{nodeCode}/start header: X-Agent-Token POST /api/jobs/{jobId}/nodes/{nodeCode}/complete 带 businessRefs/summary POST /api/jobs/{jobId}/nodes/{nodeCode}/fail 带 errorCode/retryable/routeRole ``` 字段细节看 `设计文档` 第六部分和 `main.py` 里的 Pydantic 模型。 ## 九、验收总纲 每做完一个节点/接口,打开 `实施与验收规范` 第四部分,对着该节点的**代码验收**(你自检)和**业务验收**(交业务勾)两栏逐条过。全绿才算完。