Describe REST contracts, validation, routing, and I4 sync checklist aligned with V4 schema and parallel iteration index. Made-with: Cursor
14 KiB
迭代 I4 设计说明 — M3 交付批次与清单、M4 许可 SN 台账
迭代定位:与 并行迭代索引 中 I4 一致 — 平台后端 M3 交付 + M4 SN 录入/绑定/状态/手工回写;前端 交付页 + SN 页;本仓库(SDK 工作区)以 OpenAPI 契约与文档口径 与 BP-10 对齐。
分支:develop。
已有实现锚点(勿从零重设计,仅对齐与补全):FlywayV4__delivery_batch_and_license_sn.sql;cn.craftlabs.platform.api.domain.DeliveryBatchStatus/LicenseSnStatus;web/dto下Delivery*、LicenseSn*;审计常量AuditEntityTypes、AuditActions已含DELIVERY_BATCH、LICENSE_SN及对应动作。
1. I4 范围与 I3 / I5 边界
1.1 I4 纳入(本迭代 DoD)
| 域 | 说明 |
|---|---|
| M3 P0 | 交付批次(项目/可选合同、批次号、计划日、备注);交付清单行(描述、数量、可选合同行关联);批次状态 PENDING → DELIVERED / CANCELLED 及完成时间等侧写。对应产品:M3-F01~F05 P0。 |
| M4 P0 | SN 台账:全局唯一 sn_code;project_id 与/或 contract_line_id 绑定路径;生命周期状态子集;激活备注/手工回写字段。对应产品:M4-F01~F05 P0。 |
| M10-F01 | 交付批次、交付行、SN 的关键变更与状态迁移写入审计(与 I3 合同审计模式一致;实体类型见 §4)。 |
| 跨轨口径 | I4 末同步点:SN 绑定与「孤儿 SN」规则文档化并三轨对齐;交付门禁(M3-F07)与「孤儿 SN」强校验(M4-F02) 在 M11-F20 系统参数 中预留为 未来可配置项(I4 可实现默认策略 + 配置占位,不阻塞 I4 闭环)。 |
1.2 I3 留给上游的契约(I4 只消费,不重复建设)
- 合同 / 合同行:
project_id、contract_id、行项主键;合同状态机已在 I3 冻结。交付行上的contract_line_id必须解析到合法合同行及其所属项目。 - 客户 / 项目:批次必填
project_id;可选contract_id须属于同一项目。
1.3 I5 明确不纳入 I4(避免范围蔓延)
- M5 Callback Inbox、M6 集成配置 的持久化与页面(I5 起)。
- Webhook 生产级 投递、幂等落库与平台 Inbox 全链路 E2E。
- 设备(M7)、比特控制台摘要链接(M4-F06) 等可后续挂接;I4 仅保证 SN 主数据与绑定字段可关联到合同行/项目。
2. 数据模型锚点(与迁移一致)
表与字段以 services/delivery-platform-api/src/main/resources/db/migration/V4__delivery_batch_and_license_sn.sql 为准:
platform_delivery_batch:project_id(必填)、contract_id(可选)、batch_code(唯一)、planned_delivery_date、status(默认PENDING)、finished_at、remarks。platform_delivery_line:归属batch_id,description、quantity、contract_line_id(可选),sort_order。platform_license_sn:sn_code(全局唯一)、project_id/contract_line_id(均可空于 DB 层,业务校验见 §4)、status(默认REGISTERED)、activation_remark。
2.1 状态枚举(API JSON 使用枚举名字符串)
交付批次 DeliveryBatchStatus:
| 值 | 说明 |
|---|---|
PENDING |
未交付(默认) |
DELIVERED |
已交付 |
CANCELLED |
已取消 |
许可 SN LicenseSnStatus(P0 子集,与代码枚举一致):
| 值 | 说明 |
|---|---|
REGISTERED |
已登记 |
ISSUED |
已发放 |
ACTIVATED |
已激活 |
SUSPENDED |
已冻结 |
REVOKED |
已回收 |
非法状态迁移返回 409,错误码建议与合同类似:DELIVERY_BATCH_ILLEGAL_STATUS、LICENSE_SN_ILLEGAL_STATUS(具体以 OpenAPI 与实现为准)。
3. REST API 提案(前缀 /api/v1)
与现有 Controller 风格一致:@RequestMapping("/api/v1/...")。下列路径为 I4 计划形态;JSON 字段名与当前 DTO camelCase 对齐(projectId、contractId、batchCode 等)。
3.1 交付批次 delivery-batches
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/v1/delivery-batches |
分页列表;查询参数建议:projectId、contractId、status、keyword(批次号)、page、size。 |
POST |
/api/v1/delivery-batches |
创建批次(体见下);不含行时可后续用行接口追加。 |
GET |
/api/v1/delivery-batches/{id} |
详情;可通过 ?includeLines=true 或默认嵌套返回 lines(与 DeliveryBatchResponse 一致)。 |
PUT |
/api/v1/delivery-batches/{id} |
更新计划交付日、备注等非状态字段(DeliveryBatchUpdateRequest)。 |
PATCH |
/api/v1/delivery-batches/{id}/status |
仅变更状态:PENDING → DELIVERED 或 CANCELLED;服务端可在此写入 finishedAt(如 DELIVERED)。 |
嵌套 — 交付行 lines
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/v1/delivery-batches/{batchId}/lines |
清单列表。 |
POST |
/api/v1/delivery-batches/{batchId}/lines |
新增一行。 |
PUT |
/api/v1/delivery-batches/{batchId}/lines/{lineId} |
更新行。 |
DELETE |
/api/v1/delivery-batches/{batchId}/lines/{lineId} |
删除行。 |
创建批次请求体示例
{
"projectId": 1001,
"contractId": 2002,
"batchCode": "DLV-2026-0001",
"plannedDeliveryDate": "2026-04-15",
"remarks": "首批现场交付"
}
更新批次请求体示例(PUT /api/v1/delivery-batches/{id})
{
"plannedDeliveryDate": "2026-04-20",
"remarks": "延期一周"
}
状态 PATCH 示例(PATCH /api/v1/delivery-batches/{id}/status)
{
"status": "DELIVERED"
}
交付行写入示例(POST / PUT body,DeliveryLineRequest)
{
"sortOrder": 1,
"description": "AI 推理节点 × 生产环境",
"quantity": 2,
"contractLineId": 3003
}
详情响应片段(DeliveryBatchResponse,含行)
{
"id": 1,
"projectId": 1001,
"contractId": 2002,
"batchCode": "DLV-2026-0001",
"plannedDeliveryDate": "2026-04-15",
"status": "PENDING",
"finishedAt": null,
"remarks": "首批现场交付",
"createdAt": "2026-04-06T08:00:00Z",
"updatedAt": "2026-04-06T08:00:00Z",
"lines": [
{
"id": 10,
"batchId": 1,
"sortOrder": 1,
"description": "AI 推理节点 × 生产环境",
"quantity": 2,
"contractLineId": 3003,
"createdAt": "2026-04-06T08:05:00Z",
"updatedAt": "2026-04-06T08:05:00Z"
}
]
}
3.2 许可 SN license-sns
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/v1/license-sns |
分页列表;建议查询:projectId、contractLineId、status、snCode(精确或前缀按产品定)。 |
POST |
/api/v1/license-sns |
创建 SN(LicenseSnCreateRequest);须满足 §4 绑定规则。 |
GET |
/api/v1/license-sns/{id} |
详情。 |
PUT |
/api/v1/license-sns/{id} |
全量/部分更新绑定字段:projectId、contractLineId、activationRemark(LicenseSnUpdateRequest);用于纠正绑定或手工回写备注。 |
PATCH |
/api/v1/license-sns/{id}/status |
变更 LicenseSnStatus(LicenseSnStatusPatchRequest);须校验合法迁移。 |
创建 SN 请求体示例
{
"snCode": "SN-CRAFT-8F3A-0001",
"projectId": 1001,
"contractLineId": 3003,
"activationRemark": null
}
更新绑定 / 备注示例(PUT)
{
"projectId": 1001,
"contractLineId": 3003,
"activationRemark": "客户现场激活成功,凭证号 xxx"
}
状态 PATCH 示例
{
"status": "ACTIVATED"
}
详情响应示例(LicenseSnResponse)
{
"id": 501,
"snCode": "SN-CRAFT-8F3A-0001",
"projectId": 1001,
"contractLineId": 3003,
"status": "ACTIVATED",
"activationRemark": "客户现场激活成功,凭证号 xxx",
"createdAt": "2026-04-06T09:00:00Z",
"updatedAt": "2026-04-06T10:00:00Z"
}
4. 校验规则与审计
4.1 交付批次
projectId:必填;项目须存在。contractId:可选;若提供,合同须存在且contract.project_id == batch.project_id。batchCode:全平台唯一(与表uq_platform_delivery_batch_code一致);冲突 409。- 状态:仅允许自
PENDING转至DELIVERED或CANCELLED;DELIVERED/CANCELLED视为终态,禁止再次变更(除非产品后续另定「重开」流程,不在 I4 P0)。
4.2 交付行
contractLineId:可选;若提供,合同行须存在,且其所属合同的project_id须与父批次project_id一致(从而与批次可选contract_id兼容:若批次已指定合同,可额外校验行所属合同与批次合同一致,建议 强一致:行上合同行必须属于batch.contract_id当contract_id非空时)。quantity:> 0(与DeliveryLineRequest中@DecimalMin一致)。
4.3 许可 SN
snCode:必填;全局唯一;冲突 409。- 绑定路径:至少具备
projectId或contractLineId之一(可同时具备)。- 若仅提供
contractLineId:服务端派生project_id= 该合同行所属合同的project_id,并持久化(便于列表按项目过滤)。 - 若同时提供两者:须校验
contractLine派生出的project_id与请求projectId一致,否则 400。
- 若仅提供
- 孤儿 SN(与 I4 末同步对齐):
- 产品理想态(M4-F02):禁止无项目且无合同行路径的「裸 SN」。
- M11-F20(P1):「孤儿 SN」强校验开关、交付门禁(M3-F07,例如仅已交付范围可发放/绑定)作为系统参数在架构上预留;I4 建议 默认策略:创建/更新时 拒绝 零绑定(与 P0 一致);若需「先录入后绑定」,可通过 配置 降级为 警告 + 允许保存(实现可放在应用服务层读取参数表,表结构可 Mid 再做,I4 先在文档与 OpenAPI
description中固定语义)。
- 状态迁移:按 §2.1 枚举定义允许边(细表可在实现中维护;禁止随意跳转到任意状态)。
4.4 审计(M10-F01)
沿用 I3 模式:实体类型 + 动作 + 旧值/新值摘要 + 操作者 + 时间。常量已存在于:
AuditEntityTypes.DELIVERY_BATCH、AuditEntityTypes.LICENSE_SNAuditActions:DELIVERY_BATCH_CREATED/UPDATED/STATUS_CHANGED;DELIVERY_LINE_ADDED/UPDATED/DELETED;LICENSE_SN_CREATED/UPDATED/STATUS_CHANGED
若持久化审计行需扩展子类型或 payload 结构,保持与合同审计同一表结构,仅扩展 entity_type / action 枚举值;无需为 I4 另起实体类型常量,除非后续拆分「交付行」为独立可检索实体(当前可用 DELIVERY_LINE_* 动作挂 entity_id = line id,batch_id 放上下文 JSON)。
5. 前端路由(Vue 3,布局子路由)
与 轨道 B — I4 一致,路径挂在 AppLayout 之下(懒加载、meta.title / 权限码略)。
| 路由 | 页面职责 |
|---|---|
/deliveries |
交付批次列表、筛选、跳转新建/详情。 |
/deliveries/new |
新建批次(项目/可选合同、批次号、计划日、备注);可内嵌或分步添加行。 |
/deliveries/:id |
批次详情:行清单 CRUD;状态按钮 调用 PATCH .../status(PENDING → DELIVERED/CANCELLED)。 |
/licenses/sn |
SN 台账列表;孤儿 SN 列表筛选或醒目标记(与后端配置/字段一致)。 |
/licenses/sn/new |
新建 SN(录入 snCode、绑定项目/合同行)。 |
/licenses/sn/:id |
SN 详情:PUT 调整绑定与 activationRemark;PATCH 调整状态;展示简要时间线(可仅读审计或本地状态历史 Mid 增强)。 |
契约顺序提醒(轨道 B §4):Auth → Customer/Project → Contract → Delivery/SN → Callback;I4 页面依赖 I2/I3 主数据与合同行选择器。
6. I4 末同步点 Checklist(后端 + 前端 + SDK 文档)
以下为 并行索引 I4 末 的落地核对项。
6.1 后端(platform-api)
- Flyway V4 表与索引已在各环境应用;DTO 与 OpenAPI 字段一致。
- §3 路径已实现或通过兼容别名暴露;错误码与 409 语义与合同模块一致。
- §4.1~§4.3 校验全覆盖(含合同行与项目一致性、SN 全局唯一、绑定派生)。
- 孤儿 SN:默认策略与(可选)M11-F20 配置占位行为文档化并在代码注释或配置类中可定位。
- 交付门禁(M3-F07):与 SN 创建/绑定相关的规则在代码中可插拔或明确「I4 硬编码默认 + I5+ 读配置」的 TODO 与 Owner。
- 审计:
DELIVERY_BATCH/LICENSE_SN/ 交付行动作写入 M10-F01 存储。 contracts/openapi/delivery-platform-api.json更新并通过OpenApiContractSnapshotTest。
6.2 前端(delivery-platform-ui)
- §5 路由与菜单可达;RBAC 权限码与后端对齐。
- 交付详情状态操作仅展示合法迁移;错误态与 409 提示一致。
- SN 新建/编辑:合同行选择器与项目联动;孤儿场景 UI 与后端策略一致(禁止或警告)。
- E2E P0:
交付 → SN 录入/绑定 → 状态/备注回写(与轨道 B I4 DoD 一致)。
6.3 客户端 SDK 工作区(本仓库)
- OpenAPI 快照与 contracts/README.md 说明含 Delivery/SN 标签。
- tracks/03-client-sdk.md 或等价文档中 BP-10 与平台对象口径 补充:交付批次、SN 在集成叙事中的位置(不实现平台 REST 客户端亦可,但文档须与 I4 契约一致)。
- M11-F20:在 SDK/集成文档中标注为 后续配置项(门禁、孤儿强校验),避免集成方误假设 I4 已暴露该 HTTP API。
7. 修订记录
| 日期 | 说明 |
|---|---|
| 2026-04-06 | 初版:I4 范围与边界、REST 提案、校验与审计、前端路由、I4 末三轨 checklist。 |