Преглед на файлове

docs(integration): 增加第三方对接模拟器方案与初步任务书

Co-authored-by: Cursor <cursoragent@cursor.com>
YY968XX преди 5 часа
родител
ревизия
22425fb5e5

+ 905 - 0
doc/plan/系统集成/Ai-DOP第三方对接模拟器初步执行任务书.md

@@ -0,0 +1,905 @@
+# Ai-DOP 第三方对接模拟器初步执行任务书
+
+> 派生自 [`Ai-DOP第三方对接模拟器建设方案.md`](./Ai-DOP第三方对接模拟器建设方案.md)。  
+> 本任务书是第一版实施拆解,供后续开发者或大模型执行;正式编码前仍须按仓库协作规则列出准确改动清单并确认。  
+> 当前基线:HEAD `5f6600ecf`,server `1.0.596`,Web `2.4.415`。  
+> 编制日期:2026-09-30。
+
+---
+
+## 0. 任务目标
+
+建设独立本地可视化第三方系统模拟器。
+
+第一阶段必须能真实验证:
+
+1. 数据库同步 `DB_SYNC`;
+2. Ai-DOP 主动接口拉取 `API_PULL`;
+3. 第三方主动接口推送 `API_INBOUND`。
+
+第二阶段再建设自动化场景、故障注入、全链路对账、SQL Server、CI 和容器化能力。
+
+第一阶段不得只把现有 `push_demo.py` 包一层页面后宣布完成,也不得只证明 Mock 端自己能响应。三种方式都必须经过 Ai-DOP 现有真实执行链。
+
+---
+
+## 1. 开工门禁
+
+### G1:范围确认
+
+已确认:
+
+- 模拟器独立运行,不进入 Ai-DOP 菜单;
+- 第一阶段包含三种入站方式;
+- 第一阶段 DB_SYNC 只模拟 MySQL;
+- API_INBOUND 覆盖现有 26 个代码契约和 7 类协议操作;
+- 业务数据范围以业务页和技术页为准。
+
+### G2:环境确认
+
+执行前确认:
+
+- Python 3.11+;
+- 可安装 FastAPI、Uvicorn、PyMySQL;
+- 有独立 MySQL 测试 schema 的建表与读写权限;
+- Ai-DOP 开发或 UAT 地址可访问;
+- 有测试租户;
+- DB_SYNC/API_PULL 测试来源不会覆盖现有生产权威来源;
+- API_INBOUND 测试 AccessKey 绑定测试租户;
+- Secret 由环境变量或启动时输入提供。
+
+### G3:三层基线
+
+执行前保存:
+
+#### 代码层
+
+```text
+rg "class MdpDbPullExecutor|class MdpApiPullExecutor|class MdpInboundController" server/Plugins/Admin.NET.Plugin.AiDOP
+rg "\\[\"[A-Z0-9_]+\"\\]\\s*=" server/Plugins/Admin.NET.Plugin.AiDOP/DataPlatform/Inbound/MdpInboundFieldMapper.cs
+```
+
+#### 配置层
+
+```sql
+SELECT source_code, source_type, system_code, status
+FROM mdp_source
+ORDER BY source_code;
+
+SELECT entity_code, source_id, source_table_name, source_api_path,
+       target_table_name, inbound_enabled, incr_column
+FROM mdp_entity
+ORDER BY entity_code, source_id;
+```
+
+授权查询须在安全客户端执行,不输出 AccessSecret:
+
+```sql
+SELECT access_key, entity_code, tenant_id, source_code, status
+FROM mdp_inbound_grant
+ORDER BY access_key, entity_code;
+```
+
+#### 数据层
+
+```sql
+SELECT source_code, status, COUNT(*) AS cnt, MAX(end_time) AS latest_end
+FROM mdp_sync_log
+GROUP BY source_code, status;
+
+SELECT status, COUNT(*) AS cnt, MAX(created_at) AS latest_request
+FROM mdp_inbound_request
+GROUP BY status;
+```
+
+### G4:停止门禁
+
+出现以下任一情况立即停止,不得用临时写库绕过:
+
+- 目标为生产环境;
+- 无法确认测试租户;
+- 测试来源会替换当前标准对象权威来源;
+- 需要把真实 Secret 写进仓库;
+- 需要直接写 Ai-DOP 贴源/标准/KPI 表才能“跑通”;
+- 现有 Ai-DOP 配置缺失且用户未授权补配置;
+- 样例业务键与真实业务键存在碰撞风险。
+
+---
+
+## 2. 两阶段总览
+
+| 阶段 | 目标 | 工作包 |
+|---|---|---|
+| 第一阶段 | 三种方式完成基础联调 | P1-A~P1-H |
+| 第二阶段 | 集成回归平台 | P2-A~P2-F |
+
+第一阶段完成后先验收,再决定是否进入第二阶段。
+
+---
+
+## 3. 第一阶段拟新增和修改文件
+
+以下为初步清单,编码前须重新核对实际调用面。
+
+### 3.1 新增目录
+
+```text
+tools/integration-simulator/
+├─ app.py
+├─ requirements.txt
+├─ README.md
+├─ config.example.json
+├─ clients/
+│  ├─ inbound_client.py
+│  └─ aidop_probe.py
+├─ providers/
+│  ├─ mock_api.py
+│  └─ mock_db.py
+├─ catalog/
+│  ├─ entities.json
+│  ├─ scenarios.json
+│  └─ sample_adapters.py
+├─ static/
+│  ├─ index.html
+│  ├─ app.js
+│  └─ app.css
+└─ tests/
+   ├─ test_inbound_signature.py
+   ├─ test_sample_adapters.py
+   ├─ test_mock_api.py
+   ├─ test_mock_db.py
+   └─ test_redaction.py
+```
+
+### 3.2 复用但不迁移
+
+第一阶段继续复用:
+
+```text
+doc/db/mdp/mock_api/endpoints.json
+doc/db/mdp/mock_api/samples/*.json
+tools/mock/inbound/push_demo.py
+```
+
+不得直接删除或搬迁这些文件。新模拟器通过适配器读取既有样例,避免破坏现有 contract tests。
+
+### 3.3 可能修改
+
+仅在确认调用面后修改:
+
+```text
+doc/db/mdp/mock_api/mock_server.py
+doc/db/mdp/mock_api/requirements.txt
+doc/db/mdp/mock_api/seed_mock_db.py
+doc/plan/系统集成/README.md
+```
+
+原则:
+
+- `mock_server.py` 只做兼容复用,不改变现有端点默认响应;
+- `seed_mock_db.py` 不再只登记来源,需能调用新模拟库装载器或明确弃用;
+- 不修改 `Web/` 和 `server/` 主代码,除非实施中实证发现阻断缺陷并另行确认。
+
+---
+
+## 4. P1-A:公共模型与目录
+
+### 目标
+
+建立三种通道共用的对象目录、样例目录和状态模型。
+
+### 实施
+
+`catalog/entities.json` 每个对象至少包含:
+
+```json
+{
+  "objectCode": "ITEM",
+  "businessName": "物料基础信息",
+  "sample": "doc/db/mdp/mock_api/samples/item.json",
+  "dbSync": {
+    "supported": true,
+    "table": "sim_item",
+    "businessKey": ["Domain", "ItemNum"],
+    "incrementColumn": "sourceUpdatedAt"
+  },
+  "apiPull": {
+    "supported": true,
+    "path": "/api/items",
+    "responsePath": "data.list",
+    "dedupKeyPath": "bizKey"
+  },
+  "apiInbound": {
+    "supported": true,
+    "entityCode": "MDM_ITEM",
+    "contractVersion": "v1"
+  }
+}
+```
+
+状态枚举至少包括:
+
+```text
+CODE_UNSUPPORTED
+CONFIG_NOT_REGISTERED
+CONFIG_NOT_ENABLED
+GRANT_MISSING
+SOURCE_UNREACHABLE
+READY
+DATA_NOT_RUN
+RUNNING
+RUN_SUCCEEDED
+RUN_FAILED
+```
+
+### 范围
+
+对象目录必须覆盖业务页确认表全部数据包。API_INBOUND 侧登记当前 26 个代码契约;没有推送契约的对象写 `supported=false` 和明确原因。
+
+### 验收
+
+- 目录加载成功;
+- 每个业务数据包都有三通道状态;
+- 不把“配置未开”写成“代码不支持”;
+- 所有样例路径存在;
+- 样例不含真实客户敏感数据。
+
+---
+
+## 5. P1-B:安全配置与本地控制服务
+
+### 目标
+
+实现本地 FastAPI 控制服务与静态页面。
+
+### 配置
+
+`config.example.json` 只能放非敏感默认项:
+
+```json
+{
+  "aidopBaseUrl": "http://127.0.0.1:5005",
+  "mockApiPort": 8018,
+  "mysqlDatabase": "aidop_integration_sim",
+  "allowedTargetHosts": ["127.0.0.1", "localhost"]
+}
+```
+
+敏感信息仅从环境变量读取,例如:
+
+```text
+AIDOP_SIM_MYSQL_PASSWORD
+AIDOP_SIM_INBOUND_SECRET
+AIDOP_SIM_INBOUND_ACCESS_KEY
+AIDOP_SIM_ADMIN_TOKEN
+```
+
+不得提供含真实值的 `.env`。
+
+### 页面
+
+至少包含:
+
+- 环境状态;
+- 对象选择;
+- 通道选择;
+- 样例编辑;
+- 执行按钮;
+- 请求/响应预览;
+- 三层结果;
+- 最近运行记录。
+
+### 安全
+
+- 浏览器 API 不返回 Secret;
+- 服务端日志对认证头和连接串脱敏;
+- 默认拒绝非白名单目标 host;
+- 报告中只保留 AccessKey 后四位;
+- 页面不使用 localStorage 保存认证信息。
+
+### 验收
+
+- 本地页面可打开;
+- 缺环境变量时给出明确提示;
+- 日志无密码、Secret、JWT;
+- 非白名单目标被阻断。
+
+---
+
+## 6. P1-C:DB_SYNC 模拟
+
+### 目标
+
+模拟第三方 MySQL 数据库,供 Ai-DOP 现有 DB_SYNC 真实读取。
+
+### 实施
+
+`mock_db.py` 提供:
+
+1. 创建模拟 schema;
+2. 按对象建源表;
+3. 重置单表;
+4. 装载 canonical 样例;
+5. 追加数据;
+6. 更新已有数据并推进增量列;
+7. 查询样例行数与最大增量值;
+8. 生成 Ai-DOP 配置清单。
+
+不得:
+
+- 连接 Ai-DOP 库后直接写贴源;
+- 使用 Ai-DOP 主库账号作为模拟库账号;
+- 自动覆盖现有 `mdp_source` 或标准对象来源登记。
+
+### 最小对象
+
+必须覆盖至少:
+
+- 物料;
+- 销售订单头与行;
+- 生产工单;
+- 采购订单与收货;
+- 出入库流水;
+- 交货计划;
+- 工序计划;
+- 成品相关数据。
+
+最终以对象目录中 `dbSync.supported=true` 的全部对象为完成范围。
+
+### 用例
+
+1. 首次全量;
+2. 重复同步;
+3. 新增增量;
+4. 更新增量;
+5. 错误业务键;
+6. 增量列不推进;
+7. 源库不可达;
+8. 认证失败。
+
+### 验收
+
+- Ai-DOP 通过 `MdpDbPullExecutor` 拉取;
+- `mdp_sync_log` 有结果;
+- `last_cursor` 符合预期;
+- 贴源数据来源为测试 source_code;
+- 重复执行不产生重复业务行。
+
+---
+
+## 7. P1-D:API_PULL 模拟
+
+### 目标
+
+模拟第三方查询 API,供 Ai-DOP 现有 API_PULL 主动调用。
+
+### 实施
+
+`mock_api.py` 复用既有 endpoints 与 samples,增加统一控制能力:
+
+- 启停;
+- 切换样例;
+- cursor 过滤;
+- 鉴权模式;
+- 延迟;
+- HTTP 错误;
+- 响应路径;
+- 每次调用的脱敏审计。
+
+第一阶段不实现超出现有执行器能力的复杂分页协议。
+
+### 鉴权用例
+
+- NONE;
+- Bearer/Token;
+- Basic;
+- APIKey。
+
+OAuth2 只验证配置路径或放第二阶段,不在第一阶段搭完整授权服务器。
+
+### 响应用例
+
+- `data.list` 正常;
+- 空数组;
+- 错误 response path;
+- 重复 bizKey;
+- cursor 前后数据;
+- 401、403、429、500;
+- 超时。
+
+### 验收
+
+- Ai-DOP 通过 `MdpApiPullExecutor` 请求 Mock;
+- 认证头正确;
+- response path 与 dedup key 生效;
+- cursor 场景符合当前执行器行为;
+- 贴源 raw_data 与样例一致;
+- 错误响应不会被写成成功。
+
+---
+
+## 8. P1-E:API_INBOUND 模拟
+
+### 目标
+
+把现有 `push_demo.py` 的协议能力提取为可复用客户端,并由页面驱动。
+
+### 实施
+
+`inbound_client.py` 必须与后端一致:
+
+```text
+message =
+METHOD&path&accessKey&timestamp&nonce&bodySha256&idempotencyKey
+signature = Base64(HMAC-SHA256(secret, message))
+```
+
+支持 Headers:
+
+```text
+X-Access-Key
+X-Timestamp
+X-Nonce
+X-Signature
+X-Content-SHA256
+Idempotency-Key
+X-Mdp-Contract-Version
+```
+
+### 七类操作
+
+1. schema;
+2. 普通 POST;
+3. receipt;
+4. bulk;
+5. open snapshot;
+6. commit snapshot;
+7. digest。
+
+### 实体范围
+
+识别方案中列出的 26 个 entityCode。每个实体:
+
+- 可发起 schema;
+- 可编辑最小样例;
+- schema 成功时校验必填字段;
+- 403 时显示配置未开;
+- 普通 POST 只对 READY 实体执行。
+
+### 必测用例
+
+- 正常推数;
+- 缺幂等键;
+- body 摘要不一致;
+- 过期 timestamp;
+- nonce replay;
+- 同幂等键同 body;
+- 同幂等键不同 body;
+- 部分行拒绝;
+- stale 数据;
+- v2 库存流水;
+- bulk;
+- snapshot open/commit;
+- digest;
+- receipt。
+
+### 验收
+
+- 签名固定向量与 C# 端一致;
+- Secret 不出现在浏览器与日志;
+- 26 个实体都生成预检结果;
+- READY 实体普通推数成功;
+- 七类操作完成基础测试;
+- `mdp_inbound_request` 与回执一致。
+
+---
+
+## 9. P1-F:跨通道样例与基础业务场景
+
+### 目标
+
+让三种方式使用同一业务语义,而不是三套互不关联的 Demo。
+
+### 运行编号
+
+```text
+SIM-{yyyyMMddHHmmss}-{shortId}
+```
+
+所有业务键由适配器附加运行编号。
+
+### 基础场景一:订单制造链
+
+```text
+物料
+→ 销售订单头/行
+→ 生产工单
+→ 工单用料
+→ 报工
+```
+
+### 基础场景二:采购执行链
+
+```text
+供应商
+→ 采购订单
+→ 供应商发货
+→ 收货/IQC
+→ 退货
+```
+
+### 基础场景三:库存与成品链
+
+```text
+库存期初
+→ API_INBOUND v2 出入库流水
+→ 成品报检
+→ 成品入库/结存
+```
+
+### 关联键
+
+- 销售:订单号 + 行号;
+- 制造:工单号;
+- 采购:采购单号 + 行号 + 物料;
+- 库存:流水 Id + 物料 +业务类型;
+- 齐套:核验头 Id + 工单号;
+- 成品:生产订单号 + 销售订单号。
+
+### 验收
+
+- 三种通道的样例适配后保持业务含义一致;
+- 无契约节点明确显示“不支持该通道”;
+- 不因跳过节点宣称链路完整;
+- 样例不使用固定真实单号。
+
+---
+
+## 10. P1-G:预检、结果分层与报告
+
+### 预检
+
+每次执行前检查:
+
+- 模拟端是否可用;
+- Ai-DOP 是否可访问;
+- 来源是否存在;
+- 实体是否登记;
+- 目标贴源是否登记;
+- API_INBOUND 是否 enabled;
+- schema/grant 是否可用;
+- 最终目标租户;
+- 运行编号是否唯一。
+
+### 三层报告
+
+#### 代码层
+
+```text
+SUPPORTED / UNSUPPORTED
+```
+
+#### 配置层
+
+```text
+READY / NOT_REGISTERED / NOT_ENABLED / GRANT_MISSING / SOURCE_UNREACHABLE
+```
+
+#### 数据层
+
+```text
+NOT_RUN / ACCEPTED / STAGING_WRITTEN / TRANSFORM_PENDING / RUN_FAILED
+```
+
+第一阶段若没有安全的只读管理 API 查询贴源结果,允许报告 `TRANSFORM_PENDING` 并给出人工 SQL,不得猜测成功。
+
+### 报告内容
+
+- 运行编号;
+- 时间;
+- 对象;
+- 通道;
+- 请求摘要;
+- 脱敏响应;
+- 三层结论;
+- 后续核验 SQL;
+- 已知契约缺口。
+
+---
+
+## 11. P1-H:测试、文档与第一阶段验收
+
+### 单元测试
+
+- 签名 golden vector;
+- SHA256 与 HMAC;
+- 脱敏;
+- 样例适配;
+- 业务键前缀;
+- MySQL DDL 生成;
+- cursor 过滤;
+- 三层状态判定;
+- 非白名单目标阻断。
+
+### 集成测试
+
+1. 启动 Mock API;
+2. 初始化模拟 MySQL;
+3. 启动 Ai-DOP;
+4. 配置三个测试来源;
+5. 每种方式至少跑通一个金标对象;
+6. DB_SYNC 跑一次增量;
+7. API_PULL 跑一次鉴权和 cursor;
+8. API_INBOUND 跑 26 实体 schema 预检和七类操作;
+9. 执行三组基础场景;
+10. 生成脱敏报告。
+
+### 推荐命令
+
+具体命令以实现后的 README 为准,预期形式:
+
+```text
+python -m venv .venv
+.venv\Scripts\pip install -r tools/integration-simulator/requirements.txt
+.venv\Scripts\python tools/integration-simulator/app.py
+.venv\Scripts\pytest tools/integration-simulator/tests
+```
+
+### 第一阶段验收表
+
+- [ ] 三种通道都经过 Ai-DOP 真实执行器
+- [ ] MySQL 模拟库不等于 Ai-DOP 库
+- [ ] API_PULL Mock 可切鉴权与错误
+- [ ] API_INBOUND Secret 不进浏览器
+- [ ] 业务页全部数据包已登记能力矩阵
+- [ ] 26 个推数契约全部预检
+- [ ] 七类推数操作都有基础用例
+- [ ] 三组跨对象场景可执行
+- [ ] 配置未开与代码不支持分开显示
+- [ ] 运行报告已脱敏
+- [ ] 没有直接写 Ai-DOP 业务表
+- [ ] 没有改变生产标准对象来源
+
+---
+
+## 12. 第二阶段任务
+
+### P2-A:SQL Server 方言
+
+- 建立 SQL Server 模拟库;
+- 验证列探测;
+- 验证 OFFSET/FETCH;
+- 验证 keyset;
+- 对比 MySQL 与 SQL Server 序列化差异。
+
+### P2-B:场景编排
+
+- 依赖图;
+- 自动排序;
+- 多对象批次;
+- 场景回放;
+- 参数化业务日期与数量;
+- 场景版本管理。
+
+### P2-C:故障注入
+
+- 网络中断;
+- 超时;
+- 限流;
+- 重复;
+- 乱序;
+- cursor 不推进;
+- 脏业务键;
+- 快照差集阻断;
+- 大批量压力。
+
+### P2-D:全链路自动对账
+
+- 贴源;
+- 标准层;
+- DWD;
+- KPI;
+- 看板 API;
+- S8 规则输入;
+- ChatBI 可查询范围。
+
+### P2-E:CLI / CI / 容器化
+
+- 无界面运行;
+- JUnit/JSON 报告;
+- Docker Compose;
+- 每日契约回归;
+- Pull Request 守卫;
+- 契约漂移检测。
+
+### P2-F:Ai-DOP 契约扩展衔接
+
+对当前无 API_INBOUND 契约的对象逐项立任务:
+
+- 销售订单头;
+- 合同评审;
+- 发货计划/发货单;
+- 工序计划;
+- MRP;
+- 采购申请;
+- 交货计划;
+- 现存量;
+- 过程检验;
+- 成品入库。
+
+这些任务属于 Ai-DOP 产品能力建设,不应混入模拟器代码。
+
+---
+
+## 13. 反向影响推演
+
+### 13.1 代码调用面
+
+已核查:
+
+- DB_SYNC → `MdpSourcePullDispatcher` → `MdpDbPullExecutor`;
+- API_PULL → `MdpSourcePullDispatcher` → `MdpApiPullExecutor`;
+- API_INBOUND → `MdpInboundController` → 接收服务;
+- 三者最终进入现有贴源/转换路径。
+
+结论:**第一阶段模拟器本身无主链影响;真实测试会调用同步与重建链。**
+
+### 13.2 数据契约面
+
+已核查:
+
+- 三通道需统一业务键与业务语义;
+- 技术页字段是样例适配依据;
+- API_INBOUND 只有 26 个现有代码契约;
+- 周转类推数依赖库存流水 v2。
+
+结论:**需同步新增对象目录与样例适配器;不得改现有指标口径。**
+
+### 13.3 多数据源面
+
+已核查:
+
+- 同一 standard object 可能已有 T8、165、自建单或真实第三方来源;
+- 三种模拟通道不能共用 source_code;
+- 测试来源不能成为生产权威。
+
+结论:**需三个专用测试来源;运行前显示来源决策。**
+
+### 13.4 多租户 / Domain 面
+
+已核查:
+
+- API_INBOUND 租户取开放身份;
+- DB/API 拉取取来源与实体配置;
+- Domain 不能代替 tenant_id。
+
+结论:**只允许测试租户;需在预检中显示租户和 Domain。**
+
+### 13.5 运行面
+
+已核查:
+
+- 模拟器依赖 Python 与 MySQL;
+- Mock API 现有默认端口为 8018;
+- 测试会占用同步、重建、限流与 nonce 资源;
+- 第一阶段不应做高并发压测。
+
+结论:**需低频批次限制、端口检测和生产目标硬阻断。**
+
+### 13.6 验证面
+
+已核查:
+
+- 现有 push demo 有 10 类推数用例;
+- 现有 mock_api 有大量对象样例;
+- 模拟数据库缺完整物化;
+- 没有统一三层报告。
+
+结论:**需补模拟数据库、统一控制、状态分层与守卫测试。**
+
+---
+
+## 14. 版本与提交规则
+
+### 本次文档交付
+
+只新增/修改说明文档,不递增前后端版本。
+
+### 后续第一阶段代码
+
+若只改 `tools/`、`doc/db/mdp/mock_api/` 和文档,且不进入前后端运行构建:
+
+- 不递增 `Web/package.json`;
+- 不递增 server `.csproj`。
+
+若实施中修改 `Web/` 或 `server/` 运行代码/配置:
+
+- 按实际纳入提交的端递增 patch;
+- 前后端同时改则分别递增;
+- 不得因为计划涉及某端但提交未包含该端而升号。
+
+建议提交拆分:
+
+1. `feat(simulator): 建立三通道公共目录与本地控制台`
+2. `feat(simulator): 增加 MySQL 与 API_PULL 模拟`
+3. `feat(simulator): 接入 API_INBOUND 全协议测试`
+4. `test(simulator): 增加三通道场景与脱敏报告守卫`
+
+用户说“提交”时按仓库规则 commit + push。
+
+---
+
+## 15. 交付报告模板
+
+### 版本与提交
+
+- 模拟器版本:
+- commits:
+- 是否修改 Web/server:
+
+### 三层结果
+
+#### 代码层
+
+- DB_SYNC:
+- API_PULL:
+- API_INBOUND:
+
+#### 配置层
+
+- 测试租户:
+- 三个 source_code:
+- 已登记对象:
+- 未登记/未授权对象:
+
+#### 数据层
+
+- DB_SYNC 流水:
+- API_PULL 贴源:
+- API_INBOUND request/receipt:
+- 标准层/KPI:已核验或待核验:
+
+### 对象覆盖
+
+- 业务页数据包:
+- API_INBOUND 26 契约:
+- 无推送契约对象:
+
+### 安全
+
+- Secret 未落盘:
+- 报告已脱敏:
+- 生产地址已阻断:
+
+### 反向影响
+
+- 调用面:
+- 契约面:
+- 多来源:
+- 多租户:
+- 运行:
+- 验证:
+
+### 未完成项
+
+- 阻塞:
+- 第二阶段候选:
+
+---
+
+## 16. 后续执行者启动提示词
+
+```text
+请严格执行 doc/plan/系统集成/Ai-DOP第三方对接模拟器初步执行任务书.md 的第一阶段。
+
+开工前:
+1. 读取 AGENTS.md 和全部 alwaysApply 规则;
+2. 重跑任务书 G3 的代码/配置/数据三层基线;
+3. 列出实际改动文件、可见行为、风险和不做范围,等待确认;
+4. 不得提交 Word 锁文件、日志、凭据、连接串或真实业务数据。
+
+第一阶段必须同时覆盖 DB_SYNC、API_PULL、API_INBOUND。
+不得绕过 Ai-DOP 执行器直接写贴源/标准/KPI 表。
+不得把配置未开通说成代码未实现。
+不得把 HTTP 成功说成业务全链路已跑通。
+```

+ 700 - 0
doc/plan/系统集成/Ai-DOP第三方对接模拟器建设方案.md

@@ -0,0 +1,700 @@
+# Ai-DOP 第三方对接模拟器建设方案
+
+| 项 | 内容 |
+|---|---|
+| 文档定位 | 第三方对接模拟器总体方案 |
+| 编制日期 | 2026-09-30 |
+| 状态 | 初版方案,待按配套任务书实施 |
+| 业务依据 | [`Ai-DOP第三方对接业务数据详表-业务页.md`](./Ai-DOP第三方对接业务数据详表-业务页.md) |
+| 技术依据 | [`Ai-DOP第三方对接业务数据详表-技术页.md`](./Ai-DOP第三方对接业务数据详表-技术页.md)、[`Ai-DOP第三方系统集成指南.md`](./Ai-DOP第三方系统集成指南.md) |
+| 配套任务书 | [`Ai-DOP第三方对接模拟器初步执行任务书.md`](./Ai-DOP第三方对接模拟器初步执行任务书.md) |
+
+---
+
+## 0. 一句话
+
+建设一个独立运行的本地第三方系统模拟器,用同一套可追踪业务样例分别模拟:
+
+1. 第三方数据库供 Ai-DOP 同步,即 `DB_SYNC`;
+2. 第三方查询 API 供 Ai-DOP 主动拉取,即 `API_PULL`;
+3. 第三方主动调用 Ai-DOP 标准接口推数,即 `API_INBOUND`。
+
+第一阶段以“能真实完成三种对接方式的基础联调”为目标;第二阶段再补场景编排、故障注入、自动对账、更多数据库方言与持续回归。
+
+---
+
+## 1. 背景与问题
+
+Ai-DOP 已具备三种入站方式,但当前联调资产分散:
+
+- API 主动拉取 Mock 位于 `doc/db/mdp/mock_api/`;
+- API 推数客户端位于 `tools/mock/inbound/push_demo.py`;
+- 数据库模拟脚本只登记过 Mock 来源,尚未形成完整的“样例 → 源表 → 同步 → 验收”工具;
+- 各工具没有统一页面、统一样例目录、统一运行编号和统一结果解释;
+- 接口成功、配置开通、数据真正进入贴源与标准层经常被混成一个结论。
+
+因此,测试人员需要在多个脚本、配置页和数据库查询之间来回切换,难以快速回答:
+
+- 当前失败是模拟端没启动、Ai-DOP 代码不支持、配置没开通,还是数据未跑通?
+- 同一业务对象用数据库同步、接口拉取、接口推送时,最终是否落到一致的数据语义?
+- HTTP 202 是否只是接收成功,还是下游贴源、转换和指标也成功?
+- 当前业务数据详表中的对象,哪些能通过哪种方式验证?
+
+---
+
+## 2. 建设目标
+
+### 2.1 第一阶段目标:基础联调可用
+
+第一阶段交付一个独立本地可视化工具,做到:
+
+1. 启停第三方 Mock API;
+2. 初始化并装载第三方 MySQL 模拟源库;
+3. 使用真实签名调用 Ai-DOP API_INBOUND;
+4. 三种方式共用同一套 canonical 业务样例;
+5. 按业务对象查看请求、响应、耗时、运行编号与可解释结果;
+6. 能验证业务页、技术页中各数据包在三种方式下的可达性;
+7. 明确区分“代码无能力”“配置未开通”“数据未跑通”;
+8. 不接触生产凭据,不把测试数据伪装成真实业务数据。
+
+第一阶段不是完整自动化测试平台,不要求把所有标准层、KPI 和看板对账全部自动化。
+
+### 2.2 第二阶段目标:可重复的集成回归平台
+
+第二阶段在第一阶段基础上增加:
+
+- 跨对象业务场景编排;
+- 错误签名、超时、重复、乱序、分页、断点续传等故障注入;
+- 标准层、DWD、KPI、看板结果自动对账;
+- SQL Server 数据库方言回归;
+- CLI/CI 无界面执行;
+- 报告导出、历史对比与脱敏留证;
+- Docker 化与一键环境初始化;
+- 对当前无 API_INBOUND 契约的业务对象,在 Ai-DOP 先完成契约扩展后纳入推数回归。
+
+---
+
+## 3. 明确不做
+
+### 3.1 第一阶段不做
+
+- 不模拟 Ai-DOP 向第三方回写的出站接口;
+- 不直接写 Ai-DOP 贴源表、标准表、DWD 或 KPI 表;
+- 不绕过现有 `MdpDbPullExecutor`、`MdpApiPullExecutor`、`MdpInboundController`;
+- 不为不存在的 API_INBOUND 对象伪造接口;
+- 不自动修改生产环境的数据源、实体、授权或开放身份;
+- 不持久化 AccessSecret、数据库密码、JWT、连接串;
+- 不以 HTTP 200/202 单独宣称“业务已跑通”;
+- 不在第一阶段同时模拟 MySQL、SQL Server、Oracle、PostgreSQL 四种数据库。
+
+### 3.2 第二阶段另立项的 Ai-DOP 能力缺口
+
+下列对象当前没有 API_INBOUND 推送契约,模拟器不能代替 Ai-DOP 实现它们:
+
+- 销售订单头;
+- 合同评审环节;
+- 发货计划与发货单;
+- 工序级日计划与排产结果;
+- 物料需求计划;
+- 采购申请;
+- 交货计划;
+- 现存量快照;
+- 过程检验;
+- 成品入库。
+
+它们在第一阶段仍可通过 `DB_SYNC` 或 `API_PULL` 模拟;若要支持第三方主动推送,须先完成 Ai-DOP 契约与贴源配置扩展。
+
+---
+
+## 4. 现状取证
+
+能力结论必须分代码层、配置层、数据层。
+
+### 4.1 代码层
+
+#### 数据库同步
+
+- 执行器:`server/Plugins/Admin.NET.Plugin.AiDOP/DataPlatform/Executors/MdpDbPullExecutor.cs`;
+- 实施名:`DB_SYNC`;
+- 连接工厂:`MdpSourceScopeFactory.cs`;
+- 代码支持 MySQL、SQL Server、Oracle、PostgreSQL;
+- 增量依赖 `mdp_entity.incr_column` 与 `last_cursor`;
+- MySQL 与 SQL Server 有不同分页 SQL。
+
+结论:代码层已有数据库同步能力。第一阶段用 MySQL 覆盖主路径,第二阶段补 SQL Server 方言回归。
+
+可重跑检索:
+
+```text
+rg "SupportedType.*DB_SYNC|class MdpDbPullExecutor|MapDbType" server/Plugins/Admin.NET.Plugin.AiDOP
+```
+
+#### 主动接口拉取
+
+- 执行器:`server/Plugins/Admin.NET.Plugin.AiDOP/DataPlatform/Executors/MdpApiPullExecutor.cs`;
+- 实施名:`API_PULL`;
+- 当前采用 GET;
+- 支持 `NONE`、Bearer/Token、Basic、APIKey、OAuth2 等鉴权配置;
+- 支持 `response_data_path`、`dedup_key_path`;
+- 增量模式会附加 cursor 参数;
+- 当前不是通用多页循环客户端,Mock 必须按现有契约一次返回本批数据。
+
+结论:代码层已有 API 拉取能力,现有 `doc/db/mdp/mock_api/mock_server.py` 可作为基础。
+
+可重跑检索:
+
+```text
+rg "class MdpApiPullExecutor|response_data_path|dedup_key_path|cursor" server/Plugins/Admin.NET.Plugin.AiDOP
+```
+
+#### 第三方接口推送
+
+`server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/MdpInboundController.cs` 已提供:
+
+1. `POST /api/mdp/inbound/{entityCode}`;
+2. `GET /api/mdp/inbound/{entityCode}/schema`;
+3. `GET /api/mdp/inbound/receipts/{syncBatchId}`;
+4. `POST /api/mdp/inbound/{entityCode}/snapshots`;
+5. `POST /api/mdp/inbound/{entityCode}/snapshots/{snapshotId}/commit`;
+6. `POST /api/mdp/inbound/{entityCode}/bulk`;
+7. `GET /api/mdp/inbound/{entityCode}/digest`。
+
+认证使用 `InboundSignature`,签名字串为:
+
+```text
+METHOD&path&accessKey&timestamp&nonce&bodySha256&idempotencyKey
+```
+
+结论:代码层已有统一推数、验签、幂等、回执、快照、bulk 和 digest 能力。
+
+可重跑检索:
+
+```text
+rg "Http(Post|Get)|InboundSignature|Idempotency-Key" server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/MdpInboundController.cs server/Plugins/Admin.NET.Plugin.AiDOP/DataPlatform/Inbound
+```
+
+### 4.2 配置层
+
+#### DB_SYNC / API_PULL
+
+必须存在:
+
+- `mdp_source`:来源类型、连接方式、数据库或 API 配置;
+- `mdp_entity`:源表/API path、目标贴源表、业务键、增量列、批次参数;
+- 租户标准对象来源登记;
+- 触发该对象拉取的模块重建或同步入口。
+
+#### API_INBOUND
+
+必须同时满足:
+
+1. 代码有字段契约;
+2. `mdp_entity.inbound_enabled=1`;
+3. `mdp_inbound_grant` 有当前 AccessKey 与 entityCode 授权;
+4. `SysOpenAccess` 有同 AccessKey 的开放身份和绑定租户。
+
+当前迁移脚本曾为联调来源准备最多 20 个实体授权,但运行环境不得仅凭脚本推定已开通。模拟器必须通过 schema 与预检结果实测。
+
+### 4.3 数据层
+
+本次只读查询:
+
+```sql
+SELECT status, COUNT(*)
+FROM mdp_inbound_request
+GROUP BY status;
+```
+
+返回空结果集,说明当前目标库尚无可分组的入站请求流水。该结论只表示数据未真实跑过,不表示代码没有能力。
+
+DB_SYNC / API_PULL 的真实运行情况需在实施前重跑:
+
+```sql
+SELECT source_code, status, COUNT(*) AS cnt,
+       MAX(end_time) AS latest_end
+FROM mdp_sync_log
+GROUP BY source_code, status
+ORDER BY source_code, status;
+```
+
+并按目标贴源表检查来源分布、最新业务日期和样例业务键。
+
+---
+
+## 5. 总体架构
+
+```mermaid
+flowchart LR
+  subgraph simulator [第三方对接模拟器]
+    ControlPanel[本地可视化控制台]
+    SampleCatalog[统一业务样例目录]
+    MockDb[(MySQL模拟源库)]
+    MockApi[第三方查询API]
+    InboundClient[第三方签名推数客户端]
+    RunStore[本地脱敏运行记录]
+    ControlPanel --> SampleCatalog
+    ControlPanel --> MockDb
+    ControlPanel --> MockApi
+    ControlPanel --> InboundClient
+    ControlPanel --> RunStore
+  end
+
+  subgraph aidop [Ai-DOP]
+    DbExecutor[MdpDbPullExecutor]
+    ApiExecutor[MdpApiPullExecutor]
+    InboundApi[MdpInboundController]
+    Staging[(mdp_stg贴源)]
+    Transform[标准层转换与模块重建]
+  end
+
+  MockDb -->|DB_SYNC| DbExecutor
+  MockApi -->|API_PULL| ApiExecutor
+  InboundClient -->|API_INBOUND| InboundApi
+  DbExecutor --> Staging
+  ApiExecutor --> Staging
+  InboundApi --> Staging
+  Staging --> Transform
+```
+
+### 5.1 独立工具而非 Ai-DOP 内置页面
+
+选择独立工具的原因:
+
+- 被测系统与模拟第三方系统边界清晰;
+- 能真实验证网络、鉴权与协议,不与 Ai-DOP 登录态混用;
+- Secret 可留在本地服务进程内,不进入浏览器;
+- 可同时提供数据库、HTTP 查询 API、签名推数三类外部能力;
+- 后续可独立容器化或交付第三方现场使用;
+- 不新增 Ai-DOP 业务菜单和 FUNC 编号。
+
+### 5.2 技术形态
+
+第一阶段优先使用 Python 实现,复用现有 `push_demo.py` 和 `mock_server.py` 的协议代码:
+
+```text
+tools/integration-simulator/
+├─ app.py                    # 本地控制服务与页面
+├─ clients/
+│  ├─ inbound_client.py      # HMAC 签名与七类推数操作
+│  └─ aidop_probe.py         # 只读预检
+├─ providers/
+│  ├─ mock_api.py            # API_PULL 对端
+│  └─ mock_db.py             # MySQL 建表、装载、清理
+├─ catalog/
+│  ├─ entities.json          # 对象与三通道能力矩阵
+│  └─ samples/*.json         # canonical 样例
+├─ static/                   # 本地页面资源
+├─ tests/
+└─ README.md
+```
+
+不要求另起完整 Vue/npm 工程。页面只承担配置、编辑样例、发起操作和显示结果。
+
+---
+
+## 6. 三种方式的第一阶段设计
+
+### 6.1 DB_SYNC
+
+#### 模拟端
+
+- 使用独立 MySQL schema,例如 `aidop_integration_sim`;
+- 按 canonical 样例生成第三方源表;
+- 每张表必须有稳定业务键;
+- 增量对象必须有单调递增时间列;
+- 支持重置、装载、追加、更新四种动作;
+- 所有业务键以 `SIM-{runId}-` 开头;
+- 模拟库只充当第三方源库,不写 Ai-DOP 库。
+
+#### Ai-DOP 侧前置
+
+- `mdp_source.source_type=DB`;
+- `conn_mode=EXTERNAL`;
+- 配置测试数据库连接;
+- `mdp_entity.source_table_name`、`target_table_name`、`incr_column`、业务键正确;
+- 按既有模块入口触发同步或重建。
+
+#### 基础验收
+
+- 连接测试成功;
+- 首次同步写入贴源;
+- 再次同步不重复;
+- 更新增量列后只处理新增/更新数据;
+- `mdp_sync_log` 有可解释状态;
+- 贴源行 `source_system` 为专用模拟来源。
+
+### 6.2 API_PULL
+
+#### 模拟端
+
+- 提供 GET 接口;
+- 支持 `data.list` 响应路径;
+- 每行带稳定 `bizKey` 或配置对应去重路径;
+- 支持 cursor 入参;
+- 支持 NONE、Bearer/Token、Basic、APIKey 的基础联调;
+- 可返回 200、401、403、429、500 和延迟响应;
+- 第一阶段每次返回完整当前批,不实现复杂多页循环。
+
+#### Ai-DOP 侧前置
+
+- `mdp_source.source_type=API`;
+- 配置 base URL 与鉴权;
+- `mdp_entity.source_api_path`;
+- `response_data_path`;
+- `dedup_key_path`;
+- 增量对象配置 cursor 语义。
+
+#### 基础验收
+
+- Ai-DOP 能带正确认证调用 Mock;
+- 能从 `data.list` 取行;
+- 去重键稳定;
+- cursor 能推进;
+- 鉴权失败和服务端错误有可解释结果;
+- 贴源数据与 canonical 样例一致。
+
+### 6.3 API_INBOUND
+
+#### 模拟端
+
+- 本地服务读取 AccessKey 与 Secret;
+- Secret 只驻留服务端内存;
+- 自动生成 timestamp、nonce、body SHA256、幂等键和 HMAC 签名;
+- 支持契约版本头;
+- 支持全部七类入站操作;
+- 允许编辑 JSON 或 NDJSON;
+- 支持重复发送相同幂等键;
+- 不在页面或运行日志显示 Secret。
+
+#### Ai-DOP 侧前置
+
+- 开放身份已绑定测试租户;
+- grant 与 entityCode 已授权;
+- entity 已开启 inbound;
+- 来源为专用 `API_INBOUND` 测试来源;
+- 限流与 IP 白名单允许本机测试。
+
+#### 基础验收
+
+- schema 可读;
+- 普通推数返回 202;
+- receipt 可按批次查询;
+- 相同幂等键同报文返回幂等回放;
+- 相同幂等键不同报文返回冲突;
+- 错误签名、过期时间戳、nonce 重放被拒;
+- bulk、快照和 digest 可完成基础成功用例;
+- `mdp_inbound_request` 与贴源数据可对账。
+
+---
+
+## 7. 业务范围
+
+### 7.1 统一业务样例目录
+
+样例目录以业务页第 5 章确认表和技术页字段为基线,至少覆盖:
+
+- 物料、客户、供应商、货源清单、库位、员工;
+- 销售订单头、销售订单行、合同评审、齐套核验;
+- 生产工单、工序计划、工单用料、报工;
+- 交货计划、采购订单、采购申请、收货、供应商发货、来料检验、退货、欠料;
+- 出入库流水、库存期初、月度库存金额、现存量;
+- 成品报检、成品入库、成品结存;
+- 业务页明确要求的关联日期、数量、状态、业务类型、审核状态。
+
+同一场景中的订单号、工单号、采购单号、物料编码必须可关联。
+
+### 7.2 API_INBOUND 当前 26 个代码契约
+
+第一阶段模拟器须识别:
+
+```text
+MDM_ITEM
+MDM_CUSTOMER
+MDM_SUPPLIER
+MDM_LOCATION
+MDM_SOURCE_LIST
+MDM_EMPLOYEE_HEADCOUNT
+S1_SALES_ORDER_ENTRY
+S1_REQUIREMENT_EXAMINE_RESULT
+S1_REQUIREMENT_EXAMINE_DETAIL
+S2_WORK_ORDER_SCHEDULE
+S3_PURCHASE_ORDER
+S3_PURCHASE_RECEIPT
+S4_SHIPMENT
+S4_IQC
+S4_RETURN
+S4_SHORTAGE
+S5_WORK_ORDER_BOM
+S5_INVENTORY_TXN
+S5_INVENTORY_OPENING_BALANCE
+S5_INVENTORY_BALANCE_MONTHLY
+S6_WORK_ORDER_LINE
+S6_REPORT_TXN
+S7_FQC_TASK_TXN
+S7_SALES_ORDER_LINE
+S7_FINISHED_ONHAND
+S7_FINISHED_OPENING_BALANCE
+```
+
+支持某 entityCode 不等于运行配置已开通。预检结果必须分别显示:
+
+- `CODE_SUPPORTED`;
+- `CONFIG_NOT_REGISTERED`;
+- `CONFIG_NOT_ENABLED`;
+- `GRANT_MISSING`;
+- `READY`;
+- `DATA_NOT_RUN`;
+- `RUN_SUCCEEDED`;
+- `RUN_FAILED`。
+
+### 7.3 通道能力矩阵
+
+| 对象类型 | DB_SYNC | API_PULL | API_INBOUND |
+|---|:---:|:---:|:---:|
+| 技术页已开通的 20 个推数对象 | 可模拟 | 可模拟 | 可模拟 |
+| 客户/供应商/库位/货源 | 可模拟 | 可模拟 | 代码有契约,配置可能未开 |
+| 齐套结果头/明细 | 可模拟 | 可模拟 | 代码有契约,贴源配置待核 |
+| 销售订单头/合同评审 | 可模拟 | 可模拟 | 当前无契约 |
+| 交货计划/MRP/采购申请 | 可模拟 | 可模拟 | 当前无契约 |
+| 工序计划/排产 | 可模拟 | 可模拟 | 当前无契约 |
+| 现存量/过程检验/成品入库 | 可模拟 | 可模拟 | 当前无契约 |
+
+### 7.4 第一阶段跨对象基础场景
+
+至少提供三组样例:
+
+1. **订单制造链**:物料 → 销售订单 → 工单 → 工单用料 → 报工;
+2. **采购执行链**:供应商 → 采购订单 → 供应商发货 → 收货/IQC → 退货;
+3. **库存与成品链**:期初 → v2 出入库流水 → 成品报检 → 成品结存。
+
+API_INBOUND 无对应契约的节点必须在运行图中显示“该通道不支持”,不能跳过后仍宣称全链路完整。
+
+---
+
+## 8. 页面设计
+
+### 8.1 首页
+
+显示:
+
+- Ai-DOP 目标地址;
+- 模拟数据库状态;
+- Mock API 状态;
+- API_INBOUND 凭证是否已加载;
+- 三种方式的可用对象数量;
+- 最近运行结果。
+
+### 8.2 对象测试页
+
+用户选择:
+
+- 业务对象;
+- 对接方式;
+- 样例;
+- 运行编号;
+- 契约版本;
+- 操作类型。
+
+页面展示:
+
+- 请求/源数据预览;
+- 预检结果;
+- 执行结果;
+- 脱敏 Headers;
+- HTTP 状态和响应;
+- 后续人工核验提示;
+- 明确的代码/配置/数据层结论。
+
+### 8.3 环境安全页
+
+- 只允许 `localhost`、明确的开发/UAT 地址;
+- 生产目标默认阻断;
+- Secret 只从环境变量或启动输入读取;
+- 页面不可读取 Secret;
+- 运行记录自动脱敏;
+- 不提供“保存密码”按钮。
+
+---
+
+## 9. 安全与数据隔离
+
+1. 测试数据业务键统一加 `SIM-{runId}-`;
+2. 默认只允许测试租户;
+3. 三种通道使用不同 `source_code`,共享一个测试 `system_code`;
+4. 模拟数据库与 Ai-DOP 数据库必须是不同 schema/连接;
+5. 不在 Git 中写入任何密码、Secret、JWT 或真实连接串;
+6. 导出报告不含认证头、Secret、数据库密码和完整敏感 payload;
+7. 删除测试数据不由模拟器直接执行,第一阶段只提供运行编号和清理清单;
+8. API_INBOUND 不接受 body 中任意 tenantId 改变目标租户;
+9. 生产 URL 必须显式传入二次解锁参数方可调用,且第一阶段验收禁止使用生产。
+
+---
+
+## 10. 两阶段交付
+
+### 10.1 第一阶段:基础实现
+
+交付:
+
+- 独立本地控制台;
+- MySQL 模拟源库;
+- 第三方 Mock GET API;
+- API_INBOUND 签名客户端;
+- 统一样例目录;
+- 三通道对象能力矩阵;
+- 三种方式的基础成功/失败用例;
+- API_INBOUND 26 契约与 7 类操作;
+- 三组跨对象基础场景;
+- 脱敏运行记录;
+- 启动与配置说明;
+- 人工 SQL/API 验收清单。
+
+完成条件:
+
+- 任一具备配置的对象可选择三种方式之一执行;
+- 同一 canonical 样例可供三种方式转换使用;
+- 三条路径均经过 Ai-DOP 真实执行器;
+- 结果能明确定位到代码、配置或数据层;
+- 不依赖修改 Ai-DOP 业务代码即可完成基础联调。
+
+### 10.2 第二阶段:增强
+
+交付:
+
+- SQL Server 模拟库;
+- 场景编排与依赖自动排序;
+- 并发、限流、超时、乱序、断点、重试和错误注入;
+- 自动查询标准层、DWD、KPI 与看板 API;
+- 三通道同业务结果差异报告;
+- 历史报告与趋势;
+- CLI/CI;
+- Docker Compose;
+- Playwright 页面回归;
+- 契约漂移检测;
+- 当前无 API_INBOUND 契约对象的扩展项目衔接。
+
+---
+
+## 11. 验收口径
+
+### 11.1 代码层验收
+
+- DB_SYNC 确实经过 `MdpDbPullExecutor`;
+- API_PULL 确实经过 `MdpApiPullExecutor`;
+- API_INBOUND 确实经过 `MdpInboundController`;
+- 未新增直接写 Ai-DOP 业务表的旁路;
+- 签名算法有固定向量测试;
+- canonical 样例到三种通道的适配有单元测试。
+
+### 11.2 配置层验收
+
+- 每个对象显示来源、实体、目标贴源、业务键、增量列;
+- API_INBOUND 显示 entity 是否启用及 grant 是否可用;
+- 配置未开时明确停止,不自动改生产配置;
+- 同一标准对象不会误把三种来源同时设为生产权威。
+
+### 11.3 数据层验收
+
+- DB_SYNC:`mdp_sync_log`、游标、贴源来源分布可对账;
+- API_PULL:贴源 raw_data、业务键、cursor 可对账;
+- API_INBOUND:request、receipt、accepted/rejected、贴源可对账;
+- 三种方式都能查到最新业务日期;
+- “未产生数据”不能写成“代码未实现”。
+
+### 11.4 第一阶段完成判据
+
+第一阶段完成不等于所有 KPI 已有值。完成判据是:
+
+1. 三种入站方式都至少有一个对象真实跑通;
+2. 业务/技术详表的全部数据包都有通道能力标记;
+3. API_INBOUND 的已存在 26 个代码契约都能执行 schema 预检;
+4. 已配置的推数实体能执行普通 POST;
+5. 七类推数操作均有基础测试;
+6. 未配置或无契约对象能得到正确的分层结论;
+7. 三组基础业务场景可以装载和执行;
+8. 凭据与测试数据隔离要求全部满足。
+
+---
+
+## 12. 反向影响推演
+
+### 12.1 代码调用面
+
+- DB_SYNC 会经过所有调用 `MdpSourcePullDispatcher` 的模块同步/重建入口;
+- API_PULL 与 DB_SYNC 共用分发和贴源写入;
+- API_INBOUND 进入接收、镜像、中立投影和模块重建;
+- 第一阶段不修改这些主链,只新增独立工具。
+
+结论:**无主链代码改动;真实模拟流量会触发既有同步和重建。**
+
+### 12.2 数据契约面
+
+- 三种方式最终写同类贴源与标准对象;
+- 错误业务键可能覆盖同来源旧数据;
+- 日期、数量、业务类型、审核状态缺失会导致 HTTP 成功但指标无值;
+- `S5_INVENTORY_TXN` 周转类场景必须使用 v2 中立契约。
+
+结论:**需同步维护统一样例目录和字段映射;业务键必须测试隔离。**
+
+### 12.3 多数据源面
+
+- 三种来源不能用同一 `source_code`;
+- 同一标准对象生产时只能有一个权威来源;
+- 模拟运行只能使用测试来源,不得改变现有 T8、165、自建单或真实第三方来源。
+
+结论:**需三个测试 source_code 和共同 system_code;不得抢占生产来源。**
+
+### 12.4 多租户 / Domain 面
+
+- API_INBOUND 租户由开放身份决定;
+- DB_SYNC/API_PULL 按来源、实体和租户来源登记决定;
+- Domain 是业务域字段,不得替代 tenant_id;
+- canonical 样例必须可配置 Domain,但不能由此跨租户。
+
+结论:**只允许测试租户;运行前必须显示最终目标租户。**
+
+### 12.5 运行面
+
+- 需要本地 MySQL、Python Mock 服务和 Ai-DOP 开发/UAT 环境;
+- 真实请求会占用限流、nonce、同步任务和重建队列;
+- 大批量运行可能影响共享开发库;
+- 生产地址和凭据必须硬阻断。
+
+结论:**第一阶段默认低频单批,批量压测放第二阶段。**
+
+### 12.6 验证面
+
+- 现有 `push_demo.py` 仅覆盖推数部分场景;
+- 现有 `mock_api` 可复用但缺统一控制与结果分层;
+- 模拟 DB 尚缺完整样例物化;
+- 当前缺三通道同样例自动比较。
+
+结论:**第一阶段补基础守卫与人工对账,第二阶段补全链自动对账。**
+
+---
+
+## 13. 风险与控制
+
+| 风险 | 控制 |
+|---|---|
+| 测试数据污染真实业务 | 专用租户、来源、`SIM-{runId}` 业务键 |
+| Secret 泄漏 | 只在本地服务内存,日志和报告脱敏 |
+| 配置没开被误判为代码缺失 | 三层状态码与 schema 预检 |
+| HTTP 成功被误判为业务出数 | 第一阶段报告分“摄取成功”和“下游待核” |
+| 三种来源相互覆盖 | 不同 source_code,共同 system_code,仅测试来源 |
+| 大量数据触发重建压力 | 第一阶段单批低频,默认限制行数 |
+| API_PULL Mock 超出执行器能力 | 严格遵循现有 GET、data path、cursor 契约 |
+| MySQL 单引擎不能代表 SQL Server | 明确列为第二阶段方言回归 |
+
+---
+
+## 14. 决策结论
+
+1. 模拟器作为独立工具建设,不进入 Ai-DOP 菜单;
+2. 第一阶段同时覆盖 DB_SYNC、API_PULL、API_INBOUND;
+3. 第一阶段数据库模拟只做 MySQL,SQL Server 放第二阶段;
+4. 三种方式共用 canonical 样例,但保持独立 source_code;
+5. API_INBOUND 覆盖现有 26 个代码契约与 7 类操作;
+6. 业务页中无推送契约的对象仍通过 DB_SYNC/API_PULL 测试;
+7. 第一阶段不改 Ai-DOP 业务主链,不自动写生产配置;
+8. 方案实施以配套初步任务书为准。

+ 7 - 0
doc/plan/系统集成/README.md

@@ -16,6 +16,13 @@
 python doc/plan/系统集成/_gen_integration_guide_docx.py
 ```
 
+## 第三方对接模拟与测试(内部)
+
+| 文档 | 说明 |
+|------|------|
+| [Ai-DOP第三方对接模拟器建设方案.md](./Ai-DOP第三方对接模拟器建设方案.md) | 独立本地第三方系统模拟器总体方案;第一阶段同时验证数据库同步 `DB_SYNC`、主动接口拉取 `API_PULL`、第三方接口推送 `API_INBOUND`,第二阶段扩展全链路自动对账、故障注入、SQL Server 与 CI |
+| [Ai-DOP第三方对接模拟器初步执行任务书.md](./Ai-DOP第三方对接模拟器初步执行任务书.md) | 可供后续开发者或大模型执行的两阶段初步任务书;含三层基线、文件清单、工作包、26 个推数契约、7 类推数操作、测试门禁和六面反向影响 |
+
 ## 中立标准层改造(本目录,内部)
 
 | 文档 | 说明 |