88 lines
3.7 KiB
Markdown
88 lines
3.7 KiB
Markdown
# API Contract Specification
|
||
|
||
## Purpose
|
||
|
||
定义所有接口的统一契约:响应封装、错误码、分页、鉴权层级与认证接口,作为前后端联调的唯一锚点。
|
||
|
||
## Requirements
|
||
|
||
### Requirement: 统一响应封装
|
||
所有接口 SHALL 返回 `{ code, message, data }` 结构;code=0 表示成功。
|
||
|
||
#### Scenario: 成功响应
|
||
- **WHEN** 接口处理成功
|
||
- **THEN** 返回 code=0、message=ok、data 为业务数据
|
||
|
||
#### Scenario: 失败响应
|
||
- **WHEN** 接口处理失败
|
||
- **THEN** 返回非 0 code 与可读 message,data 为空
|
||
|
||
### Requirement: 错误码分段
|
||
错误码 SHALL 与 HTTP 状态对齐分段:401xx 认证、403xx 授权、400xx 参数、404xx 资源、409xx 冲突、500xx 系统。
|
||
|
||
#### Scenario: 未登录
|
||
- **WHEN** 未携带有效 token 访问受保护接口
|
||
- **THEN** HTTP 401,code 为 401xx 段
|
||
|
||
### Requirement: 分页约定
|
||
列表接口 SHALL 使用 page/pageSize 分页,返回 `{ list, total, page, pageSize }`。
|
||
|
||
#### Scenario: 分页查询
|
||
- **WHEN** 客户端传 page=1&pageSize=20
|
||
- **THEN** 返回 data 含 list、total、page、pageSize
|
||
|
||
### Requirement: 三级鉴权
|
||
接口 SHALL 分为三级:公开接口无需 token;未登记接口仅需登录;登记为「接口」资源的接口需 token 且当前用户具备对应 code(权限标识)。
|
||
|
||
#### Scenario: 未登记接口
|
||
- **WHEN** 已登录用户访问未登记为资源的接口
|
||
- **THEN** 校验通过(仅需登录态)
|
||
|
||
#### Scenario: 登记接口越权
|
||
- **WHEN** 已登录用户访问登记为接口资源、但自身角色无该 permission 的接口
|
||
- **THEN** 系统返回 403
|
||
|
||
### Requirement: 认证接口
|
||
系统 SHALL 提供登录、刷新令牌、登出接口;登录需 tenantCode+username+password,返回 access token 与 refresh token。
|
||
|
||
#### Scenario: 登录成功
|
||
- **WHEN** 用户提供正确的租户、账号与密码
|
||
- **THEN** 返回 access token(2h 过期)与 refresh token(7d 过期)
|
||
|
||
#### Scenario: 刷新令牌
|
||
- **WHEN** access 过期后客户端携带 refresh token 请求刷新
|
||
- **THEN** 系统签发新 access 与 refresh,并作废旧 refresh
|
||
|
||
### Requirement: 核心域接口目录
|
||
系统 SHALL 为每个核心域提供 REST 资源接口(复数、kebab-case):/users、/roles、/resources、/orgs、/dict-types、/configs、/audit-logs、/login-logs、/sessions。
|
||
|
||
#### Scenario: 资源 CRUD
|
||
- **WHEN** 管理端操作某核心域
|
||
- **THEN** 通过对应复数资源路径进行增删改查
|
||
|
||
### Requirement: 字典聚合查询接口
|
||
系统 SHALL 提供 `GET /dicts` 接口,需登录态,按当前租户一次返回全部启用状态的字典类型及其启用状态的字典项(字典项按 sort 升序),供前端登录后缓存渲染。
|
||
|
||
#### Scenario: 一次性拉取
|
||
- **WHEN** 前端调用 GET /dicts
|
||
- **THEN** 返回全部启用字典类型,每个类型含其启用字典项(label/value/color_type/sort)
|
||
|
||
#### Scenario: 停用过滤
|
||
- **WHEN** 某字典类型或字典项被停用
|
||
- **THEN** GET /dicts 不返回该类型或该项
|
||
|
||
### Requirement: 会话与账号安全接口
|
||
系统 SHALL 提供以下接口:`GET /sessions`(分页查询活跃会话)、`POST /sessions/:sid/kick`(单会话强退)、`POST /users/:id/kick-sessions`(踢用户全部会话)、`POST /users/:id/lock`(锁定用户,body 可含 reason)、`POST /users/:id/unlock`(解锁用户)。
|
||
|
||
#### Scenario: 查询活跃会话
|
||
- **WHEN** 客户端请求 GET /sessions
|
||
- **THEN** 返回活跃会话分页数据(list/total/page/pageSize)
|
||
|
||
#### Scenario: 单会话强退
|
||
- **WHEN** 客户端请求 POST /sessions/:sid/kick
|
||
- **THEN** 该会话被强退
|
||
|
||
#### Scenario: 锁定与解锁
|
||
- **WHEN** 客户端请求 POST /users/:id/lock 或 /users/:id/unlock
|
||
- **THEN** 用户被锁定或解锁
|