> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions System - Quick Reference

> Last Updated: 2025-01-25 Status: Active

**Last Updated:** 2025-01-25\
**Status:** Active

> **Comprehensive Guide:** For detailed information, see [permissions-system-guide.md](permissions-system-guide.md)

***

## Permission Key Format

```
{module}.{entity}.{action}
```

**Examples:**

* `hr.employees.view` - View HR employees
* `fa.bills.approve` - Approve FA bills
* `rh.residents.create` - Create RH residents
* `system.platform.admin` - Platform admin access

**Categories:**

* `view` - Read access
* `create` - Create new records
* `edit` - Modify existing records
* `delete` - Remove records
* `approve` - Approval workflows
* `admin` - Full administrative access

***

## Common Patterns

### Component Usage

```typescript theme={null}
// Hook for permission checks
import { useHasPermission } from '@/platform/permissions';
const canView = useHasPermission('hr.employees.view');

// Conditional rendering
import { PermissionGate } from '@/platform/permissions';
<PermissionGate permission="hr.employees.edit">
  <EditButton />
</PermissionGate>

// Page-level protection
import { RequirePermission } from '@/platform/permissions';
<RequirePermission permission="hr.employees.view">
  <EmployeesPage />
</RequirePermission>
```

### Navigation Items

```typescript theme={null}
{
 label: 'Employees',
 path: '/hr/employees',
 permission: 'hr.employees.view', // ✅ Use this
 // minRole: 'staff' // ❌ Don't use (V1 deprecated)
}
```

### RLS Policies

```sql theme={null}
-- ✅ CORRECT: Use SECURITY DEFINER function
CREATE POLICY "users_can_view_employees" ON hr_employees
FOR SELECT
USING (
  pf_has_permission(auth.uid(), organization_id, 'hr.employees.view')
);

-- ❌ WRONG: Direct role check (V1 deprecated)
USING (has_role(auth.uid(), 'staff'));
```

***

## Role to Permission Mapping

| V1 Role (Deprecated) | V2 Permission Pattern                |
| -------------------- | ------------------------------------ |
| `platform_admin`     | `system.platform.admin`              |
| `org_admin`          | `system.platform.admin` or `*.admin` |
| `site_admin`         | `*.view` + `*.create` + `*.edit`     |
| `staff`              | `*.view` + `*.create`                |
| `readonly`           | `*.view` only                        |
| `finance_admin`      | `fa.admin` + all FA permissions      |
| `finance_staff`      | `fa.*.view` + `fa.*.create`          |

**Note:** V1 roles are deprecated. Always use V2 permission keys.

***

## Migration Quick Reference

### Code Migration Patterns

#### Navigation

```typescript theme={null}
// ❌ Before (V1)
{ label: 'Employees', path: '/hr/employees', minRole: 'staff' }

// ✅ After (V2)
{ label: 'Employees', path: '/hr/employees', permission: 'hr.employees.view' }
```

#### Components

```typescript theme={null}
// ❌ Before (V1)
import { useUserRole } from '@/platform/modules/useUserRole';
const { role } = useUserRole();
if (role === 'org_admin') { ... }

// ✅ After (V2)
import { useHasPermission } from '@/platform/permissions';
const canAdmin = useHasPermission('system.platform.admin');
if (canAdmin) { ... }
```

#### RLS Policies

```sql theme={null}
-- ❌ Before (V1)
CREATE POLICY "org_admins_can_edit" ON some_table
FOR UPDATE
USING (has_role(auth.uid(), 'org_admin'));

-- ✅ After (V2)
CREATE POLICY "org_admins_can_edit" ON some_table
FOR UPDATE
USING (pf_has_permission(auth.uid(), organization_id, 'module.entity.edit'));
```

***

## Quick Lookup Tables

### Permission Categories

| Category  | Description                | Example               |
| --------- | -------------------------- | --------------------- |
| `view`    | Read-only access           | `hr.employees.view`   |
| `create`  | Create new records         | `hr.employees.create` |
| `edit`    | Modify existing records    | `hr.employees.edit`   |
| `delete`  | Remove records             | `hr.employees.delete` |
| `approve` | Approval workflows         | `fa.bills.approve`    |
| `admin`   | Full administrative access | `hr.admin`            |

### System Permissions

| Permission                    | Description                         |
| ----------------------------- | ----------------------------------- |
| `system.platform.admin`       | Platform-wide administrative access |
| `system.organizations.view`   | View organizations                  |
| `system.organizations.create` | Create organizations                |
| `system.organizations.edit`   | Edit organizations                  |

### Module Prefixes

| Prefix | Module                             |
| ------ | ---------------------------------- |
| `hr`   | Human Resources (Workforce & HRIS) |
| `fa`   | Finance & Accounting               |
| `rh`   | Recovery Housing                   |
| `fw`   | Forms & Workflow                   |
| `fm`   | Facilities Management              |
| `gr`   | Governance & Compliance            |
| `lo`   | Leadership Operating System        |
| `pf`   | Platform Foundation                |

***

## Anti-Patterns (What NOT to Do)

### ❌ Hardcode Role Checks

```typescript theme={null}
// ❌ WRONG
if (user.role === 'org_admin') { ... }

// ✅ CORRECT
const canAdmin = useHasPermission('system.platform.admin');
if (canAdmin) { ... }
```

### ❌ Direct Database Queries

```typescript theme={null}
// ❌ WRONG
const { data } = await supabase
  .from('pf_role_permissions')
  .select('*')
  .eq('permission_key', 'hr.employees.view');

// ✅ CORRECT
const canView = useHasPermission('hr.employees.view');
```

### ❌ Use V1 Patterns

```typescript theme={null}
// ❌ WRONG (V1 deprecated)
import { useUserRole } from '@/platform/modules/useUserRole';
const { role } = useUserRole();
if (hasMinimumRole(role, 'staff')) { ... }

// ✅ CORRECT (V2)
import { useHasPermission } from '@/platform/permissions';
const canView = useHasPermission('hr.employees.view');
```

### ❌ Recursive RLS Policies

```sql theme={null}
-- ❌ WRONG (Causes infinite recursion)
CREATE POLICY "document_org_access" ON pf_documents
FOR SELECT USING (
 organization_id IN (
 SELECT organization_id FROM pf_user_role_assignments 
 WHERE user_id = auth.uid() -- This table also has RLS!
 )
);

-- ✅ CORRECT (Use SECURITY DEFINER function with V2 permissions)
CREATE POLICY "document_org_access" ON pf_documents
FOR SELECT USING (
  pf_has_permission(auth.uid(), organization_id, 'pf.documents.view')
);
```

***

## Common Permission Keys

### HR Module

* `hr.employees.view`
* `hr.employees.create`
* `hr.employees.edit`
* `hr.employees.delete`
* `hr.ats.view`
* `hr.ats.create`
* `hr.credentialing.view`
* `hr.credentialing.approve`

### Finance Module

* `fa.accounts.view`
* `fa.bills.view`
* `fa.bills.create`
* `fa.bills.approve`
* `fa.transactions.view`
* `fa.budgets.view`

### Recovery Housing Module

* `rh.residents.view`
* `rh.residents.create`
* `rh.residents.edit`
* `rh.beds.view`
* `rh.census.view`

### Forms & Workflow Module

* `fw.forms.view`
* `fw.forms.create`
* `fw.workflows.view`
* `fw.workflows.create`
* `fw.workflows.edit`

**For complete list:** See [Module Permissions Matrix](module-permissions-matrix.md)

***

## Database Tables

| Table                      | Purpose                            | Status                                               |
| -------------------------- | ---------------------------------- | ---------------------------------------------------- |
| `pf_user_role_assignments` | User-to-role assignments           | ✅ Active                                             |
| `pf_roles`                 | Role definitions (custom + system) | ✅ Active                                             |
| `pf_role_permissions`      | Permission-to-role mappings        | ✅ Active                                             |
| `pf_permissions`           | Permission definitions             | ✅ Active                                             |
| `pf_user_roles`            | Legacy V1 table                    | 🗑️ Dropped (migrated to `pf_user_role_assignments`) |

***

## References

* [Comprehensive Guide](permissions-system-guide.md) - Detailed system documentation
* [PF-30 Specification](../../specs/pf/specs/PF-30-permissions-system-v2.md) - Complete specification
* [Module Permissions Matrix](module-permissions-matrix.md) - All available permissions
* [Permissions Component README](../architecture/integrations/index.md) - Component docs

***

**Last Updated:** 2025-01-25\
**Status:** Active Quick Reference
