装备数字车间 · 权限治理与工作身份

权限与角色切换验收报告

按资料、产品原型、设计、开发、测试梳理本轮调整。页面与操作使用真实权限;管理员采用固定授权;内部维护与普通业务隔离;工作身份切换保护未保存内容。

日期 2026-09-06 · 生成时间 2026年9月6日 12:11:22(北京时间) · 证据来自当前报告目录
通过本轮记录的验收项已通过

真实接口、浏览器操作与构建/测试记录分别列示;测试覆盖范围和 OFD 本地入口边界仍需结合下文阅读。

真实 API · 权限主流程32 / 32接口断言,不计作浏览器用例
真实 API · 维护隔离边界39 / 39目录、审计、角色与写入保护
浏览器 E2E · 当前结果9 / 9已标记为最终完整运行
构建 / 单测 / DDL通过独立统计,详见验证记录

以旧系统实际能力为迁移边界

旧环境采用 SINGLE_ACTIVE。管理员曾动态获得全部叶子权限,但内容写又被教员身份门槛阻止;本轮把这种不一致改为明确的页面权限与操作权限。

旧角色旧授权数据范围迁移依据
管理员 · admin动态全部叶子权限ALL旧权限集合全选,但内容写仍被教员身份门槛阻止。
教员 · teacher33 项显式权限SYSTEM保留原有制作、教学能力;未获授予的资源管理不自动新增。
学员 · student14 项显式权限SELF保留本人或本人队组的学习与执行能力。

动作合同记录 87 个新增动作和 14 个停用共用动作码。旧角色仅按原已持有权限和所属页面展开,自定义角色不自动补齐其他业务能力。

保持入口,把“能查看”和“能操作”说明白

页面与工作区

三个登录身份入口保留。列表的新建、复制、删除、发布按各类内容权限显示;没有修改权限的三维工作区仍可查看,编辑、导入、自动保存和恢复写入受到控制。

管理员授权界面展示固定清单,不能在普通角色编辑中改动固定模板。勾选动作自动补齐所属页面;取消页面先确认依赖动作。

头像与个人中心

只列出当前账号已分配且有效的工作身份。单角色生效模式下,切换前确认各工作区未保存内容;成功后重新加载身份、菜单和页签。

切换请求失败保留原页面。切换已提交但新身份加载失败时,不继续使用旧身份业务缓存。

页面、动作、身份和数据范围分别约束

内容类型新建 / 复制编辑 / 上传 / 封面删除工程发布 / 撤回发布批准 / 驳回
模型content.model.createcontent.model.updatecontent.model.deletecontent.model.publish不新增审批功能
场景content.scene.createcontent.scene.updatecontent.scene.deletecontent.scene.publish不新增审批功能
训练编排content.training.createcontent.training.updatecontent.training.deletecontent.training.publish不新增审批功能
作业指导书content.ofd.createcontent.ofd.updatecontent.ofd.deletecontent.ofd.publishcontent.ofd.review

保存后发布需要修改与发布两项权限。只有发布权限时,提交已保存的服务端版本;OFD 还须复用与当前内容指纹一致的已保存交付物,缺失或过期时由编辑者处理。

迁移后角色默认保留能力明确边界
管理员固定普通管理授权、系统配置与既有教学/资源管理不自动拥有内容写、学员执行/提交或内部维护权限。
教员原有四类内容制作、教学管理与运行能力原无 manage 的资源/知识管理不因拆码获得 CRUD。
学员本人/本人队组的领取、执行、提交、指导书学习与反馈SELF 范围、参与人、队伍、岗位和正式考试投影继续生效。
内部维护受保护账号与有效内部角色共同确认后获得维护能力普通人员/角色目录隐藏;内部审计与业务审计分别读取。

任务中的教员、学员、观察员成员身份与平台角色名称解耦;成员身份不授予平台动作权限。业务参与范围、固定版本、乐观锁、发布前置条件继续由服务端校验。

实现范围与需要保留的边界

  • 内容四类动作、教学各渠道、资源管理真实操作分别授权;停用旧共用动作码,不设置永久兼容放行。
  • 模型同源宿主桥接、场景与训练运行时、正式工作台及 OFD 本地入口同步只读和操作门控;模型静态生成包未在本轮重做。
  • 所有工作区参与角色切换确认。场景加载或资源上传先阻止离开;已开始的截图上传、保存、发布等待完整结束再核查未保存状态。
  • 前一工作区选择放弃、后一工作区取消时仍保留草稿。角色接口成功后整页进入总览,新启动重新取身份和菜单,页签按用户与角色隔离。
  • 036 迁移固定管理员模板、细分已有角色能力并增加审计范围;维护凭据只经私有初始化流程设置,报告和 DDL 不包含凭据。
OFD 本地入口的边界

默认 OFD 原型仍使用本地存储。本轮接入真实会话和本地写权限保护,未将整个原型业务迁移至 API;不能将前端限制描述成完整服务端隔离、跨设备协作或新增审批功能。

真实接口、浏览器、构建与单测分别验收

A. 真实 API:权限配置与多角色主流程

通过 32 / 32 项通过 · JSON 证据

逐项检查结果
检查项目结果补充证据
root 使用管理员登录入口进入内部维护角色通过
普通角色目录不显示内部维护角色通过
管理员角色采用固定的受限授权通过
管理员授权已持久化,不动态获得全权限通过
admin 无法通过接口修改固定管理员授权通过
root 无法通过接口修改固定管理员授权通过
admin 账号已取消 is_protected通过
用户目录不显示 root 维护账号通过
普通账号按 ID 查询 root 受保护通过
普通账号按 ID 停用 root 受保护通过
普通账号按 ID 重置密码 root 受保护通过
普通账号按 ID 删除 root 受保护通过
管理员无法访问维护审计通过
普通审计不混入 root 登录与操作记录通过
root 活动保留在可追溯的内部审计通过
目录提供模型独立动作与查看依赖通过
已移除旧的共用内容写权限通过
创建可配置的reader测试角色通过
保存reader细分授权通过
创建可配置的editor测试角色通过
保存editor细分授权通过
建立隔离的多角色测试账号通过
多角色测试账号正常登录通过
接口切换到reader角色通过
reader当前身份独立生效通过
reader拥有模型查看权限通过
只有查看权限时,直接新建接口返回403通过
接口切换到editor角色通过
editor当前身份独立生效通过
editor拥有模型查看权限通过
自定义非教员角色获得新增权限即可创建模型通过
普通管理员模型查看与创建权限相互独立通过

B. 真实 API:内部维护与审计隔离边界

通过 39 / 39 项通过 · JSON 证据

逐项检查结果
检查项目结果补充证据
维护账号使用已分配的内部角色,普通管理员不带维护标记通过
admin 的普通角色目录和分页都隐藏内部角色通过
admin 不能按已知内部角色 ID 读取/详情通过HTTP 404
admin 不能按已知内部角色 ID 读取/users通过HTTP 404
admin 不能按已知内部角色 ID 读取/permissions通过HTTP 404
root 的普通角色目录和分页都隐藏内部角色通过
root 不能按已知内部角色 ID 读取/详情通过HTTP 404
root 不能按已知内部角色 ID 读取/users通过HTTP 404
root 不能按已知内部角色 ID 读取/permissions通过HTTP 404
角色 admin 的关联用户排除维护账号通过
角色 administrative 的关联用户排除维护账号通过
角色 teacher 的关联用户排除维护账号通过
角色 student 的关联用户排除维护账号通过
角色 group_leader 的关联用户排除维护账号通过
角色 rv_reader_1e43e04e 的关联用户排除维护账号通过
角色 rv_editor_1e43e04e 的关联用户排除维护账号通过
教学人员搜索不暴露维护账号通过
教学人员按 ID 解析拒绝维护账号通过HTTP 400
公开登录候选列表不暴露维护账号通过
admin 无法通过普通用户接口给测试账号授予内部角色通过HTTP 400
root 无法通过普通用户接口给测试账号授予内部角色通过HTTP 400
拒绝内部角色分配后测试账号原角色和版本保持不变通过
admin 无法通过普通编辑更改固定管理员数据范围通过HTTP 403
admin 无法停用固定管理员角色通过HTTP 403
root 无法通过普通编辑更改固定管理员数据范围通过HTTP 403
root 无法停用固定管理员角色通过HTTP 403
固定管理员角色状态、范围、版本未被边界请求改变通过
普通管理员不能读取维护审计/列表通过HTTP 403
普通管理员不能读取维护审计/stats通过HTTP 403
普通管理员不能读取维护审计/export通过HTTP 403
已知维护账号错误密码和未知账号均返回统一认证失败通过
维护登录失败在普通列表不可见且内部审计保留真实 USER 目标通过
未知身份失败仍可在普通安全审计中查到通过
普通审计导出不包含维护记录,维护导出保留该记录通过
普通审计统计只计算 BUSINESS,维护统计只计算 INTERNAL通过
普通用户和角色统计排除内部账号及内部角色通过
首页人数不计维护账号,最近动态不显示维护失败日志通过
数据库只读核验:已知维护失败 INTERNAL,未知失败 BUSINESS通过
维护再次登录后普通 admin 仍未被重新保护通过

C. 浏览器 E2E:可见交互与异常路径

通过 9 / 9 项通过,0 项失败,0 项待完成/跳过/需复核 · 完整 JSON · 开始于 2026-09-06T04:01:43.840Z

浏览器用例结果耗时失败证据
管理员授权固定,权限树细分到页面操作通过4.9 秒
权限依赖:勾选操作自动补齐查看,取消查看需要确认通过11.4 秒
头像弹窗切换自定义角色,清理旧缓存并改变操作能力通过6.2 秒
角色切换接口失败保留原身份与页面通过3.7 秒
切换已提交但身份加载失败,不展示旧角色业务页面通过5.1 秒
训练编排未保存时,取消切换保留当前内容与身份通过7.9 秒
未保存训练的保存请求失败时,阻止提交角色切换通过6.6 秒
权限加载乱序:关闭 A 后打开 B,A 的迟到响应不能覆盖 B通过6.2 秒
保存授权期间禁止恢复,PUT 成功但列表刷新失败仍保留提交快照通过6.5 秒

角色切换/身份获取/保存失败等异常路径使用浏览器定向响应模拟。它们验证前端保留状态与阻断行为,不表示真实服务发生过这些故障。

D. 构建、聚焦单测与 DDL

完整验证记录。下方按实际执行的命令与结果展示,不把单测数量并入 E2E 或真实 API 数量。

{
  "time": "2026-09-06T04:08:03.624366+00:00",
  "overallStatus": "PASS",
  "e2eComplete": true,
  "build": {
    "web": "PASS: pnpm build; Vite production build and postbuild 10 iframe payload checks",
    "auth": "PASS: Maven test/package",
    "tran": "PASS: Maven test/package"
  },
  "backendTests": {
    "ut_auth": {
      "tests": 112,
      "failures": 0,
      "errors": 0,
      "skipped": 0
    },
    "ut_tran": {
      "tests": 340,
      "failures": 0,
      "errors": 0,
      "skipped": 0
    }
  },
  "nodeTests": {
    "contentCoverPermissions": {
      "tests": 57,
      "failed": 0,
      "command": "node --test tools/content-permissions.test.mjs tools/training-cover.test.mjs tools/scene-cover-api.test.mjs"
    },
    "uiPermissionContracts": {
      "tests": 12,
      "failed": 0,
      "command": "node --test scripts/permission-selection.contract.test.mjs scripts/teaching-permissions.test.mjs"
    }
  },
  "realApi": {
    "permissions": 32,
    "maintenanceBoundaries": 39,
    "failed": 0
  },
  "e2e": {
    "complete": true,
    "passed": 9,
    "failed": 0,
    "flaky": 0,
    "skipped": 0,
    "screenshots": 12,
    "command": "pnpm exec playwright test --config role-permissions-live.config.ts"
  },
  "ddl": {
    "status": "PASS",
    "file": "20260906_036_role_permissions_maintenance.sql",
    "sha256": "66d6c32edef315c8fcd9264352dda3444ddcdf1ca2d50d2af6f138fc7f4d4bd1",
    "environment": "Development: unreal_tran / public, KingBase MySQL compatibility",
    "execution": "200 statements committed; same SHA rerun committed successfully",
    "catalogLeafCount": 138,
    "adminFixedLeafCount": 106,
    "fullDdlUpdated": true,
    "executionRecord": "unreal_tran_api/database/迁移执行记录.md"
  },
  "runtime": {
    "gateway": "http://127.0.0.1:6180",
    "authPort": 6101,
    "tranPort": 6102,
    "deployedArtifacts": {
      "auth": {
        "sha256": "98aaeedfe29c8e75e99ef9421a3982ae52ab357eb8592c68a30dfc54e633ff85",
        "runningCopyMatches": true
      },
      "tran": {
        "sha256": "d66a38602e32c0db0c2680905f6a6461d9cd09ab12f4ba1481c87f99f583e828",
        "runningCopyMatches": true
      }
    },
    "rootBootstrap": "Initialized from the local account file; one-time bootstrap disabled on restart; root login verified afterward",
    "adminProtected": false
  },
  "cleanup": {
    "time": "2026-09-06T04:07:09.247Z",
    "projects": [
      "165"
    ],
    "users": [
      "100"
    ],
    "roles": [
      "20",
      "21"
    ],
    "status": "PASS",
    "postDeleteReads": "All 4 isolated fixture records return HTTP 404"
  },
  "artifactChecks": {
    "status": "PASS",
    "file": "artifact-checks.json",
    "diffWhitespace": {
      "unreal_tran_api": "PASS",
      "unreal_tran_web": "PASS",
      "ute2e": "PASS"
    }
  },
  "scopeNotes": [
    "Root login and operation audits are retained as INTERNAL; ordinary lists, statistics and exports exclude them.",
    "Admin has fixed persisted grants; both admin and root cannot edit that built-in role permission set through the application.",
    "OFD legacy editor continues to store its existing local browser data; session permission checks were added, not a new server persistence workflow.",
    "Permission and role-switch tests are the focus; this run does not claim complete regression of every teaching or 3D business scenario.",
    "Temporary test fixtures were deleted; existing training used for dirty-state checks was not saved.",
    "Development environment only; no production deployment, Git commit or push performed."
  ]
}

E. 临时测试数据与清理

清理证据。业务模型、场景与训练的保留/恢复情况以记录为准。

{
  "time": "2026-09-06T04:07:09.247Z",
  "projects": [
    "165"
  ],
  "users": [
    "100"
  ],
  "roles": [
    "20",
    "21"
  ],
  "status": "PASS",
  "postDeleteReads": "All 4 isolated fixture records return HTTP 404"
}

截图证据 · 点击放大

截图只证明相应画面。标记为“过程截图”的文件未关联当前结果,不计入当前通过数量。

可随 Git 交付的材料

data/ 仅包含脱敏角色/权限快照与动作合同。本生成器不读取或复制账号配置、私有测试 fixtures、数据库备份、服务日志或会话凭据。

打开原图