Skip to main content

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.

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

// 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

// V1 (Hardcoded)
const roleLabel = ROLE_CONFIG[role]?.label || role;

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

Role Sorting

// 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