Files
hepu/docs/contract/6_J-00_OpenAPI使用说明_V1.8.md
T
aomin a7605ef8b8 chore(repo): 导入 M-Z 业务底座 V1.9 基线并建立仓库规范
按周工交付的 SEC-Z-01 清理后源码建立 M-Z 主干,并按 Git 仓库惯例重排目录。

- aomin-gateway/  后端工程 87 文件,原样保留,路径与构建命令未变
- demo/           演示前端与设备模拟器 9 文件(原 02_前端与设备端),非正式三端
- docs/handover/  交付与安全清理材料 6 份,内容未改
- docs/contract/  J-00 规格、OpenAPI、内部五接口、状态机、Mock 样例
- docs/reference/ 指纹与校验清单,含 84 个源码文件的 sha256 清单

目录重排只动位置不动内容:源码树 84 文件哈希与交付一致,逐文件自校验通过;
12 条 Flyway 迁移与交付包内镜像逐字节一致。

未纳入:迁移镜像目录(与工程内一套重复,改留指纹)、target/、证据 raw、
应急恢复脚本、评审用虚构台账数据。

安全:SEC-Z-01 15 处明文已清零,导入前重新扫描无新增命中,本仓库无历史污染。
行尾按交付字节原样保存(.gitattributes 设 * -text),不做归一化以免整树摘要失效。
2026-11-13 17:32:37 +08:00

6.9 KiB
Raw Blame History

J-00 OpenAPI 机器可读版 · 使用说明

文件:6_J-00_接入接口规格_V1.8_OpenAPI.yaml(OpenAPI 3.0.3,v1.8.0)—— 与本说明放在同一目录,可直接用编辑器或 Swagger Editor 打开 对应:6_J-00_接入接口规格_V1.8.md(同一个契约的人读版) 编制:周工 | 2026-11-02

为什么文件名这么长:这是故意的。同一份契约有两个形态——.md 讲"为什么",.yaml 讲"长什么样"。两个文件共用 6_J-00_接入接口规格_V1.8 前缀,在文件夹里永远相邻,谁也漏不掉;仅仅一个叫 internal-iot.yaml 的文件,脱离上下文就没人知道它是 J-00 的机读版。


一、这是什么

一份机器可读的接口契约。内容和 J-00 V1.8 一一对应,只是换了一种能被工具直接消费的写法。

两份文件的分工,不要理解成两份契约:

管什么 举例
本文件(YAML) 长什么样 路径、方法、字段类型、必填、枚举、长度上限、错误结构
J-00 V1.8 为什么这样 告警状态机、四条硬边界、幂等三档算法、断档与 0x04、tsSource 为什么不能伪造

有些东西写不进 YAML,比如「deviceTime 没有就传 null,禁止用 receivedAt 顶替——填了等于伪造时源」。所以:字段定义以本文件为准,业务语义的解释权仍在 J-00。

两者不一致时,以本文件为准,同时回改 J-00,两边同版本号。


二、里面有什么

项 数量 说明
接口 6 在役 5 个(I-01/02/05/12/18)+ 二期预留 1 个(I-17)
schema 20 Event/DeviceStatus/RawFrame/Command/CommandResult 及其批次包装
公共参数 8 鉴权头 4 个 + 幂等键 4 个(每接口一个)
公共响应 4 400/401/429/500

五个在役接口:

编号 方法 路径 operationId
I-01 POST /events/batch ingestEvents
I-02 POST /device-status/batch ingestDeviceStatus
I-12 POST /raw-frames ingestRawFrames
I-18 GET /commands/pending pullPendingCommands
I-05 POST /commands/result reportCommandResults
I-17 POST /commands/{commandId}/dump 二期预留,本期固定 404,不要实现

枚举已全部写死,且与 J-00 逐值一致:

枚举 值数 内容
eventType 29 10 对发生/解除 + 9 个单值
sourceChannel 4 OWN_GW/HORN_HOST/HORN_CELL/MIR_CELL
result 5 ACKED/SENT/TIMEOUT/DEVICE_OFFLINE/FAILED
rejectReason 4 RATE_LIMITED/SCHEMA_INVALID/UNKNOWN_CHANNEL/SENSOR_ID_INVALID
cmdType 8 set_mode/set_ack_policy/time_sync/set_report_cfg/del_sensor/reboot/diag_dump/set_ota

三、能拿它做什么(五件事)

下表里的 $Y 指本文件名。因为它带中文和版本号,直接敲命令很累,下面给了变量写法,复制即用。

用途 怎么用 省了什么
接口校验 用 swagger-cli validate 或编辑器插件跑一遍 字段漏写、枚举越界当场暴露,不用等联调
生成服务端骨架 openapi-generator-cli generate -i "$Y" -g spring 五个 Controller 的入参出参自动生成,外包只填业务
生成前端类型 -g typescript-fetch 或 typescript-axios 陈工不用照表格手敲 TS 类型
起 Mock 服务 prism mock "$Y" 前端不用等后端就能联调
生成测试用例 -g jmeter 或 schemathesis run 必填、枚举、边界自动出用例,比手写清单全

推荐的命令(外包侧):

# 文件名太长,先存成变量,后面照抄即可
Y="6_J-00_接入接口规格_V1.8_OpenAPI.yaml"

# 1. 语法与规范校验
npx @redocly/cli lint "$Y"

# 2. 生成 Spring Boot 服务端接口骨架
npx @openapitools/openapi-generator-cli generate \
  -i "$Y" -g spring \
  -o ./generated --additional-properties=interfaceOnly=true

# 3. 起 Mock 服务(前端联调用)
npx @stoplight/prism-cli mock "$Y" -p 4010

四、与 J-00 V1.8 的逐项核对

已用脚本比对,以下全部一致:

项 J-00 位置 YAML 位置
五个接口的编号与路径 §1.1 paths
eventType 29 值 §1.5.1 schemas.EventType.enum
事件对象 12 个字段与必填性 §1.3 schemas.Event
I-02 十个字段 §1.8 schemas.DeviceStatus
I-12 八个字段(含 rawFrame 定死 Base64) §1.9.2 schemas.RawFrame
result 5 值 §3.3 schemas.CommandResult.result
I-18 四个查询参数与上限 §3.2 paths./commands/pending.parameters
鉴权四层 + 幂等键算法 §1.2 components.parameters(每个接口的幂等键分别写,因为取法不同)
响应结构与 unregistered 非错误语义 §1.7 schemas.IngestResponse

幂等键按接口分开写,这是 V1.6 的重点修正:

接口 幂等键 为什么不能统一
I-01 {sourceChannel}-{首条 eventId}-{条数} 有 eventId
I-02 {sourceChannel}-{首条 sensorId}-{reportedAt}-{条数} I-02 报文里没有 eventId
I-12 {sourceChannel}-{首条 rawRef}-{条数} I-12 报文里没有 eventId,rawRef 就是 MD5(原始帧字节)
I-05 {nodeId}-{首条 commandId}-{条数} 有 commandId
I-18 不带 GET 拉取,重复拉天然幂等,靠租约去重

五、已知未定项(不藏着)

项 现状 何时定
错误响应里的 code 具体码值 只写了 {code, message} 结构,没固定码值 待与业务层错误码表统一后回填。当前按 HTTP 段理解:400xx 请求非法/401xx 鉴权失败/429xx 限流
I-17 的请求体 只写了「本期 404」 二期启用诊断包时再补
params 的结构 additionalProperties: true,随 cmdType 变 八种命令字的参数结构不在本文件里,由业务层命令模块保证;外包按 cmdType 做编码即可

六、对陈工和外包各说一句

给陈工:这份 YAML 可以生成 TS 类型,openapi-generator -g typescript-fetch。你前端不用照 J-00 的表格手敲字段,也不用维护第二份接口定义——生成一次即可,接口变了重生成。

给外包(谢工):五个接口全在这里。各字段的 description 是给你的实现提示,重点是三处最容易做错的:

  1. I-02 / I-12 的幂等键不是 eventId(报文里没这个字段),按对应 components.parameters 的说明算。
  2. I-18 是 GET,签名时 sha256(body) 取空串的 hash,path 含 query 一并算。
  3. rejectedDetail 里出现的条目一律不重试,只有整批 5xx 才重试。