Files
model-platform/frontend/app/features/operations/operationsRole.ts
T
郑龙捷 74dd97428f feat: 接入运维真实数据与三角色权限链路
- 新增 model_deploy 与 model_operations 双库查询,支持模型列表、模型详情、单月监控结果和运维工作台真实接口。

- 关闭运维模块生产 Mock 数据,补充缺表/空数据降级、工作台空状态和首条纵向链路测试。

- 按业务团队、模型团队、管理员权限矩阵接入菜单、页面、操作按钮和后端接口权限校验,支持 business_team 角色。

- 更新工作台布局、深色欢迎卡片、全宽页面适配、顶部回退,以及权限分组展示。

- 新增架构实现基线、周目标完成情况和角色权限矩阵初始化 SQL 文档。
2026-09-02 15:02:47 +08:00

161 lines
5.7 KiB
TypeScript

import { useAuth, type AuthUser } from "~/context/AuthContext";
export type OperationsRole = "business" | "model" | "admin";
export type OperationsPageKey =
| "workbench"
| "usage"
| "models"
| "banks"
| "deployed-models"
| "monitoring"
| "monitoring-detail"
| "reports"
| "report-summary"
| "workflows"
| "knowledge"
| "rules"
| "prompts"
| "settings";
export type OperationsAction =
| "workflow:create"
| "workflow:feedback"
| "workflow:submit-material"
| "workflow:advance"
| "workflow:online"
| "workflow:business-confirm"
| "monitor:initial-review"
| "monitor:final-review"
| "report:edit"
| "report:export"
| "report:send"
| "rules:publish"
| "rules:rollback"
| "rules:simulate"
| "rules:manage"
| "prompts:manage"
| "prompts:regression"
| "settings:manage";
const PAGE_ROLE_VISIBILITY: Record<OperationsPageKey, OperationsRole[]> = {
workbench: ["business", "model", "admin"],
usage: ["admin"],
models: ["business", "model", "admin"],
banks: ["business", "model", "admin"],
"deployed-models": ["model", "admin"],
monitoring: ["business", "model", "admin"],
"monitoring-detail": ["business", "model", "admin"],
reports: ["business", "model", "admin"],
"report-summary": ["business", "model", "admin"],
workflows: ["business", "model", "admin"],
knowledge: ["model", "admin"],
rules: ["model", "admin"],
prompts: ["model", "admin"],
settings: ["admin"],
};
const ACTION_ROLE_VISIBILITY: Record<OperationsAction, OperationsRole[]> = {
"workflow:create": ["business", "admin"],
"workflow:feedback": ["business", "admin"],
"workflow:submit-material": ["model", "admin"],
"workflow:advance": ["model", "admin"],
"workflow:online": ["model", "admin"],
"workflow:business-confirm": ["business", "admin"],
"monitor:initial-review": ["model", "admin"],
"monitor:final-review": ["business", "admin"],
"report:edit": ["model", "admin"],
"report:export": ["business", "model", "admin"],
"report:send": ["model", "admin"],
"rules:publish": ["admin"],
"rules:rollback": ["admin"],
"rules:simulate": ["admin"],
"rules:manage": ["admin"],
"prompts:manage": ["model", "admin"],
"prompts:regression": ["model", "admin"],
"settings:manage": ["admin"],
};
export const OPERATIONS_PAGE_PERMISSIONS: Record<OperationsPageKey, string> = {
workbench: "operations:workbench:view",
usage: "operations:usage:view",
models: "operations:model-overview:view",
banks: "operations:bank-overview:view",
"deployed-models": "operations:deployed-models:view",
monitoring: "operations:monitoring-overview:view",
"monitoring-detail": "operations:monitoring-detail:view",
reports: "operations:report:view",
"report-summary": "operations:report-summary:view",
workflows: "operations:workflow:view",
knowledge: "operations:knowledge:view",
rules: "operations:rules:view",
prompts: "operations:prompt:view",
settings: "operations:settings:view",
};
export const OPERATIONS_ACTION_PERMISSIONS: Record<OperationsAction, string> = {
"workflow:create": "operations:workflow:create",
"workflow:feedback": "operations:workflow:feedback",
"workflow:submit-material": "operations:workflow:submit-material",
"workflow:advance": "operations:workflow:advance",
"workflow:online": "operations:workflow:online",
"workflow:business-confirm": "operations:workflow:confirm",
"monitor:initial-review": "operations:monitoring-detail:model-review",
"monitor:final-review": "operations:monitoring-detail:business-review",
"report:edit": "operations:report:edit",
"report:export": "operations:report:export",
"report:send": "operations:report:send",
"rules:publish": "operations:rules:publish",
"rules:rollback": "operations:rules:rollback",
"rules:simulate": "operations:rules:simulate",
"rules:manage": "operations:rules:publish",
"prompts:manage": "operations:prompt:edit",
"prompts:regression": "operations:prompt:regression",
"settings:manage": "operations:settings:view",
};
export function resolveOperationsRole(user: AuthUser | null): OperationsRole {
if (user?.is_system_admin || user?.role_code === "admin") return "admin";
const code = user?.role_code?.toLowerCase() ?? "";
if (["business", "business_team", "biz"].includes(code)) return "business";
return "model";
}
export function useOperationsRole(): OperationsRole {
return resolveOperationsRole(useAuth().user);
}
export function isOperationsPageVisibleForRole(role: OperationsRole, page: OperationsPageKey): boolean {
return PAGE_ROLE_VISIBILITY[page].includes(role);
}
export function isOperationsActionVisibleForRole(role: OperationsRole, action: OperationsAction): boolean {
return ACTION_ROLE_VISIBILITY[action].includes(role);
}
export function useOperationsPermission(permissionCode: string): boolean {
const { user } = useAuth();
return Boolean(user?.is_system_admin || user?.permissions.includes(permissionCode));
}
export function useCanOperationsPage(page: OperationsPageKey): boolean {
return useOperationsPermission(OPERATIONS_PAGE_PERMISSIONS[page]);
}
export function useCanOperationsAction(action: OperationsAction): boolean {
return useOperationsPermission(OPERATIONS_ACTION_PERMISSIONS[action]);
}
export function operationsPagePermission(page: OperationsPageKey): string {
return OPERATIONS_PAGE_PERMISSIONS[page];
}
export function operationsPageFromPath(pathname: string): OperationsPageKey {
const normalized = pathname.replace(/^\/operations\/?/, "");
if (normalized.startsWith("monitoring/")) return "monitoring-detail";
const path = normalized.split("/")[0] ?? "";
if (!path) return "workbench";
if (path === "monitoring") return "monitoring";
if (path in PAGE_ROLE_VISIBILITY) return path as OperationsPageKey;
return "workbench";
}