# ERP Service 契约草案 ERP Service 是独立业务项目。 它不属于 iTi-Flask core。 它应按业务项目方式依赖 iTi-Flask,并遵从框架的应用工厂、module、migration、seed 和配置规则。 ERP Service 实际项目应放在 iTi-Flask 仓库之外。 ```text /root/Projects/iTi/erp-service ``` 在 ERP Service 这个业务项目内部,Monitor 能力以 module 组织。 本仓库只保留契约文档,不内置 ERP Service 代码。 ## 职责 ERP Service 负责隔离既有 Monitor ERP 系统。 第一版职责: - 调用 Monitor ERP HTTP API。 - 通过 ODBC 读取 Monitor ERP 数据库。 - 提供轻量定时同步任务。 - 将 ERP 数据上报给业务项目。 - 对业务项目提供统一 HTTP JSON API。 业务项目不直接连接 Monitor API。 业务项目不直接连接 Monitor ODBC。 ## 非目标 不做: - 服务注册发现。 - Kubernetes service mesh。 - 分布式事务。 - Saga。 - gRPC。 - 消息总线全家桶。 - 自动弹性伸缩。 - 多租户网关。 第一版只做 HTTP JSON。 ## 服务边界 ERP Service 自己持有: - Monitor API 配置。 - Monitor ODBC 配置。 - ERP 字段映射。 - ERP 查询和转换逻辑。 - ERP 同步任务状态。 业务项目只关心: - 请求哪个 ERP 能力。 - 传入业务参数。 - 得到标准 JSON 响应。 - 处理真实 HTTP 状态码。 ## 认证 服务间调用使用 service token。 请求头: ```http Authorization: Bearer X-Trace-Id: ``` `X-Trace-Id` 由调用方传入。 没有时调用方生成。 ## 状态码 服务间 API 使用真实 HTTP 状态码。 建议: - `200`:成功。 - `202`:任务已接受。 - `400`:请求参数错误。 - `401`:服务 token 无效。 - `404`:资源不存在。 - `409`:幂等键冲突或任务状态冲突。 - `422`:ERP 返回数据无法转换。 - `502`:Monitor API 或 ODBC 返回异常。 - `503`:Monitor 不可用。 - `504`:Monitor 超时。 不要把服务间失败包装成 HTTP 200。 ## API 草案 健康检查: ```http GET /health ``` 返回: ```json {"status": "ok"} ``` ERP API 代理能力: ```http POST /monitor/api/call ``` 请求: ```json { "name": "get_customer", "params": {"customer_id": "C001"} } ``` ODBC 查询能力: ```http POST /monitor/odbc/query ``` 请求: ```json { "name": "customer_by_id", "params": {"customer_id": "C001"} } ``` 同步任务: ```http POST /sync/jobs GET /sync/jobs/{job_id} ``` 创建请求: ```json { "kind": "customers", "since": "2026-05-08T00:00:00+08:00", "callback_url": "http://business.local/internal/erp/customers", "idempotency_key": "customers-20260508" } ``` 创建返回: ```json { "job_id": "01HX...", "status": "accepted" } ``` ## 调用约定 业务项目调用 ERP Service 时使用 `iti.service_client`。 默认建议: ```python SERVICES = { "erp": { "base_url": "http://erp-service:8000", "token": "...", "timeout": { "connect": 1.0, "read": 10.0, "write": 5.0, "pool": 1.0, }, "retry": { "attempts": 2, "backoff": 0.2, "statuses": [502, 503, 504], }, "circuit_breaker": { "enabled": True, "fail_max": 5, "reset_timeout": 30, }, } } ``` GET 查询可以默认重试。 POST 默认不重试。 需要重试 POST 时,必须提供 `idempotency_key`。 ## 任务边界 ERP Service 可以使用 iTi-Flask 的轻量 task runner。 限制: - 只在一个专用进程启用。 - 任务状态第一版可以存在进程内。 - 需要跨重启恢复时,再引入数据库任务表。 这不是分布式任务平台。