角色权限(RBAC v2)
设计
权限解耦三张表(在 shared_auth 库):
sql
CREATE TABLE permissions (
key TEXT PRIMARY KEY,
app TEXT, -- 'robovan' | 'nempoi' | 'platform'
category TEXT,
description TEXT
);
CREATE TABLE roles (
id BIGSERIAL PRIMARY KEY,
app TEXT,
name TEXT,
description TEXT,
is_system BOOLEAN DEFAULT FALSE, -- 系统预置 vs 自定义
UNIQUE(app, name)
);
CREATE TABLE role_permissions (
role_id BIGINT REFERENCES roles(id) ON DELETE CASCADE,
permission_key TEXT REFERENCES permissions(key) ON DELETE CASCADE,
PRIMARY KEY (role_id, permission_key)
);系统预置角色
| App | 角色 | 说明 |
|---|---|---|
| robovan | superadmin | 顶级,所有权限 |
| robovan | management | 管理层 |
| robovan | operations | 运营 |
| robovan | finance | 财务 |
| robovan | sales | 销售 |
| robovan | pending | 待审批,无权限 |
| nempoi | superadmin | 顶级 |
| nempoi | admin | 运营 |
| nempoi | customer | 客户 |
is_system=true 的角色不可删,superadmin 不可改权限(防误操作)。
自定义角色
门户超管面板 → 角色权限 → + 新建自定义角色 可创建任意角色,并通过权限矩阵勾选授权。可删可改。
应用层 RBAC v1 兼容(robovan)
robovan 应用层仍用旧 10 个 key:
view_dashboard/manage_vehicles/manage_orders/manage_trips/manage_customers/manage_costs/view_availability/run_batch/manage_users/view_logs
permissionService 直接查 shared_auth.role_permissions JOIN roles WHERE app='robovan'。门户矩阵 UI 勾选 → 写 shared_auth → robovan 应用层立即生效(5s 缓存 TTL,改完后 invalidate 立即清)。
allowPerm(key) 中间件:
js
async function allowPerm(key) {
return async (req, res, next) => {
if (req.user.is_root_owner || req.user.role === 'superadmin') return next();
const grants = await permSvc.loadGrants();
if (grants[req.user.role]?.includes(key)) return next();
return res.status(403);
};
}NEMPOI
NEMPOI 当前还用 require_role() 字符串匹配,未接 RBAC v2 应用层(待后续切换)。permission 数据已在 shared_auth 准备好,require_perm() helper 已写但未替换现有路由。