feat: implement RBAC permissions system
Add role-based access control with hierarchy: super_admin > team_admin > engineer > viewer. Adds is_super_admin boolean to User model (migration 010), centralized backend permissions module, frontend usePermissions hook, and UI enforcement (conditional Create/Edit buttons, editor redirect for viewers, role badge in header). All endpoint admin checks updated from role=="admin" to is_super_admin. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Link, useLocation, useNavigate, Outlet } from 'react-router-dom'
|
||||
import { useAuthStore } from '@/store/authStore'
|
||||
import { usePermissions } from '@/hooks/usePermissions'
|
||||
import { ThemeToggle } from '@/components/common/ThemeToggle'
|
||||
import { BrandLogo } from '@/components/common/BrandLogo'
|
||||
import { BrandWordmark } from '@/components/common/BrandWordmark'
|
||||
@@ -9,6 +10,7 @@ export function AppLayout() {
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
const { user, logout } = useAuthStore()
|
||||
const { effectiveRole } = usePermissions()
|
||||
|
||||
const handleLogout = async () => {
|
||||
await logout()
|
||||
@@ -53,6 +55,20 @@ export function AppLayout() {
|
||||
<span className="hidden text-sm text-muted-foreground sm:block">
|
||||
{user?.name || user?.email}
|
||||
</span>
|
||||
{effectiveRole && effectiveRole !== 'engineer' && (
|
||||
<span
|
||||
className={cn(
|
||||
'hidden rounded-full px-2 py-0.5 text-xs font-medium sm:inline-block',
|
||||
effectiveRole === 'super_admin' && 'bg-red-500/10 text-red-600 dark:text-red-400',
|
||||
effectiveRole === 'team_admin' && 'bg-blue-500/10 text-blue-600 dark:text-blue-400',
|
||||
effectiveRole === 'viewer' && 'bg-gray-500/10 text-gray-600 dark:text-gray-400'
|
||||
)}
|
||||
>
|
||||
{effectiveRole === 'super_admin' ? 'Super Admin' :
|
||||
effectiveRole === 'team_admin' ? 'Team Admin' :
|
||||
'Viewer'}
|
||||
</span>
|
||||
)}
|
||||
<ThemeToggle />
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
|
||||
Reference in New Issue
Block a user