17 KiB
后端接口版本与定义规范 v1
修订日期:2026-09-12;核对代码基线:22579e5。本版按代码补齐存储/执行、表达式、流式结果、浏览器保存和任务生命周期边界。
本文统一说明 SystemSimulationApp 后端的接口边界、版本编号和事实来源。规范版本为
1.2.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 | 2(兼容读 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. 事实来源和优先级
接口定义冲突时,按以下优先级处理:
- 可执行代码和机器可读 Schema;
- 自动化合同测试;
- 当前版本规范文档;
- 示例、调研记录和历史说明。
各类合同的唯一事实来源如下:
| 合同 | 唯一事实来源 |
|---|---|
| 公开模型类型和版本 | 模型类的 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 |
| 网络最终连接检查 | SimulationNetwork.connect() |
| HTTP 路由和请求模型 | app/main.py |
前端兜底目录、画布布局和示例 XML 不能反向定义后端物理合同。
3. 组件接口合同
每个公开组件必须显式声明:
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中图形、布局、分组不定义物理方程;但role="amesimGasMediumDefinition"已用于前端及 XML 介质引用检查。网络构造还依据AmesimGasMediumDefinitionComponent的继承关系识别介质定义,不能只加 role 就得到介质能力。
物理流变量统一以进入组件为正。物理连接的两个端点无方向;信号方向由注册端口的
output/input 合同决定。
4. 组件目录接口
GET /api/components/catalog 返回组件库、分类和模型合同。响应顶层必须为:
{
"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 求解输入。根元素固定使用:
<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 | 经 Pydantic 存储结构检查的原始 JSON;不保证可执行或可被浏览器导入 |
POST /api/reactflow/projects/{id} |
ReactFlowProjectPayload |
保存摘要 |
POST /api/reactflow/system-xml |
ReactFlowProjectPayload |
application/xml,System XML v3 |
POST /api/reactflow/compile-model |
ReactFlowProjectPayload |
网络结构 JSON;不生成或编译 C |
POST /api/system-xml/validate |
原始 XML v3 | 三层校验报告 |
POST /api/system-xml/parse |
原始 XML v3 | 规范化执行模型 |
POST /api/system-xml/compile-model |
原始 XML v3 | 校验报告、设置和网络;不生成或编译 C |
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 和合同测试
仍是必要依据。
6.1 工程存储与执行入口
ReactFlowProjectPayload 顶层禁止未知字段,节点 data 和边 data 保留额外编辑元数据。存储不等同于执行校验:可保留缺失/不同的组件版本供查看。浏览器要求有效布局、端口对象与 data.isContactEdge;信号端口 positiveFlowDirection: null 仍应省略,这部分精简规则未改。
工程 JSON v2:参数数值、十进制数字字符串、数学表达式,全部按 parameterUnits[name] 指定的单位解释;缺省使用目录 SI 单位。缺失参数采用目录 SI 默认值,不随显示单位二次换算。例如单位选 bar 时,2.5、"2.5"、"=2.5"、"2+0.5" 均得到 250000 Pa。温度使用仿射换算,20 degC = 293.15 K;压力是绝压,不添加大气压偏移。
旧工程 JSON v1:为保持已有模型物理输入不变,普通数值/十进制数字字符串仍按 SI,表达式按显示单位解释。不可只把版本号 1 改成 2。浏览器兼容读取后提示旧规则,手工导出时将 SI 数字转换回所选单位,写出 v2。若某参数经过显示单位往返会改变浮点末位,则该参数改用 SI 单位导出并提示,保持求解输入逐值精确不变。编辑器内存、浏览器草稿/本地保存和结果快照继续使用内部 v1/SI 数字表示,不是新的外部 JSON v2。无法转换的未知组件/参数草稿保留 v1 和原版本,发出警告供修复,不丢字段。
| 入口 | 输入处理 | 数值执行边界 |
|---|---|---|
| 网页参数面板与 JSON v2 | 数值与表达式均使用所选单位;导出 XML 前求值 | 完整、有限 SI 数值和当前模型版本 |
| HTTP JSON→XML / compile-model | prepare_project() 共享表达式解析和单位换算,返回版本警告 |
严格数值化后调用原 XML/网络构造器 |
| 原生 CLI JSON 输入 | 与 HTTP 复用 prepare_project(),警告写入 stderr |
同上;XML 输入仍不允许表达式 |
| XML / 内部数值构造器 / C | 不接收显示单位或表达式;数字字符串也应在输入适配层转为数字 | 仅有限 SI 数值;版本与端口/参数合同严格校验 |
语法统一为有界算术 + - * / ^ **、括号、科学计数法、常量 pi/e(不区分大小写)及函数 sqrt abs sin cos tan asin acos atan exp ln log log10 min max pow。幂右结合,-2^2=-4;ln/log 均是自然对数。最多 512 字符、256 词元/运算、32 层嵌套、16 个函数参数;禁止代码执行、未知变量、除零和非有限结果。离散编辑器参数只允许合法数值选项,不接受表达式。仿真时间设置同样可输入表达式,单位固定 s。
组件版本检查使用当前目录内存索引,导入时集中提示;运行/生成 XML 时再次警告,单纯版本不同或缺失不阻止执行。组件缺失、类型冲突、端口不兼容、未知参数、非法数值仍阻止执行。浏览器导出 JSON 时,只有通过组件兼容与参数校验的节点更新为当前版本;未通过者保留原版本。该过程不是旧方程的复现,也不能证明物理语义兼容,警告须明确可能失败或结果与实际不符。
HTTP XML 导出在 X-Component-Version-Warnings 返回 URL 编码 JSON(代码、说明、总数、最多前 10 个组件,头部限制 3800 字节);compile-model 在响应 warnings 中返回完整清单。没有版本差异时无需该响应头。
参数单位换算表唯一来源为 schemas/parameter-units.json,网页和 Python 共用;表达式语法用跨语言同一组用例验收。
6.2 流式结果、保存与 CSV
C 程序把结果写为 JSON。数值数组使用 Ryu 的 binary64 往返编码,结合缓冲写出;流式路径附带字节索引,Python 读取较小元数据并直接拼接 series 字节,避免将全部曲线转成 Python 浮点列表再编码。HTTP 数据仍是普通 JSON 数组,没有改成二进制数组协议。
simulate-stream 的心跳是带 heartbeat: true 的 event="progress",队列无消息时约每 5 秒发送;最终事件为 result 或 error。一个 NDJSON 事件可能分成多段字节 yield,消费者须按换行组装,不能按 HTTP chunk 一段一对象处理。同步 /simulate 默认仍物化完整曲线;任务 GET 遇到保留的原生 series 会以分段 JSON 返回,外部对象结构相同。
正式网页在接收和解析后将结果交给界面,resultPersistence.ts 再异步把曲线打包为 Float64Array 写入 IndexedDB,事务完成后才发布 sessionStorage 指针。因此“结果可查看”“浏览器持久化完成”和“下载文件保存”是不同事件。.simresult 仍通过 JSON 编码保存;不能把数值往返精度等同于所有导出文本逐字节一致。
网页 CSV 由 resultCsvExport.ts 向 Web Worker 分块传输数据并生成 Blob,默认不调用仍保留的 /api/simulation-results/csv。列顺序来自结果元数据,数值使用原始 SI,与图表显示单位分开;后端 CSV 接口为另一个可用入口。普通网页只能知道已生成 Blob/触发下载,无法通用地确认操作系统已将文件落盘,自动化测量需要额外下载完成信号。
6.3 任务生命周期
流式接口接受可选 X-Simulation-Id,省略时生成 ID,并在响应头返回。状态、取消标志与最终结果保存在当前 Python 进程内存中;服务重启即丢失,不是持久任务队列。终态任务超过 600 秒后,在注册新任务时清理,不是精确到时删除。取消 reason 为 user/stalled,断开事件流会请求 stalled 取消。
原生执行默认超时 300 秒;C 可返回部分结果,进程超过时限再加 5 秒,或收到取消后 5 秒仍未退出,Python 才强制结束并报错。不能把所有取消都承诺为立即终止且一定有完整结果文件。
7. 数据命名、单位和错误
- XML 属性和目录 JSON 主要使用
camelCase; - ReactFlow 仿真设置保留现有
t_start/t_stop/step/max_step名称; - 不允许调用方自行猜测或转换字段命名;
- XML 和求解参数统一使用 SI 基准值;
- 实例 ID 和机器标识必须稳定,显示名称不能代替机器标识。
System XML 校验问题统一包含:
{
"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 接受 v1/v2,导出使用 v2 的统一单位规则。输入适配层允许版本警告后选择当前模型,内部执行 XML 仍精确匹配。LMECHN1/FORC 的既有显式迁移由网页和 Python 输入层对齐;PNVO 的布局兼容留在网页。不得把一般版本提示解释为自动保留旧模型的物理语义。
工程结构解析先于目录恢复。当前信号端口的 positiveFlowDirection 应缺省,不能从目录复制 null;连线须有 data.isContactEdge 布尔字段。后端请求模型接受的数据不一定通过前端 parseProjectPayload(),应使用实际浏览器导出的结构并验证往返,见目录与工程协议。旧 XML v1/v2 不属于上述型号专用处理的范围。
MECMAS21 的 useFriction、strib 等 AMESim 选项统一使用目录声明的原生编码:
1 表示“否/禁用”,2 表示“是/启用”。工程 JSON v1/v2、组件目录、System XML v3
和模型构造器不再接受或自动换算旧的 0/1 编码,也不再使用
amesimParameterEncodingVersion 触发猜测式转换。
10. 接口修改完成条件
任何接口合同变更至少应同时完成:
- 更新唯一事实来源;
- 根据兼容性决定是否提高对应版本;
- 更新机器可读 Schema;
- 更新当前规范和示例;
- 增加请求、响应、拒绝边界和前后端联调测试;
- 明确说明未实现的兼容或迁移能力。
2026-09-12 / 1.2.0 修订
实现工程组件版本警告、外部 JSON v2 一致单位语义、网页/HTTP/CLI 表达式归一化;XML v3、数值内核模型版本与求解精度未改变。验收记录见 docs/other/2026-09-12-project-contract-acceptance.md。