Files
railwaysystem/docs/api-v2/01_api_design_principles.md
T

6.8 KiB
Raw Blame History

RailwaySystem API 设计原则与规范

状态: Phase 2 规范冻结 (Review Round 1 修订版) 适用范围: 所有 Controller、API 契约、DTO/VO 及前端调用


1. 业务驱动与工作台优先原则

1.1 拒绝单表 CRUD 堆砌

本系统是面向铁路培训基地的智慧培训业务系统,不是 21 张数据库表的 CRUD 管理后台。严禁出现以下反模式:

一张数据库表
→ 一个单表 Controller
→ 一个单表 Service
→ 一套单表 CRUD 页面

1.2 业务工作台与聚合驱动

业务人员在日常管理中是以“开班计划”为主线推进各阶段工作的。因此系统核心页面是以 培训计划工作台 (Plan Workbench) 为枢纽,通过聚合视图直观展示当前培训所处的阶段(筹备中、排课中、住宿分配中、报到中、培训进行中、已结束),并提供进入各业务动作的明确入口,而不是让用户在几十个左侧菜单栏来回跳转拼接数据。


2. Resource API 与 Command API 区分

为了保持 API 语义清晰,明确操作意图与事务边界,所有接口严格区分 资源查询 (Resource API) 与 业务动作 (Command API)。

2.1 资源型 API (Resource API)

  • 定位: 用于获取业务实体详情、列表、看板或特定维度的只读数据。
  • HTTP 动词: 纯 GET。
  • 特点: 无副作用、幂等,不触发跨表业务状态跃迁。
  • 示例:
    GET /train/plans/{planId}               // 获取计划详情
    GET /train/plans/{planId}/courses       // 查询计划本期课程列表
    GET /train/plans/{planId}/timetable     // 获取完整课程表
    GET /train/enrollments/{id}             // 查询参训档案详情
    GET /train/dormitory/occupancy-board    // 获取宿舍房态看板
    

2.2 命令型 API (Command API)

  • 定位: 用于驱动业务流程流转、触发状态机跃迁、执行跨表批量操作或外部协作。
  • HTTP 动词: 业务动作用名词或动宾短语结尾(如 /complete, /preallocate, /sign-in)。
  • 与普通 CRUD 更新的区分:
    • 普通的字段修改(如改教师电话、改教室容量)属于标准资源更新 (PUT /train/teacher/{id});
    • 真正业务 Command(如 POST /train/plans/{id}/complete, POST /train/plans/{id}/accommodations/preallocate, POST /train/attendance/sign-in)必须具有跨表状态推动语义,受严格事务保护与不变量拦截。

3. URL 命名与路径规范

  1. 统一前缀: 所有培训业务接口统一以 /train 开头,兼容 RuoYi 路由机制与安全过滤器。
  2. RESTful 资源层级: 遵循“父资源/ID/子资源”层级表达从属关系:
    • /train/plans/{planId}/courses
    • /train/plans/{planId}/lessons
    • /train/plans/{planId}/enrollments
  3. 领域主键显式声明: 路径变量统一使用数据库 V2 确立的领域 ID 名称:
    • {planId} (String, 32位)
    • {planCourseId} (Long)
    • {enrollmentId} (Long)
    • {lessonId} (Long)
    • {accommodationId} (Long)
    • {checkinId} (Long)
    • {scoreItemId} (Long)
  4. 禁止隐式复合参数替代主键: 严禁在 URL 或 RequestBody 中反复退化为 plan_id + student_id + c_id + time 查找记录。

4. 分页与列表控制规范

严禁前端通过 pageSize=99999 获取全量业务数据,必须严格划分分页接口与专用聚合接口:

分类 典型接口 控制策略 说明
常规主数据列表 教师、学员、公共课程库、教学资源、教室、场地、电子班牌 必须分页 (pageNum, pageSize) 默认 pageSize=10,最大允许 pageSize=100
大型业务流列表 培训计划列表、参训学员名单、课次列表、学习记录流水 必须分页 (pageNum, pageSize) 参训学员按计划筛选时分页呈现,提供按状态过滤
业务聚合视图 培训计划工作台 (/workbench)、完整课程表 (/timetable) 不分页 (专用聚合 VO 返回) 课程表按时间周期或开班全程以结构化日历网格返回
业务配置项 本期成绩项目配置 (/score-items)、本期课程清单 (/courses) 不分页 (全量返回) 一个培训班课程通常为 310 门,成绩项为 36 项,数量可控
统计与看板 统计概览 (/overview)、房态看板 (/occupancy-board) 不分页 (结构化聚合看板) 服务端完成聚合计算,返回统计指标及图表数据结构

5. 响应体规范 (RuoYi 体系兼容)

系统全面兼容若依现有的 AjaxResult 和 TableDataInfo 标准,前端不需要额外定制拦截器:

5.1 单一实体 / 命令响应 / 聚合 VO

采用 AjaxResult 包装:

{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "planId": "PLAN202609001",
    "planName": "沈阳局2026年第1期高速铁路综合培训班"
  }
}

5.2 分页列表响应

采用若依标准 TableDataInfo 包装:

{
  "total": 45,
  "rows": [
    { "enrollmentId": 1001, "studentName": "张三", "enrollmentStatus": 1 }
  ],
  "code": 200,
  "msg": "查询成功"
}

5.3 业务异常响应

发生业务校验失败时返回标准 HTTP 200 或业务错误码(如 500),由全局异常捕获器统一封装:

{
  "code": 40901,
  "msg": "排课冲突:王老师在该时段已有授课任务(安全理论基础 09:00-11:00)",
  "data": {
    "conflictType": "TEACHER",
    "conflictLessonId": 801
  }
}

6. 确定性标记与 API 优先级规范

6.1 需求确定性分级

  • 【确认】: PRD V1.0 与第二次项目会议纪要已明确冻结的业务需求与规则,不可随意擅改。
  • 【默认/建议方案(待现场确认)】: 设计层给出的标准工程实现方案,若现场验证后甲方有微调,可平滑变更。
  • 【待现场确认】: 明确属于 PRD V-01 ~ V-14 范围的事项(如及格线判定、学员画像标签、超期报到处理策略),API 契约保持高弹性,严禁硬编码。
  • 【扩展】: 一期不开发、仅在模型或契约层预留扩展兼容能力(如分布式事务、Kafka、Outbox模式、复杂证书体系),严禁过度设计。

6.2 API 优先级分级 (P0 / P1 / P2)

  • P0 (一期核心闭环必须实现): 支撑培训班从立项、选课、入班、排课、住宿、报到、上课打卡、打分、统计到结训的最小可用闭环接口。后续 Issue 拆分优先以此作为开发基线。
  • P1 (一期辅助管理能力): 在主链路畅通后实现的辅助运维、人工修正、主档维护与报表查询接口。
  • P2 (依赖现场确认或非首轮必须): 依赖现场硬件协议确认或面向学员端的次要门户接口,实现前需再次确认。