5.0 KiB
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 与 mustChangePassword(待改密标志)。
Scenario: 登录成功
- WHEN 用户提供正确的租户、账号与密码
- THEN 返回 access token(2h 过期)、refresh token(7d 过期)与 mustChangePassword(待改密为 true,否则 false)
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 用户被锁定或解锁
Requirement: 通知接口
系统 SHALL 提供:GET /notices(分页,管理)、POST /notices、PATCH /notices/:id、DELETE /notices/:id(管理,需 notice:* 权限);GET /notices/mine(当前用户可见通知 + 已读状态)、GET /notices/unread-count(未读数)、POST /notices/:id/read(标记已读)、POST /notices/read-all(全部已读),后四者仅需登录态。
Scenario: 拉取未读数
- WHEN 用户请求 GET /notices/unread-count
- THEN 返回其未读通知数
Scenario: 标记已读
- WHEN 用户请求 POST /notices/:id/read
- THEN 该通知对当前用户标记为已读
Requirement: 租户品牌接口
系统 SHALL 提供 GET /auth/brand(仅登录态),返回当前租户品牌(name、brandName、logoUrl、themeColor、copyright);tenant 的新增/编辑/列表接口 SHALL 支持品牌字段。
Scenario: 拉取当前租户品牌
- WHEN 已登录用户请求 GET /auth/brand
- THEN 返回其所在租户的品牌字段(缺省为空)
Scenario: 维护租户品牌
- WHEN 管理员新增或编辑租户并填写品牌字段
- THEN 品牌字段随 tenant 一并保存与返回