liuyun ed9af5337d
Some checks are pending
CI / backend (push) Waiting to run
CI / frontend (push) Waiting to run
docs(spec): 归档 tenant-brand + 同步租户品牌主 spec
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 22:33:21 +08:00

6.3 KiB
Raw Permalink Blame History

Data Model Specification

Purpose

定义系统数据模型的字段字典:实体目录、公共字段、枚举、状态机与命名约定,作为前后端字段一致性的唯一锚点。

Requirements

Requirement: 业务实体公共字段

所有业务软删实体 SHALL 携带公共字段:id(UUID v7)、tenant_code、created_at、created_by、updated_at、deleted_at;日志/会话类实体不携带 deleted_at。

Scenario: 创建记录

  • WHEN 创建任一业务实体记录
  • THEN 系统自动填充 id、tenant_code、created_at、created_by

Scenario: 软删

  • WHEN 删除业务实体
  • THEN 系统置 deleted_at 而非物理删除

Requirement: 实体目录

系统 SHALL 包含实体 tenant、user、role、resource、org、dict_type、dict_item、config、audit_log、login_log、refresh_token、notice,以及关联表 user_role、role_resource、role_org、notice_read。

Scenario: 字典拆分

  • WHEN 维护数据字典
  • THEN 字典分为 dict_type(类型)与 dict_item(项)两类,经 dict_type_code 关联

Requirement: 通知实体

系统 SHALL 包含 notice 实体(公告/通知:id、tenant_code、title、content、status、created_by、created_at、deleted_at)与 notice_read 关联表(notice_id + user_id + read_at,唯一 tenant_code+notice_id+user_id),用于站内通知与已读追踪。

Scenario: 发布通知

  • WHEN 管理员发布一条通知
  • THEN 写入 notice,status=enabled 时对本租户所有用户可见

Scenario: 记录已读

  • WHEN 用户阅读某通知
  • THEN 写入 notice_read 记录其 read_at

Requirement: 租户品牌字段

tenant 实体 SHALL 新增可空品牌字段:brand_name(品牌显示名)、logo_url(Logo 地址)、theme_color(主色,如 #2E7FA3)、copyright(版权文案);为空时前端回退默认值或 name。

Scenario: 租户配置品牌

  • WHEN 管理员为租户填写品牌名/Logo/主色/版权
  • THEN 存入 tenant 对应字段,登录该租户后前端按此渲染

Requirement: 资源类型与代码

resource 实体 SHALL 通过 type 字段区分菜单(menu)、按钮(button)、接口(api)三种类型;「目录」由菜单节点是否拥有菜单子节点推导,不设独立类型。每个 resource SHALL 拥有租户内唯一的 code,作为关联键与权限标识。

Scenario: 按钮鉴权点

  • WHEN 前端需要按钮级权限
  • THEN 该按钮登记为 type=button 的资源,并携带 code 权限标识

Requirement: 引用键约定

所有跨实体引用 SHALL 优先使用业务键:角色、资源、组织、字典类型、租户用 code,树的父引用用 parent_code;对用户的引用 SHALL 使用用户 id。关联表 sys_user_role、sys_role_resource、sys_role_org 分别保存 user_id+role_code、role_code+resource_code、role_code+org_code;其余引用(user.org_code、dict_item.dict_type_code、resource.parent_code、org.parent_code)同理。

Scenario: 为角色分配资源

  • WHEN 管理员为角色分配资源
  • THEN 关联记录保存 role_code 与 resource_code

Requirement: 数据权限档位

role 实体 SHALL 通过 data_scope 字段支持全部/本部门/本部门及以下/本人/自定义五档;「自定义」经 role_org 关联表声明可见部门。

Scenario: 本部门及以下

  • WHEN 角色数据权限为「本部门及以下」
  • THEN 该角色用户仅可见本部门及下级部门的数据

Requirement: 命名与表前缀

所有脚手架表 SHALL 以 sys_ 前缀命名,数据库列名采用 snake_case。

Scenario: 表命名

  • WHEN 新建脚手架表
  • THEN 表名以 sys_ 开头,列名使用 snake_case

Requirement: 用户状态机

user 实体 SHALL 通过 status 字段支持启用/停用(管理员手动启停),并通过独立的 locked_at(锁定时间,可空)与 lock_reason(锁定原因,可空)表示安全锁定;「锁定」由 locked_at 非空推导,status 仅存 enabled/disabled。停用或锁定的用户 SHALL 均无法登录。

Scenario: 锁定登录

  • WHEN 锁定用户(locked_at 非空)尝试登录
  • THEN 系统拒绝登录并提示账号已锁定

Scenario: 停用登录

  • WHEN 停用用户(status=disabled)尝试登录
  • THEN 系统拒绝登录并提示账号已停用

Requirement: 待改密标记

user 实体 SHALL 通过 must_change_password(布尔,默认 false)标记待改密状态:管理员重置密码、租户初始化下发随机密码、创建用户(默认)时置 true;创建用户时管理员可显式关闭;用户自行改密成功后置 false。

Scenario: 临时密码置标记

  • WHEN 管理员重置密码或初始化租户下发临时密码
  • THEN 该用户 must_change_password 为 true

Scenario: 创建用户默认强制改密

  • WHEN 管理员创建用户(未显式关闭「首登强制改密」)
  • THEN 该用户 must_change_password 为 true;显式关闭则为 false

Scenario: 改密清除标记

  • WHEN 用户修改本人密码成功
  • THEN 该用户 must_change_password 置为 false

Requirement: 字典实体扩展

dict_type 实体 SHALL 新增 built_in 字段(布尔,标记内置字典类型);dict_item 实体 SHALL 新增 built_in(布尔,标记内置字典项)与 color_type(字符串,取值 primary/success/warning/danger/info,可空)字段,用于前端标签渲染与内置保护。

Scenario: 内置类型标记

  • WHEN 某字典类型由系统 seed 预置
  • THEN 其 built_in 为真,后端据此保护其不被删除

Scenario: 内置项颜色

  • WHEN 内置字典项需要区分展示
  • THEN 其 color_type 指定标签色(如启用=success、锁定=danger、停用=info)

Requirement: 内置枚举字典取值

系统 SHALL 预置 5 个内置枚举字典并锚定其取值集合:common_status={enabled,disabled}、user_status={enabled,disabled,locked}、resource_type={menu,button,api}、data_scope={all,dept,dept_and_child,self,custom}、login_status={success,fail}。

Scenario: 前端按字典渲染枚举

  • WHEN 前端渲染用户/角色/资源等页面的枚举字段
  • THEN 从对应内置字典读取 label 与 color_type,取值不脱离上述集合