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>
43 lines
996 B
TypeScript
43 lines
996 B
TypeScript
import { ALL_CAPABILITIES } from './capabilities';
|
|
import { DEFAULT_ROLE_CAPABILITIES } from './default-role-capabilities';
|
|
|
|
export interface PermissionOverrides {
|
|
[role: string]: {
|
|
grant?: string[];
|
|
revoke?: string[];
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Resolve effective capabilities for a role, applying tenant overrides.
|
|
*
|
|
* Mirrors backend/src/common/permissions/resolve-permissions.ts.
|
|
*/
|
|
export function resolveCapabilities(
|
|
role: string,
|
|
overrides?: PermissionOverrides | null,
|
|
): Set<string> {
|
|
const defaults = DEFAULT_ROLE_CAPABILITIES[role] || [];
|
|
const result = new Set<string>(defaults);
|
|
|
|
if (overrides && overrides[role]) {
|
|
const roleOverride = overrides[role];
|
|
|
|
if (roleOverride.grant) {
|
|
for (const cap of roleOverride.grant) {
|
|
if (ALL_CAPABILITIES.has(cap)) {
|
|
result.add(cap);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (roleOverride.revoke) {
|
|
for (const cap of roleOverride.revoke) {
|
|
result.delete(cap);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|