feat(shared): add errors lib, question-content, and update permissions and UI

- Add errors lib for standardized error handling

- Add question-content lib for question content processing

- Update action-utils, ai/provider-config, auth-guard, permissions, types/permissions

- Update UI sheet component

- Update proxy middleware
This commit is contained in:
SpecialX
2026-06-24 12:04:09 +08:00
parent e3b8455b31
commit 1f833097e2
9 changed files with 299 additions and 53 deletions

View File

@@ -27,6 +27,13 @@ const DASHBOARD_ROUTE_PERMISSIONS: Record<string, string> = {
"/parent/dashboard": Permissions.DASHBOARD_PARENT_READ,
}
// 精确路由权限(优先级最高,覆盖 ROUTE_PERMISSIONS 的前缀匹配)
// 用于将 /admin/* 下的特定页面开放给非管理员角色
// V3.1/admin/ai-settings 对所有 AI_CHAT 用户开放(管理自己的 private provider
const SPECIFIC_ROUTE_PERMISSIONS: Record<string, string> = {
"/admin/ai-settings": Permissions.AI_CHAT,
}
// API route prefix → required permission
const API_PERMISSIONS: Record<string, string> = {
"/api/ai/chat": Permissions.AI_CHAT,
@@ -99,7 +106,20 @@ export async function proxy(request: NextRequest) {
}
// Check page route permissions
// 优先检查仪表盘路由的细粒度权限(防止跨角色访问仪表盘
// 优先级 1精确路由权限覆盖前缀匹配用于将 /admin/* 下特定页面开放给非管理员
if (Object.prototype.hasOwnProperty.call(SPECIFIC_ROUTE_PERMISSIONS, pathname)) {
const requiredPerm = SPECIFIC_ROUTE_PERMISSIONS[pathname]
if (!permissions.includes(requiredPerm)) {
const defaultPath = resolveDefaultPath(roles)
const redirectUrl = new URL(defaultPath, request.url)
redirectUrl.searchParams.set("from", pathname)
redirectUrl.searchParams.set("reason", "forbidden")
return NextResponse.redirect(redirectUrl)
}
return NextResponse.next()
}
// 优先级 2仪表盘路由的细粒度权限防止跨角色访问仪表盘
if (Object.prototype.hasOwnProperty.call(DASHBOARD_ROUTE_PERMISSIONS, pathname)) {
const requiredPerm = DASHBOARD_ROUTE_PERMISSIONS[pathname]
if (!permissions.includes(requiredPerm)) {