You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iTi-Flask/docs/ERP_SERVICE.md

215 lines
3.7 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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 <service-token>
X-Trace-Id: <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。
限制:
- 只在一个专用进程启用。
- 任务状态第一版可以存在进程内。
- 需要跨重启恢复时,再引入数据库任务表。
这不是分布式任务平台。