线上原运营管理员具有 isAdmin=true、role=admin、roles=[admin],账号未停用、资料未丢失;新运营网关只识别 ops-manager、ops-staff、ops-auditor。登录身份与业务权限不一致导致工作台、会员详情报“当前运营角色无权执行该操作”。
管理网关和两个运营网关现在共用 admin-role-policy.js:优先读取显式角色,再兼容旧管理员为本帐套运营经理,不升级为超级管理员。显式未知运营角色不会回退获取经理权限。禁用和删除状态仍先于角色校验。当前原会话已可读取工作台与会员资料。
/admin/operator-accounts,左侧“账号与安全 → 运营账号管理”。
| 身份 | 管理范围 |
|---|---|
| 运营经理(含旧 admin) | 本帐套运营经理、运营人员、审计员;不能管理或授予超级管理员 |
| 运营人员、审计员 | 不开放运营账号管理;继续使用对应角色的业务权限 |
| 超级管理员 | 所属帐套中的全部后台角色;技术后台权限保持独立 |
自己不能停用自己或修改自己的角色。账号用停用保留记录,不提供永久删除。角色变更、停用与退出会话在同一数据库事务中撤销旧会话并记录审计。公司锁与事务内操作者重检防止两个经理互相停用造成无人可管理。
线上验收发现 Parse 用户所有者可以直接更新自定义权限字段,即使新账号设置了私有 ACL。因此增加数据库授权字段保护触发器:
xs_operator_change;事务校验实际操作者与目标帐套、权限、自身保护和版本后才写入。维护注意:旧脚本通过 Parse REST 直接创建带管理员标志的用户或修改权限字段会被拒绝。日常开户应调用运营账号管理接口。迁移和隔离测试需要持有 Master Key,由限指定测试用户的一次性云函数执行受控 SQL;smoke-operator-accounts.mjs 包含这一流程及精确清理,不应关闭权限保护来运行旧脚本。
npm run test:admin:ci:192 项通过(包含表单、角色限制、重复提交、密码确认与 403 会话保留)。node --test scripts/tests/operator-accounts.test.mjs:8 项通过(角色兼容、数据库隔离、审计、版本、自身保护、经理互相停用、直接接口越权保护)。npm run test:member-enrollment:26 项通过。npm run build:admin、11 个云函数定义校验和 diff 检查通过;已有其他页面样式预算及 CommonJS 警告保留。scripts/smoke-operator-accounts.mjs:18 项线上验收通过,包含新旧账号登录、真实账号创建、重复账号拒绝、直接 Parse 权限修改拒绝、角色变更、密码新旧有效性、停用和恢复、主动会话撤销、审计及敏感字段检查。OPERATOR_SMOKE_PASSED、OPERATOR_FIXTURES_CLEANED;只改动独立测试账号,未修改真实管理员的密码和角色数据。tmp/operator-account-ui/。更新前备份三个网关及管理员角色白名单数据至 tmp/operator-accounts-release-1788963918963/。迁移脚本为新增的 OperatorAccountAudit 注册 Master-only Parse schema,并安装权限事务和触发器;迁移临时用户及临时函数已清理。
管理网关与两个运营网关已更新。前端在本机 4300 服务生效并生成生产构建;尚无本次确认的独立公网前端托管地址,不把本机界面等同于公网前端部署。