AutoRpa/AGENTS.md

15 KiB
Raw Blame History

AutoRpa

洁达 RPA。当前主线是订单中心入站(rpa_oms)、选品班次(rpa_selection/)、加购班次(rpa_cart/)、合同班次(rpa_contract/)和返利班次(rpa_rebate/):收件落 Oracle,请求里不跑选品、不录合同;选品另起进程捞 deal_flag=0;加购另起进程领表 2 成功行;合同另起进程领表 3;返利另起进程领表 4 起草行 / 表 3 只录协议行。根上不再有 选品流程/、state_center/、rpa_yisaiqi/。

智力用在定落点、想清楚对错;速度和 token 靠下面这张地图定点打开,禁止用扫仓代替思考。改对应了,反工和消耗都会少。

怎么干活

  1. 先定落点(不开文件):哪个函数、成功长什么样(哪条 ACCEPT / 哪个点名用例)、这次不碰什么。方向说不清就先问,不要靠翻目录找感觉。
  2. 只在落点上想透:规则、边界、会不会拿错号/写错状态。打开文件是为了验证落点,不是再想要不要改别处。
  3. 薄验收就停:控制台 ACCEPT SUMMARY 或一条点名用例。过了收工。

问「法子 / 怎么优化」先答方案;用户说「改 / 重构 / 收口」再动代码。一件事一个会话,换任务 /new。

项目地图

按问题打开一行,不要 list_dir 根目录。

问题 打开 验收
接口1 收件契约 rpa_oms/app/inbound/sales_goods.py、envelope.py rpa_oms/tests/test_sales_goods_receive.py::点名
接口1 Oracle 落表 rpa_oms/app/inbound/oracle_repo.py rpa_oms/tests/test_oracle_repo.py::点名
接口1 入口 / 鉴权 rpa_oms/app/main.py、auth.py 同上;真库见 rpa_oms/README.md Windows 段
接口2 取数组装 rpa_oms/app/outbound/cart_settlement.py rpa_oms/tests/test_cart_settlement_outbound.py::test_assembles_unpushed_rows_as_document_envelope
接口4 取数组装 rpa_oms/app/outbound/contract_agreement.py rpa_oms/tests/test_contract_agreement_outbound.py::test_assembles_unpushed_rows_as_document_envelope
接口3 收件契约 rpa_oms/app/inbound/purchase_contract.py rpa_oms/tests/test_purchase_contract_receive.py::点名
接口3 Oracle 落表 rpa_oms/app/inbound/oracle_contract_repo.py rpa_oms/tests/test_oracle_contract_repo.py::点名
选品规则 / 拆量 rpa_selection/rules.py、pipeline.py rpa_selection/tests/test_pipeline.py::test_split_across_malls_is_success
选品班次落表 rpa_selection/job.py、persist.py、repo.py rpa_selection/tests/test_job.py::test_job_searches_barcode_not_approval_no
合同班合单落表 rpa_contract/job.py、group.py、persist.py、repo.py rpa_contract/tests/test_job.py::test_job_merges_same_supplier_and_writes_table4
合同页面步骤 rpa_contract/contract_flow_steps.py 里对应函数 ACCEPT SUMMARY 或 rpa_contract/screenshots/ 下 ACCEPT.txt
合同入参 / 客商草稿 rpa_contract/contract_draft.py rpa_contract 点名用例
节点入口 rpa_contract/contract_create_node.py、main.py 读到正式合同号
浏览器适配 rpa_contract/apa_browser_adapter.py rpa_contract/tests/test_apa_browser_adapter.py::点名
文字验收 / 截图策略 rpa_contract/accept.py 只读 ACCEPT.txt,禁止读 png
加购班次 rpa_cart/cart_job.py、cart_repo.py、cart_match.py rpa_cart/tests/test_cart_job.py::test_job_adds_split_rows_without_insert
支付回传 rpa_cart/job.py、settle.py 1 号药城支付按 Excel 落表,不对加购行
返利班查号落表 rpa_rebate/job.py、persist.py、repo.py rpa_rebate/tests/test_job.py::test_job_finds_contract_and_writes_agreement
返利班查号页面 rpa_rebate/rebate_flow_steps.py、rebate_finder.py ACCEPT SUMMARY REBATE_FIND 或 rpa_rebate/tests/test_finder.py::test_find_flow_writes_accept_for_missing_number
四个口地图 rpa_oms/README.md、根 README.md —
节点业务规则(点名一节) docs/RPA订单中心接口开发口径_20260930.md 禁止通读 docs/

禁止打开:node_modules/、chrome-profile/、任何 png。Chrome 用户目录只在仓库外 D:\work\rpa-chrome-profile。Oracle 密码放本机 rpa_oms/.env(选品空缺时复用);商城账号放 rpa_selection/.env;返利中心账号放 rpa_rebate/.env。都已 gitignore,不要写进仓库、README、示例 JSON,不要 git add / commit / push。

接口1 落点(订单中心)

订单中心四接口,本期开放接口 1、3 收件。鉴权 header X-Oms-Token(OMS_INBOUND_TOKEN)。接口 1:POST /api/oms/v1/sales-goods,落表 rpa_sales_goods_mapping_data,deal_flag=0,请求里不跑选品。接口 3:POST /api/oms/v1/purchase-contracts,落表 rpa_purchase_contract_data,process_status=0,按对方 fid 幂等,请求里不录合同。接口 2 只从表 2 取 push_status=0 组装报文,路径仍空,不发 HTTP。

运行时只落 Oracle。单测用内存替身,不连库。服务端口 8001。

步 函数 要点
信封 parse_envelope 缺 data / 空数组 / 超过 100 条:整包 422,一条都不落
逐条校验 receive_sales_goods 入参 camelCase,落表 snake_case;长度跟 VARCHAR2
鉴权 token_ok 未配 token 一律失败
落表 OracleSalesGoodsRepo.insert fid 由序列触发器生成,INSERT 不绑这一列
幂等 同 omsId 已存在 → DUPLICATE,不更新、不重跑
同批冲突 同一 POST 里 omsId 再现 后一条 CONFLICT,只落第一条
字段不过 _parse_row REJECTED,不入库
混批 post_sales_goods 逐条有成功/重复/拒绝时 HTTP 仍 200,看 results[].resultCode

omsId / saleQty / planPurchaseQty / 接口 3 的 fid 必须是 JSON 整数,不把 "10" 当 10。Windows 连真库测;Instant Client 位数与 Python 一致。

接口 2:load_cart_settlement_envelope 捞 push_status=0,同一 omsId 整组进一批,上限 500;金额四位小数字符串。不改 push_status,不 POST 订单中心。

接口 3:receive_purchase_contracts 按 fid 幂等;同批 fid 再现 → CONFLICT;contractEntryStatus=0 必须带 contractNo;结束日不得早于开始日。INSERT 绑 fid。

验收(内存、不连库):cd rpa_oms → uv run pytest tests/test_sales_goods_receive.py::点名 -q。真库:GET /health 后把 examples/sales_goods_batch.json POST 两次(第一次两条 ACCEPTED,第二次两条 DUPLICATE)。接口 3 点名 tests/test_purchase_contract_receive.py;真库 POST examples/purchase_contract_batch.json 两次。接口 2 点名 tests/test_cart_settlement_outbound.py::test_assembles_unpushed_rows_as_document_envelope。

修接口1不要顺手改 rpa_selection/、rpa_cart/、rpa_contract/、rpa_rebate/。接口 2、4 只组装不推送。

选品落点

班次作业在 rpa_selection/,不在接口 1 请求里跑。从表 1 领 deal_flag=0,按条形码搜 1 号药城 / 药帮忙,两平台合并后按四级仓序贪心拆量,写入表 2。凑齐才落成功行;凑不齐不落部分成功。

口径:docs/superpowers/specs/2026-10-02-selection-split-allocation-design.md。

步 函数 要点
领取 claim_pending deal_flag 0→3;中途崩溃停在 3,改回 0 再跑
规则 allocate / run_selection 自营仓全称匹配、毛利 ≥ 4%、效期 ≥ 12 月;同仓只留低价;按仓序拆量
落表 build_result + save_result 成功每仓一行 status=1,合计=计划量;push_status=0
库存不足 KIND_BUSINESS_FAIL 两边都搜到但合计不够:deal_flag=2,该 omsId 不重跑
对端故障 KIND_SYSTEM_FAIL 一边故障且剩下的凑不齐:可把 deal_flag 改回 0;禁止写成库存不足

湖南壹号、甘肃壹号云不在自营集合。不加购,不推接口 2。

验收:cd rpa_selection → uv run pytest tests/test_pipeline.py::test_split_across_malls_is_success -q(杭州 3 + 广东 7 = 计划 10)。

加购落点

班次作业在 rpa_cart/,不在选品请求里跑。领表 2 operate_type=1 AND status=1 AND push_status=0 AND update_user_name=系统管理员。登录 1 号药城 / 药帮忙,按条形码再搜,对上 supplier_name,按行加车。

步 函数 要点
领取 claim_pending 盖 加购中;崩溃停在这戳,改回 系统管理员 再跑
对仓 match_offer 条形码结果对商家全称;同仓留低价
加车 run_cart_batch + 平台 add_*_cart 改数量加入购物车。无 sku_id,必须再搜
成功 mark_success 不插行,update_user_name=加购班,status 仍 1
失败 mark_fail 该行 status=2 + 原因。登录挂写系统故障;库存/中包装/对不上仓写业务原因

同一 omsId 拆两仓要加齐;一行失败只改那一行。不推接口 2,不清空购物车,不碰合同、表 1。接口 2 仍捞全部 push_status=0,加购班跑完之前不要组装。

验收:cd rpa_cart → uv run pytest tests/test_cart_job.py::test_job_adds_split_rows_without_insert -q(杭州 3 + 广东 7,不插新行)。

CONTRACT_CREATE 落点

班次作业在 rpa_contract/,不在接口 3 请求里跑。领表 3 process_status=0(跳过协议重录行),按 supplierId 合单,调页面流,写表 4。run_contract_create_flow 串页面;修一步只打开对应函数。

步 函数 要点
S02 打开 open_contract_system http://contract-test.gzmpc.com:8080/
S03 登录 login_contract_system 10007228 / 1
S04–S05 起草 enter_contract_create、select_contract_template 直达 FORM_PAGE_URL,不要点 SPA 菜单
S06 签约方 fill_contract_signatory_info 客商 DW0100046361 / 重庆亿昊药业有限公司
尽调 check_customer_diligence 正文含「未尽调」则失败,不提交
S07 基础 fill_contract_basic_info 标题 _expected_title
S08 金额日期 fill_contract_amount_and_dates 签订日/开始日用接口 3 三日期,缺则回退 order_date
S09 货品 fill_contract_goods_lines 弹窗按操作码搜
S10 付款 fill_contract_payment_info
S11 PDF upload_contract_document_if_needed 仅 YYC 传合并 PDF
S12 提交 submit_contract_for_approval 成功后不要等详情页
S13 合同号 read_contract_number 回「我的合同」,fdId > 标题+客户编码;禁止盲取最新一条

成功路径默认不截图(RPA_SCREENSHOT=always 才全截)。页面等待用 wait_for_text / wait_for_element,不要固定长睡。

返利班落点

班次作业在 rpa_rebate/,不在接口 3 请求里跑。领表 4 action_code=1 AND contract_status=1(合同班起草、尚未回成功),以及表 3 contract_entry_status=0 且已有 contractNo 的只录协议行。按合同号查返利中心;搜到再回 contractStatus=2、录协议写 actionCode=2。搜不到不重录合同,留给下一班。查号走页面;录协议仍用替身。接口 4 组包在 oms,path 空,不发 HTTP。

步 函数 要点
领取 claim_pending 表 4 盖 查号中;表 3 process_status 0→3。崩溃停戳,改回 合同班 / 0 再跑
查号 RebateFinder / search_contract 打开 REBATE_URL → 登录 → 采购协议 → 按合同号搜;表里出现该号才 True,输入框回显不算
落表 build_found + save_group 起草行 contract_status=2;每 oms_id 插 action_code=2、agreement_status=1;push_status=0
搜不到 build_not_found 戳改回 合同班;表 3 改回 0;不插协议行

验收:cd rpa_rebate → uv run pytest tests/test_job.py::test_job_finds_contract_and_writes_agreement -q。页面:uv run python run_find.py,只读 ACCEPT SUMMARY REBATE_FIND 或 rpa_rebate/screenshots/REBATE_FIND/ACCEPT.txt。接口 4:cd rpa_oms → uv run pytest tests/test_contract_agreement_outbound.py::test_assembles_unpushed_rows_as_document_envelope -q。

录协议、映射表默认值、送审下一刀。不推接口 4,不改 push_status,不碰选品 / 加购 / 合同页面。

返利中心及之后

查号页面已接 REBATE_FIND。录协议班次骨架仍是替身。三把钥匙:contractSystemNo → rebateOrderNo → receiptNoticeNo。开页面时按合同同款:一个节点一份 *_flow_steps.py,验收只看 ACCEPT / 点名用例。

节点 谁做 要回传 页面要做什么
REBATE_FIND RPA 搜到 / 搜不到 已拆:登录 → 采购协议 → 按合同号搜
REBATE_HEADER RPA rebateOrderNo 尚未拆:填必填 → 保存拿总单号
REBATE_IMPORT RPA 成功/失败行 下模板 → 按字段填 Excel → 上传 → 读导入结果
REBATE_SUBMIT RPA submitted 点提交送审
M5_CREATE_ORDER RPA 桌面端 m5OrderNo 录单后停、不保存。M5_QC_MISSING 必须识别准(直接转人工、不重试)
M5_MANUAL_CONFIRM 采购 — 人在 M5 里保存签订
M5_RECEIPT_NOTICE 采购 receiptNoticeNo 人填收货通知单号,全链终点钥匙

不要连续轮询审批;返利段开始前大约 30 分钟查一次。

验收

  • 接口1:点名 rpa_oms/tests/test_sales_goods_receive.py 或 test_oracle_repo.py;禁止为「显得全面」跑整包再去连真库。
  • 接口2:点名 rpa_oms/tests/test_cart_settlement_outbound.py::test_assembles_unpushed_rows_as_document_envelope。
  • 接口3:点名 rpa_oms/tests/test_purchase_contract_receive.py 或 test_oracle_contract_repo.py。
  • 选品:点名 rpa_selection/tests/test_pipeline.py::test_split_across_malls_is_success 或 test_rules.py::test_margin_exactly_4_percent_passes。
  • 加购:点名 rpa_cart/tests/test_cart_job.py::test_job_adds_split_rows_without_insert 或 test_job_marks_out_of_stock。
  • 合同班:点名 rpa_contract/tests/test_job.py::test_job_merges_same_supplier_and_writes_table4 或 test_job_marks_diligence_fail。
  • 返利班:点名 rpa_rebate/tests/test_job.py::test_job_finds_contract_and_writes_agreement 或 test_job_leaves_not_found_for_next_shift。
  • 返利查号页:只读控制台 ACCEPT SUMMARY REBATE_FIND 或 rpa_rebate/screenshots/REBATE_FIND/ACCEPT.txt。
  • 接口4:点名 rpa_oms/tests/test_contract_agreement_outbound.py::test_assembles_unpushed_rows_as_document_envelope。
  • 合同页:只读控制台 ACCEPT 或 rpa_contract/screenshots/ 下 ACCEPT.txt。
  • 单测只跑点名用例。禁止跑整份带页面等待的套件当回归。

不要

  • 不要扫根目录,不要通读 docs/。需要背景就点名打开一节。
  • 不要把 Oracle 密码写进仓库、README、示例 JSON。
  • 不要在接口1 请求路径里跑选品。
  • 不要在接口3 请求路径里录合同。
  • 不要为「显得全面」多开文件、重跑、看图。落点外的改动会制造反工。