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

140 lines
6.8 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.
# RailwaySystem API 设计原则与规范
> **状态:** Phase 2 规范冻结 (Review Round 1 修订版)
> **适用范围:** 所有 Controller、API 契约、DTO/VO 及前端调用
---
## 1. 业务驱动与工作台优先原则
### 1.1 拒绝单表 CRUD 堆砌
本系统是面向铁路培训基地的**智慧培训业务系统**,不是 21 张数据库表的 CRUD 管理后台。严禁出现以下反模式:
```text
一张数据库表
→ 一个单表 Controller
→ 一个单表 Service
→ 一套单表 CRUD 页面
```
### 1.2 业务工作台与聚合驱动
业务人员在日常管理中是以“**开班计划**”为主线推进各阶段工作的。因此系统核心页面是以 **培训计划工作台 (Plan Workbench)** 为枢纽,通过聚合视图直观展示当前培训所处的阶段(筹备中、排课中、住宿分配中、报到中、培训进行中、已结束),并提供进入各业务动作的明确入口,而不是让用户在几十个左侧菜单栏来回跳转拼接数据。
---
## 2. Resource API 与 Command API 区分
为了保持 API 语义清晰,明确操作意图与事务边界,所有接口严格区分 **资源查询 (Resource API)** 与 **业务动作 (Command API)**。
### 2.1 资源型 API (Resource API)
- **定位:** 用于获取业务实体详情、列表、看板或特定维度的只读数据。
- **HTTP 动词:** 纯 `GET`。
- **特点:** 无副作用、幂等,不触发跨表业务状态跃迁。
- **示例:**
```text
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`) | **不分页** (全量返回) | 一个培训班课程通常为 3~10 门,成绩项为 3~6 项,数量可控 |
| **统计与看板** | 统计概览 (`/overview`)、房态看板 (`/occupancy-board`) | **不分页** (结构化聚合看板) | 服务端完成聚合计算,返回统计指标及图表数据结构 |
---
## 5. 响应体规范 (RuoYi 体系兼容)
系统全面兼容若依现有的 `AjaxResult` 和 `TableDataInfo` 标准,前端不需要额外定制拦截器:
### 5.1 单一实体 / 命令响应 / 聚合 VO
采用 `AjaxResult` 包装:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"planId": "PLAN202609001",
"planName": "沈阳局2026年第1期高速铁路综合培训班"
}
}
```
### 5.2 分页列表响应
采用若依标准 `TableDataInfo` 包装:
```json
{
"total": 45,
"rows": [
{ "enrollmentId": 1001, "studentName": "张三", "enrollmentStatus": 1 }
],
"code": 200,
"msg": "查询成功"
}
```
### 5.3 业务异常响应
发生业务校验失败时返回标准 HTTP 200 或业务错误码(如 500),由全局异常捕获器统一封装:
```json
{
"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 (依赖现场确认或非首轮必须):** 依赖现场硬件协议确认或面向学员端的次要门户接口,实现前需再次确认。