AutoRpa/rpa_oms/README.md

147 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# rpa_oms
订单中心四个 HTTP 口,一个 FastAPI。HTTP 收件不同步跑作业。作业在 `rpa_selection` / `rpa_cart` / `rpa_contract` / `rpa_rebate`。
口径:`docs/RPA订单中心接口开发口径_20260930.md`。DDL:`docs/ddl/rpa_oms_staging_tables.sql`。
| 口 | 方向 | 底表 | 代码 |
| --- | --- | --- | --- |
| 1 | 订单中心 → 本方 | `rpa_sales_goods_mapping_data` | `POST /api/oms/v1/sales-goods` |
| 2 | 本方 → 订单中心 | `rpa_cart_settlement_goods_data` | `app/outbound/cart_settlement.py` 取 `push_status=0` 组装报文。路径仍空,不发 HTTP |
| 3 | 订单中心 → 本方 | `rpa_purchase_contract_data` | `POST /api/oms/v1/purchase-contracts`,按对方 `fid` 幂等 |
| 4 | 本方 → 订单中心 | `rpa_contract_agreement_result` | `app/outbound/contract_agreement.py` 取 `push_status=0` 组装报文。路径仍空,不发 HTTP |
入站(1、3):
- 鉴权:header `X-Oms-Token`,环境变量 `OMS_INBOUND_TOKEN`
- 信封:`{"data":[...]}`,一批最多 100 条
- 接口 1 落表 `deal_flag=0`,请求里不跑选品
- 接口 3 落表 `process_status=0`,请求里不录合同
接口 2 出站组装:`load_cart_settlement_envelope(repo)`,同一 `omsId` 不拆批。上限默认 500,环境变量 `OMS_OUTBOUND_BATCH_LIMIT` 可改。SQL 侧按组截断。不改 `push_status`,不发 HTTP。连接从 `rpa_oracle` 池借。
```python
from rpa_oracle.pool import create_pool
from app.outbound.cart_settlement import load_cart_settlement_envelope
from app.outbound.oracle_repo import OracleCartSettlementRepo
pool = create_pool(role="oms")
with pool.acquire() as conn:
envelope = load_cart_settlement_envelope(OracleCartSettlementRepo(conn))
```
接口 4 出站组装:`load_contract_agreement_envelope(repo)`,同一非空 `contractNo` 不拆批。上限同样默认 500。不改 `push_status`,不发 HTTP。
```python
from rpa_oracle.pool import create_pool
from app.outbound.contract_agreement import load_contract_agreement_envelope
from app.outbound.oracle_repo import OracleContractAgreementRepo
pool = create_pool(role="oms")
with pool.acquire() as conn:
envelope = load_contract_agreement_envelope(OracleContractAgreementRepo(conn))
```
运行时只落 / 读 Oracle。入站单测用假连接录 SQL,不连库。
## 真库
Oracle 11.2 需要 Instant Client(thick)。密码只放本机 `rpa_oms/.env`(已 gitignore),不要写进仓库、README、命令行历史。
```bash
cd rpa_oms
uv sync --python 3.12
export OMS_INBOUND_TOKEN=dev-oms-token
export RPA_ORACLE_HOST=192.168.12.244
export RPA_ORACLE_PORT=1521
export RPA_ORACLE_SERVICE=rpa
export RPA_ORACLE_USER=rpainit
export RPA_ORACLE_PASSWORD=...
export RPA_ORACLE_THICK=1
# 如需指定 Instant Client 目录:
# export RPA_ORACLE_CLIENT_LIB=/path/to/instantclient
uv run uvicorn app.main:app --reload --port 8001
```
缺 `RPA_ORACLE_HOST` / 用户 / 密码时,收件接口回 503。
## Windows 真库
本机 Mac 打不到 `192.168.12.244`,连库测试在 Windows 上做。Python 3.12 + Instant Client(位数一致),密码不要写进仓库。
PowerShell:
```powershell
cd rpa_oms
uv sync --python 3.12
Copy-Item -LiteralPath .env.example -Destination .env
# 只编辑本机 .env 的 RPA_ORACLE_PASSWORD,不要 git add .env
.\start.ps1
```
先 `GET http://127.0.0.1:8001/health`,再把 `examples/sales_goods_batch.json` POST 两次:
1. 第一次:两条 `ACCEPTED`,表里各一行 `deal_flag=0`
2. 第二次:两条 `DUPLICATE`,表行数不变
```powershell
curl.exe -sS http://127.0.0.1:8001/api/oms/v1/sales-goods `
-H "Content-Type: application/json" `
-H "X-Oms-Token: dev-oms-token" `
--data-binary "@examples/sales_goods_batch.json"
```
接口 3 同样 POST 两次 `examples/purchase_contract_batch.json`:第一次两条 `ACCEPTED`(`process_status=0`),第二次两条 `DUPLICATE`。
```powershell
curl.exe -sS http://127.0.0.1:8001/api/oms/v1/purchase-contracts `
-H "Content-Type: application/json" `
-H "X-Oms-Token: dev-oms-token" `
--data-binary "@examples/purchase_contract_batch.json"
```
## 运维
### 怎么跑
Windows 真库见上一节:本机 `.env` 配 `OMS_INBOUND_TOKEN` 和 `RPA_ORACLE_*`,`.\start.ps1` 起 8001。缺 HOST / 用户 / 密码时收件回 503。审计表 DDL 在 `docs/ddl/rpa_oms_staging_tables.sql` 末尾 `rpa_oms_inbound_audit`,真库要先建这张表。
### 看表 1/3 哪列
- 接口 1:`rpa_sales_goods_mapping_data`。看 `oms_id`、`deal_flag`(0 待选品)、`bar_code`、`goods_mdm_code`。同一 `oms_id` 不应有第二行。
- 接口 3:`rpa_purchase_contract_data`。看 `fid`、`process_status`(0 待合同班)、`contract_entry_status`、`contract_no`。按对方 `fid` 幂等。
- 审计:`rpa_oms_inbound_audit`。看 `api_no`(1 或 3)、`http_code`、`error_text`、`token_masked`。
- 接口 2:`rpa_cart_settlement_goods_data`。看 `oms_id`、`push_status`(0 未推,1 成功,2 失败,3 推送中)、`push_result`。
- 接口 4:`rpa_contract_agreement_result`。看 `contract_no`、`push_status`、`push_result`。
### 出站批次和重推
- 一批上限:环境变量 `OMS_OUTBOUND_BATCH_LIMIT`,默认 500。口 2 同一 `omsId` 不拆批;口 4 同一非空 `contractNo` 不拆批。
- 未推:`SELECT * FROM rpa_cart_settlement_goods_data WHERE push_status = 0`(口 4 换表名)。
- 已推成功:`push_status = 1`。
- 失败重推:把 `push_status` 改回 0(例如 `UPDATE ... SET push_status = 0 WHERE push_status = 2`)。`mark_pushed` 已备,路径仍空,不要把未 POST 的行标成已推。
- 缺 HOST / 用户 / 密码时 `create_pool` 抛「数据库不可用」,文案不含环境变量名。
### 崩溃与审计失败
入站请求里不跑选品、不录合同,没有班次那种「停在 3」的戳。库故障整包 503,一条业务行都不落。审计 INSERT 失败只记本机日志,不把已经 200 的收件打成 500。
### 503 对外 vs 审计原文
对外 `msg` 固定「数据库不可用」,HTTP body 不含 DSN、Instant Client 路径、`ORA-`、表名。ORA 原文在审计表 `error_text`。401 对外「身份认证失败」,token 只存 `***`。
### 点名命令
```bash
cd rpa_oms
uv run pytest tests/test_sales_goods_receive.py -q
uv run pytest tests/test_oracle_repo.py -q
uv run pytest tests/test_purchase_contract_receive.py -q
uv run pytest tests/test_oracle_contract_repo.py -q
uv run pytest tests/test_cart_settlement_outbound.py::test_assembles_unpushed_rows_as_document_envelope -q
uv run pytest tests/test_oracle_cart_repo.py::test_list_unpushed_keeps_whole_oms_group_when_limit_is_3 -q
uv run pytest tests/test_contract_agreement_outbound.py::test_assembles_unpushed_rows_as_document_envelope -q
```
真库:同一 JSON POST 两次 → 先 ACCEPTED 后 DUPLICATE。再人为断库,接口回固定「数据库不可用」,审计表有原文。