237 lines
6.2 KiB
TypeScript
237 lines
6.2 KiB
TypeScript
import { useAuthStore } from '~/stores/auth'
|
|
|
|
// Role definitions with hierarchical ranks
|
|
export enum Role {
|
|
SUPERADMIN = 'superadmin',
|
|
ADMIN = 'admin',
|
|
MODERATOR = 'moderator',
|
|
SALESPERSON = 'salesperson'
|
|
}
|
|
|
|
// Scope level definitions
|
|
export enum ScopeLevel {
|
|
GLOBAL = 'global',
|
|
COUNTRY = 'country',
|
|
REGION = 'region',
|
|
CITY = 'city',
|
|
DISTRICT = 'district'
|
|
}
|
|
|
|
// Role rank mapping (higher number = higher authority)
|
|
export const RoleRank: Record<Role, number> = {
|
|
[Role.SUPERADMIN]: 10,
|
|
[Role.ADMIN]: 7,
|
|
[Role.MODERATOR]: 5,
|
|
[Role.SALESPERSON]: 3
|
|
}
|
|
|
|
// Tile permissions mapping
|
|
export interface TilePermission {
|
|
id: string
|
|
title: string
|
|
description: string
|
|
requiredRole: Role[]
|
|
minRank?: number
|
|
requiredPermission?: string
|
|
scopeLevel?: ScopeLevel[]
|
|
}
|
|
|
|
// Available tiles with RBAC requirements
|
|
export const AdminTiles: TilePermission[] = [
|
|
{
|
|
id: 'ai-logs',
|
|
title: 'AI Logs Monitor',
|
|
description: 'Real-time tracking of AI robot pipelines',
|
|
requiredRole: [Role.SUPERADMIN, Role.ADMIN, Role.MODERATOR],
|
|
minRank: 5,
|
|
requiredPermission: 'view:dashboard'
|
|
},
|
|
{
|
|
id: 'financial-dashboard',
|
|
title: 'Financial Dashboard',
|
|
description: 'Revenue, expenses, ROI metrics with geographical filtering',
|
|
requiredRole: [Role.SUPERADMIN, Role.ADMIN],
|
|
minRank: 7,
|
|
requiredPermission: 'view:finance',
|
|
scopeLevel: [ScopeLevel.GLOBAL, ScopeLevel.COUNTRY, ScopeLevel.REGION]
|
|
},
|
|
{
|
|
id: 'salesperson-hub',
|
|
title: 'Salesperson Hub',
|
|
description: 'Performance metrics, leads, conversions for sales teams',
|
|
requiredRole: [Role.SUPERADMIN, Role.ADMIN, Role.SALESPERSON],
|
|
minRank: 3,
|
|
requiredPermission: 'view:sales'
|
|
},
|
|
{
|
|
id: 'user-management',
|
|
title: 'User Management',
|
|
description: 'Active users, registration trends, moderation queue',
|
|
requiredRole: [Role.SUPERADMIN, Role.ADMIN, Role.MODERATOR],
|
|
minRank: 5,
|
|
requiredPermission: 'view:users',
|
|
scopeLevel: [ScopeLevel.GLOBAL, ScopeLevel.COUNTRY, ScopeLevel.REGION, ScopeLevel.CITY]
|
|
},
|
|
{
|
|
id: 'service-moderation-map',
|
|
title: 'Service Moderation Map',
|
|
description: 'Geographical view of pending/flagged services',
|
|
requiredRole: [Role.SUPERADMIN, Role.ADMIN, Role.MODERATOR],
|
|
minRank: 5,
|
|
requiredPermission: 'moderate:services',
|
|
scopeLevel: [ScopeLevel.CITY, ScopeLevel.DISTRICT]
|
|
},
|
|
{
|
|
id: 'gamification-control',
|
|
title: 'Gamification Control',
|
|
description: 'XP levels, badges, penalty system administration',
|
|
requiredRole: [Role.SUPERADMIN, Role.ADMIN],
|
|
minRank: 7,
|
|
requiredPermission: 'manage:settings'
|
|
},
|
|
{
|
|
id: 'system-health',
|
|
title: 'System Health',
|
|
description: 'API status, database metrics, uptime monitoring',
|
|
requiredRole: [Role.SUPERADMIN, Role.ADMIN],
|
|
minRank: 7,
|
|
requiredPermission: 'view:dashboard'
|
|
}
|
|
]
|
|
|
|
// Composable for RBAC checks
|
|
export function useRBAC() {
|
|
const authStore = useAuthStore()
|
|
|
|
// Check if user can access a specific tile
|
|
function canAccessTile(tileId: string): boolean {
|
|
const tile = AdminTiles.find(t => t.id === tileId)
|
|
if (!tile) return false
|
|
|
|
// Check role
|
|
if (!tile.requiredRole.includes(authStore.getUserRole as Role)) {
|
|
return false
|
|
}
|
|
|
|
// Check rank
|
|
if (tile.minRank && !authStore.hasRank(tile.minRank)) {
|
|
return false
|
|
}
|
|
|
|
// Check permission
|
|
if (tile.requiredPermission && !authStore.hasPermission(tile.requiredPermission)) {
|
|
return false
|
|
}
|
|
|
|
// Check scope level
|
|
if (tile.scopeLevel && tile.scopeLevel.length > 0) {
|
|
const userScopeLevel = authStore.getScopeLevel as ScopeLevel
|
|
if (!tile.scopeLevel.includes(userScopeLevel)) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// Get filtered tiles for current user
|
|
function getFilteredTiles(): TilePermission[] {
|
|
return AdminTiles.filter(tile => canAccessTile(tile.id))
|
|
}
|
|
|
|
// Check if user can perform action
|
|
function canPerformAction(permission: string, minRank?: number): boolean {
|
|
if (!authStore.hasPermission(permission)) {
|
|
return false
|
|
}
|
|
|
|
if (minRank && !authStore.hasRank(minRank)) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// Check if user can access scope
|
|
function canAccessScope(scopeLevel: ScopeLevel, scopeId?: number, regionCode?: string): boolean {
|
|
const userScopeLevel = authStore.getScopeLevel as ScopeLevel
|
|
|
|
// Superadmin can access everything
|
|
if (authStore.getUserRole === Role.SUPERADMIN) {
|
|
return true
|
|
}
|
|
|
|
// Check scope level hierarchy
|
|
const scopeHierarchy = [
|
|
ScopeLevel.GLOBAL,
|
|
ScopeLevel.COUNTRY,
|
|
ScopeLevel.REGION,
|
|
ScopeLevel.CITY,
|
|
ScopeLevel.DISTRICT
|
|
]
|
|
|
|
const userLevelIndex = scopeHierarchy.indexOf(userScopeLevel)
|
|
const requestedLevelIndex = scopeHierarchy.indexOf(scopeLevel)
|
|
|
|
// User can only access their level or lower (more specific) levels
|
|
if (requestedLevelIndex < userLevelIndex) {
|
|
return false
|
|
}
|
|
|
|
// Check specific scope ID or region code if provided
|
|
if (scopeId || regionCode) {
|
|
return authStore.canAccessScope(scopeId || 0, regionCode)
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// Get user's accessible scope levels
|
|
function getAccessibleScopeLevels(): ScopeLevel[] {
|
|
const userScopeLevel = authStore.getScopeLevel as ScopeLevel
|
|
const scopeHierarchy = [
|
|
ScopeLevel.GLOBAL,
|
|
ScopeLevel.COUNTRY,
|
|
ScopeLevel.REGION,
|
|
ScopeLevel.CITY,
|
|
ScopeLevel.DISTRICT
|
|
]
|
|
|
|
const userLevelIndex = scopeHierarchy.indexOf(userScopeLevel)
|
|
return scopeHierarchy.slice(userLevelIndex)
|
|
}
|
|
|
|
// Get role color for UI
|
|
function getRoleColor(role?: string): string {
|
|
const userRole = role || authStore.getUserRole
|
|
|
|
switch (userRole) {
|
|
case Role.SUPERADMIN:
|
|
return 'purple'
|
|
case Role.ADMIN:
|
|
return 'blue'
|
|
case Role.MODERATOR:
|
|
return 'green'
|
|
case Role.SALESPERSON:
|
|
return 'orange'
|
|
default:
|
|
return 'gray'
|
|
}
|
|
}
|
|
|
|
return {
|
|
// Data
|
|
Role,
|
|
ScopeLevel,
|
|
RoleRank,
|
|
AdminTiles,
|
|
|
|
// Functions
|
|
canAccessTile,
|
|
getFilteredTiles,
|
|
canPerformAction,
|
|
canAccessScope,
|
|
getAccessibleScopeLevels,
|
|
getRoleColor
|
|
}
|
|
} |