Files
SystemSimulationApp/docs/standard/backend-interface-version-spec-v1.md
T

237 lines
11 KiB
Markdown
Raw 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.
# 后端接口版本与定义规范 v1
本文统一说明 SystemSimulationApp 后端的接口边界、版本编号和事实来源。规范版本为
`1.0.0`。这个编号只表示本文档自身的修订版本,不等同于 HTTP API、System XML、
组件目录或单个模型的版本。
## 1. 当前版本基线
后端没有一个可以替代所有子版本的“总版本号”。调用方必须按所使用的数据合同读取
对应版本:
| 版本轴 | 当前值 | 作用范围 | 机器可读事实来源 |
| --- | --- | --- | --- |
| HTTP API | 未版本化 | `/api/...` 路由、请求和响应 | `app/main.py`、FastAPI OpenAPI |
| 后端应用发布版本 | 未定义 | 整个后端部署产物 | 当前没有包元数据或运行时常量 |
| 组件目录 Schema | `1` | `GET /api/components/catalog` | `schemas/component-catalog-v1.schema.json` |
| System XML Schema | `3` | XML 校验、编译和仿真输入 | `schemas/system-simulation-v3.xsd` |
| 组件库版本 | 各库独立 | 一个组件库的发布边界 | 各库 `library.py` 的 `version` |
| 模型合同版本 | 各模型独立 | 单个 `MODEL_TYPE` 的物理和数据合同 | 模型类的 `MODEL_VERSION` |
| ReactFlow 工程 JSON | `1` | 编辑器存档 | `projectSchemaVersion`、`ReactFlowProjectPayload` 和前端读取代码 |
| 结果文件格式 | `1` | 前端导入、导出的结果快照 | `SimulationResultsView.tsx` |
因此,`schemaVersion=3` 只能说明文件是 System XML v3,不能说明“后端 API 是
v3”;`MODEL_VERSION=0.2.0` 也只描述对应模型合同。
FastAPI 自动生成的 OpenAPI 当前可能显示默认 `info.version=0.1.0`;后端没有显式
声明这个值,因此它不是正式 API 或应用发布版本。
## 2. 事实来源和优先级
接口定义冲突时,按以下优先级处理:
1. 可执行代码和机器可读 Schema;
2. 自动化合同测试;
3. 当前版本规范文档;
4. 示例、调研记录和历史说明。
各类合同的唯一事实来源如下:
| 合同 | 唯一事实来源 |
| --- | --- |
| 公开模型类型和版本 | 模型类的 `MODEL_TYPE`、`MODEL_VERSION` |
| 端口物理合同 | 模型类的 `PORTS` 和 `app/simulation/core/ports.py` |
| 参数、结果及单位 | 模型类的 `PARAMETERS`、`RESULT_VARIABLES` |
| 组件库及分类 | 各库 `library.py` |
| 组件目录 JSON | `build_component_catalog()` 与目录 JSON Schema |
| System XML | v3 XSD、`app/system_xml.py` |
| ReactFlow 参数表达式 | `app/parameter_expression.py`、`frontend/src/parameterExpression.ts` 及相应合同测试 |
| 网络最终连接检查 | `SimulationNetwork.connect()` |
| HTTP 路由和请求模型 | `app/main.py` |
前端兜底目录、画布布局和示例 XML 不能反向定义后端物理合同。
## 3. 组件接口合同
每个公开组件必须显式声明:
```python
MODEL_TYPE = "example_component"
MODEL_VERSION = "1.0.0"
PORTS = (...)
PARAMETERS = (...)
RESULT_VARIABLES = (...)
DISPLAY = ...
```
并提供统一的 `create()` 入口。各字段含义如下:
- `MODEL_TYPE` 是工程、XML、目录和结果元数据共同使用的稳定机器标识;
- `MODEL_VERSION` 使用 `主版本.次版本.修订版本`;
- `PORTS` 定义端口名称、种类、物理域、名义角色、变量和连接规则;
- `PARAMETERS` 定义 SI 单位、默认值、范围和离散选项;
- `RESULT_VARIABLES` 定义结构化结果元数据;
- `DISPLAY` 只定义前端展示,不得成为物理方程的隐式输入。
物理流变量统一以进入组件为正。物理连接的两个端点无方向;信号方向由注册端口的
`output/input` 合同决定。
## 4. 组件目录接口
`GET /api/components/catalog` 返回组件库、分类和模型合同。响应顶层必须为:
```json
{
"schemaVersion": 1,
"libraries": []
}
```
目录结构由 `schemas/component-catalog-v1.schema.json` 约束。库必须携带
`version`,模型必须携带 `modelVersion`。目录 Schema 的整数版本只描述目录 JSON
结构;库和模型版本仍分别使用三段式版本号。
当前三段版本只接受 `数字.数字.数字`,不接受 prerelease 或 build metadata,不能直接
等同于完整 SemVer 实现。目录 Schema 对对象使用 `additionalProperties=false`,因此
新增字段也必须先评估严格消费者,不能只因字段可选就默认兼容。
目录响应是前端生成组件面板、参数编辑器和端口快照的来源。修改响应结构时必须同时
更新 JSON Schema、前端解析和合同测试。
## 5. System XML v3
System XML v3 是当前唯一支持的 XML 求解输入。根元素固定使用:
```xml
<System schemaVersion="3" unitSystem="SI">
```
每个组件必须包含 `id`、`type`、`modelVersion` 和完整 SI 参数;连接只包含两个
`Endpoint(component, port)`。端口合同由 `type + port` 从注册表恢复,XML 不保存
端口快照和画布布局。
`modelVersion` 必须与当前注册模型完全一致。版本不一致时返回
`COMPONENT_MODEL_VERSION_MISMATCH`,不会静默使用当前模型解释旧输入。完整结构见
`docs/standard/system-xml-v3.md` 和 `schemas/system-simulation-v3.xsd`。
## 6. HTTP API
FastAPI 当前直接注册未版本化的 `/api/...` 路由,没有 `/api/v1` 命名空间,也没有
运行时 `apiVersion`。主要业务接口如下:
| 方法与路径 | 请求合同 | 响应合同 |
| --- | --- | --- |
| `GET /api/components/catalog` | 无 | 组件目录 JSON v1 |
| `GET /api/reactflow/projects` | 无 | 已保存工程摘要列表 |
| `GET /api/reactflow/projects/{id}` | 工程 ID | 严格校验后的工程 JSON v1 |
| `POST /api/reactflow/projects/{id}` | `ReactFlowProjectPayload` | 保存摘要 |
| `POST /api/reactflow/system-xml` | `ReactFlowProjectPayload` | `application/xml`,System XML v3 |
| `POST /api/reactflow/compile-model` | `ReactFlowProjectPayload` | 编译网络 JSON |
| `POST /api/system-xml/validate` | 原始 XML v3 | 三层校验报告 |
| `POST /api/system-xml/parse` | 原始 XML v3 | 规范化执行模型 |
| `POST /api/system-xml/compile-model` | 原始 XML v3 | 校验报告、设置和网络 |
| `POST /api/system-xml/simulate` | 原始 XML v3 | 同步仿真结果 |
| `POST /api/system-xml/simulate-stream` | 原始 XML v3 | `application/x-ndjson` 事件流 |
| `GET /api/system-xml/simulations/{id}` | 路径 ID | 任务快照 |
| `POST /api/system-xml/simulations/{id}/cancel` | 取消原因 JSON | 取消受理状态 |
| `POST /api/simulation-results/csv` | 结构化结果 JSON | UTF-8 CSV 附件 |
两个固定算例接口 `simulate-testmodel` 和 `simulate-test-mql` 仍属于测试/基线能力,不能
视为任意拓扑仿真合同。
FastAPI 会生成 `/openapi.json`、`/docs` 和 `/redoc`。Pydantic JSON 请求体能够进入
OpenAPI,但当前多数 JSON 响应仍以 `dict[str, object]` 构造,XML、CSV 和 NDJSON
也使用原始响应类型。因此 OpenAPI 目前不是完整的响应合同;代码、Schema 和合同测试
仍是必要依据。
## 7. 数据命名、单位和错误
- XML 属性和目录 JSON 主要使用 `camelCase`;
- ReactFlow 仿真设置保留现有 `t_start/t_stop/step/max_step` 名称;
- 不允许调用方自行猜测或转换字段命名;
- XML 和求解参数统一使用 SI 基准值;
- 实例 ID 和机器标识必须稳定,显示名称不能代替机器标识。
ReactFlow 工程 JSON 的连续数值参数可保存前端既有的受限算术表达式。
编译或 JSON→XML 时,后端在内存中安全求值,再按 `parameterUnits` 从
显示单位换算为 SI。普通数值及数值字符串仍按已存储的 SI 值解释,避免
二次换算;原表达式不回写工程 JSON。离散选项参数和任意代码不属于该合同。
这是补齐已有工程 JSON v1 前端语义的兼容性修复,不改变 System XML v3:
XML 仍只保存最终 SI 数值。
System XML 校验问题统一包含:
```json
{
"severity": "error",
"layer": "semantic",
"code": "ENDPOINT_PORT_UNKNOWN",
"message": "...",
"path": "...",
"line": 1
}
```
其中 `severity/layer/code/message` 是核心字段,`path/line` 可选。同步 HTTP 错误目前既
可能是 FastAPI 字符串 `detail`,也可能是带 `message/issues/diagnostics` 的结构化
`detail`;流式接口则使用 `event=error` 的 NDJSON 事件。统一错误响应模型尚未实现,
调用方必须同时处理这三种现有形状。
## 8. 版本变更规则
### 8.1 模型和组件库
- 修订版本:修复实现,不改变输入、端口和结果合同;
- 次版本:向后兼容地增加有默认值的参数、结果或能力;
- 主版本:删除或改名端口/参数,或者改变既有物理语义。
修改 `MODEL_TYPE` 视为新模型,不得用原标识承载不兼容合同。
以上版本含义用于分类变更影响;当前 System XML v3 对 `modelVersion` 执行完整字符串
精确匹配。因此即使只是修订或次版本变化,旧 XML 也会被拒绝,不能把“向后兼容”
理解成解析器会自动接受旧版本。
### 8.2 目录和 XML Schema
- 兼容澄清不改变 Schema 版本;
- 新增可选字段前必须验证旧消费者行为;
- 删除字段、改名或改变既有语义必须提高 Schema 版本;
- Schema、解析器、导出器、文档和合同测试必须在同一修改中更新。
### 8.3 HTTP API
当前 HTTP API 未版本化,因此不得在原路径上直接发布破坏性变更。需要破坏现有请求
或响应合同前,应先单独设计 API 版本命名空间、兼容周期和下线规则;该机制不在本文
本次整理范围内。
## 9. 旧版本和迁移边界
当前后端只接受 System XML v3:
- 不按 `schemaVersion` 自动选择 v1/v2 解析器;
- 不提供 v1/v2 到 v3 的自动迁移器;
- 不对不匹配的 `modelVersion` 做自动升级;
- 旧版本值只用于验证“不受支持输入应被拒绝”的边界测试。
ReactFlow 工程 JSON 只接受 `projectSchemaVersion: 1` 的当前结构,每个节点必须保存
目录给出的 `modelVersion`。执行、编译和 XML 导出前会再次核对节点版本;缺失或不匹配
时明确拒绝,不能先补当前默认参数再冒充当前模型。字符串端口、缺失连接 Handle 或
已经删除的兼容标记也不会被猜测、补齐或迁移;以后确有升级需求时再为新的工程版本
单独设计迁移器。
MECMAS21 的 `useFriction`、`strib` 等 AMESim 选项统一使用目录声明的原生编码:
`1` 表示“否/禁用”,`2` 表示“是/启用”。工程 JSON v1、组件目录、System XML v3
和模型构造器不再接受或自动换算旧的 `0/1` 编码,也不再使用
`amesimParameterEncodingVersion` 触发猜测式转换。
## 10. 接口修改完成条件
任何接口合同变更至少应同时完成:
1. 更新唯一事实来源;
2. 根据兼容性决定是否提高对应版本;
3. 更新机器可读 Schema;
4. 更新当前规范和示例;
5. 增加请求、响应、拒绝边界和前后端联调测试;
6. 明确说明未实现的兼容或迁移能力。