feat: add flexible capability-based RBAC with per-tenant customization
Introduces a capability layer on top of existing roles that controls feature visibility and access. Capabilities follow an area.feature.action taxonomy (~35 capabilities) with sensible defaults per role. Tenant admins can customize via grant/revoke overrides stored in org settings JSONB. Key changes: - Add vice_president role to DB schema - Backend: capability constants, resolution logic, CapabilityGuard (global), @RequireCapability decorator on all 16 tenant controllers - Frontend: permission hooks (useCanEdit, useHasCapability), CapabilityGate component, sidebar filtering by capability, all 17 pages migrated from useIsReadOnly to capability-based checks - New admin UI: /settings/permissions matrix page for per-tenant role customization with grant/revoke delta model - GET /organizations/my-capabilities endpoint for capability refresh - Validation of permissionOverrides in settings updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
22
frontend/src/permissions/CapabilityGate.tsx
Normal file
22
frontend/src/permissions/CapabilityGate.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { ReactNode } from 'react';
|
||||
import { useHasCapability, useHasAnyCapability } from './useCapability';
|
||||
|
||||
interface CapabilityGateProps {
|
||||
/** Single capability required */
|
||||
capability?: string;
|
||||
/** Multiple capabilities — user needs at least one */
|
||||
anyOf?: string[];
|
||||
/** Content shown when user has the capability */
|
||||
children: ReactNode;
|
||||
/** Optional fallback shown when user lacks the capability */
|
||||
fallback?: ReactNode;
|
||||
}
|
||||
|
||||
export function CapabilityGate({ capability, anyOf, children, fallback = null }: CapabilityGateProps) {
|
||||
const hasSingle = useHasCapability(capability || '');
|
||||
const hasAny = useHasAnyCapability(...(anyOf || []));
|
||||
|
||||
const allowed = capability ? hasSingle : anyOf ? hasAny : true;
|
||||
|
||||
return allowed ? <>{children}</> : <>{fallback}</>;
|
||||
}
|
||||
Reference in New Issue
Block a user