> ## 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.

# Object Permissions Tab V2 Migration Plan

> Component: src/platform/data-manager/components/ObjectPermissionsTab.tsx Status: ✅ Migration Complete Sunset Date: 2026-03-31 (for V1 constants removal) Create…

**Component:** `src/platform/data-manager/components/ObjectPermissionsTab.tsx`\
**Status:** ✅ Migration Complete\
**Sunset Date:** 2026-03-31 (for V1 constants removal)\
**Created:** 2026-01-26\
**Completed:** 2026-01-26\
**Related Specs:** PF-26 (Object Permissions), PF-30 (Permissions System V2)

***

## Overview

The `ObjectPermissionsTab` component currently uses V1 role patterns (hardcoded `ORDERED_ROLES` and `ROLE_CONFIG`). This migration updates it to use V2 permissions system with dynamic role fetching.

***

## Current State (V1)

**Issues:**

* Uses hardcoded `ORDERED_ROLES` array (only 5 core roles)
* Uses hardcoded `ROLE_CONFIG` object
* Doesn't include all system roles (18 total, only shows 5)
* Doesn't support custom roles
* Role list is static and doesn't reflect database state

**Files:**

* `src/platform/data-manager/components/ObjectPermissionsTab.tsx` - Main component
* `src/platform/data-manager/components/ObjectPermissionMatrix.tsx` - Matrix display
* `src/platform/data-manager/types/permissions.ts` - Type definitions with V1 constants

***

## Target State (V2)

**Goals:**

* Fetch all system roles dynamically (all 18 roles from `app_role` enum)
* Support custom roles (when PF-26 is updated to support them)
* Use V2 permission system hooks
* Remove hardcoded role constants
* Make role list dynamic and database-driven

**Implementation:**

* Use `useAvailableRoles()` hook to fetch roles
* Update `ObjectPermissionsTab` to use dynamic roles
* Update `ObjectPermissionMatrix` to work with dynamic roles
* Keep PF-26 tables (`pf_object_permissions`, `pf_field_permissions`) - these are V2 compatible

***

## Migration Steps

### Step 1: Create Role Fetching Hook ✅

**File:** `src/platform/data-manager/hooks/useAvailableRoles.ts`

**Purpose:** Fetch all available roles (system + custom) for object permissions configuration.

**Status:** ✅ Complete

### Step 2: Update ObjectPermissionsTab ✅

**Changes:**

1. Replace `ORDERED_ROLES` import with `useAvailableRoles()` hook
2. Update role initialization to use dynamic roles
3. Remove dependency on hardcoded `ROLE_CONFIG`
4. Use role labels from hook

**Files Updated:**

* `src/platform/data-manager/components/ObjectPermissionsTab.tsx` ✅

**Status:** ✅ Complete

### Step 3: Update ObjectPermissionMatrix ✅

**Changes:**

1. Remove `ROLE_CONFIG` import
2. Use dynamic role labels from props (via `PermissionMatrixRow.roleLabel`)
3. Remove sorting logic (parent component handles ordering)

**Files Updated:**

* `src/platform/data-manager/components/ObjectPermissionMatrix.tsx` ✅

**Status:** ✅ Complete

### Step 4: Update FieldPermissionsSection ✅

**Changes:**

1. Replace `ORDERED_ROLES` and `ROLE_CONFIG` with `useAvailableRoles()` hook
2. Use `getRoleLabel()` helper for display names
3. Filter roles dynamically (exclude platform\_admin and org\_admin)

**Files Updated:**

* `src/platform/data-manager/components/FieldPermissionsSection.tsx` ✅

**Status:** ✅ Complete

### Step 5: Update Type Definitions ✅

**Changes:**

1. Mark `ORDERED_ROLES` and `ROLE_CONFIG` as deprecated
2. Add migration notes
3. Keep types for backward compatibility during transition

**Files Updated:**

* `src/platform/data-manager/types/permissions.ts` ✅

**Status:** ✅ Complete

### Step 6: Testing ⏳

**Test Cases:**

1. Verify all 18 system roles appear in matrix
2. Verify role ordering is correct
3. Verify permissions can be saved for all roles
4. Verify custom roles appear (when supported)
5. Verify backward compatibility with existing permissions

**Status:** ⏳ Pending

***

## Implementation Details

### Role Fetching

```typescript theme={null}
// V1 (Hardcoded)
import { ORDERED_ROLES, ROLE_CONFIG } from '../types/permissions';
const roles = ORDERED_ROLES; // Only 5 roles

// V2 (Dynamic)
import { useAvailableRoles } from '../hooks/useAvailableRoles';
const { roles } = useAvailableRoles(); // All 18 system roles + custom roles
```

### Role Display

```typescript theme={null}
// V1 (Hardcoded)
const roleLabel = ROLE_CONFIG[role]?.label || role;

// V2 (Dynamic)
import { getRoleLabel } from '../hooks/useAvailableRoles';
const roleLabel = getRoleLabel(role);
```

### Role Sorting

```typescript theme={null}
// V1 (Hardcoded)
const sorted = roles.sort((a, b) => {
  const orderA = ROLE_CONFIG[a.role]?.order ?? 99;
  const orderB = ROLE_CONFIG[b.role]?.order ?? 99;
  return orderA - orderB;
});

// V2 (Dynamic)
import { getRoleOrder } from '../hooks/useAvailableRoles';
const sorted = roles.sort((a, b) => 
  getRoleOrder(a.role) - getRoleOrder(b.role)
);
```

***

## Database Compatibility

**PF-26 Tables (Already V2 Compatible):**

* `pf_object_permissions` - Uses `app_role` enum (supports all system roles)
* `pf_field_permissions` - Uses `app_role` enum (supports all system roles)

**No Database Changes Required:**

* Tables already support all system roles
* Migration is UI-only (removing hardcoded constants)

***

## Custom Roles Support (Future)

**Current Status:** Custom roles are not yet supported in `pf_object_permissions` table.

**Future Enhancement:**

* Update `pf_object_permissions.role` column to support both `app_role` and custom role IDs
* Or create separate `pf_object_permissions_custom` table
* Update `useAvailableRoles()` to include custom roles when supported

**Note:** The hook is already prepared for custom roles - just needs database schema update.

***

## Rollback Plan

If issues arise:

1. Revert to using `ORDERED_ROLES` and `ROLE_CONFIG` constants
2. Component will continue to work (just shows fewer roles)
3. No data loss (all permissions remain in database)

***

## Testing Checklist

* [ ] All 18 system roles appear in permission matrix
* [ ] Roles are sorted correctly (by order)
* [ ] Role labels display correctly
* [ ] Permissions can be saved for all roles
* [ ] Existing permissions load correctly
* [ ] Field permissions work with all roles
* [ ] Site scope configuration works
* [ ] Component handles loading states
* [ ] Component handles error states
* [ ] No console errors or warnings

***

## Timeline

* **2026-01-26:** Migration plan created, `useAvailableRoles` hook created ✅
* **2026-01-26:** Updated ObjectPermissionsTab component ✅
* **2026-01-26:** Updated ObjectPermissionMatrix component ✅
* **2026-01-26:** Updated FieldPermissionsSection component ✅
* **2026-01-26:** Updated type definitions with deprecation notices ✅
* **2026-XX-XX:** Testing and validation ⏳
* **2026-03-31:** Sunset date - V1 constants can be removed after this date

***

## See Also

* [PF-26 Object Permissions Spec](../../specs/pf/specs/PF-26-object-permissions.md)
* [PF-30 Permissions System V2 Spec](../../specs/pf/specs/PF-30-permissions-system-v2.md)
* [Permissions System Guide](../pf/permissions-system-guide.md)
