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.

Version: 2.0.0
Created: 2025-12-12
Last Updated: 2026-01-26
Status: Phase 2 (Hard Deprecation) - COMPLETE
Target Removal: Q2 2026
Related Spec: PF-30 (Permissions System V2)

Overview

The pf_user_roles table is being deprecated in favor of the new Permissions System V2, which uses:
  • pf_user_role_assignments - User role assignments with site scoping
  • pf_role_permissions - Permission mappings for system and custom roles
  • pf_custom_roles - Organization-defined custom roles
  • pf_module_permissions - Granular permission definitions

Deprecation Timeline

Phase 1: Soft Deprecation (COMPLETE)

Duration: 2025-12-12 - 2025-12-23
ItemStatus
New system (pf_user_role_assignments) active
Data migrated from pf_user_roles
Feature flag (permissions_v2_enabled) controls system✅ (Historical)
pf_user_roles still exists (read-only for fallback)
Code uses hasMinimumRole() with V1 fallback✅ (Removed)

Phase 2: Hard Deprecation (COMPLETE)

Duration: 2025-12-23 - 2026-01-26
ItemStatus
pf_user_roles becomes read-only
hasMinimumRole() removed from codebase
All code uses V2 permission system
All organizations migrated to V2
Feature flag logic removed
Completed Actions:
  • ✅ Removed all minRole checks from code
  • ✅ Removed hasMinimumRole() usage from components
  • ✅ All organizations have V2 enabled (mandatory)
  • ✅ Removed usePermissionsV2Enabled hook
  • ✅ Removed isV2Enabled() from PermissionService
  • ✅ Updated documentation to reflect V2 is mandatory

Phase 3: Removal

Duration: After 180 days (Q3 2026)
ItemStatus
pf_user_roles table archived🗑️
hasMinimumRole() function removed🗑️
V1 fallback logic removed from PermissionService🗑️
minRole property removed from navigation items🗑️
Action Required:
  • Final migration verification
  • Archive pf_user_roles to pf_user_roles_archive
  • Remove minRole from all navigation item definitions
  • Clean up V1 compatibility code from codebase

Tables Affected

TableCurrent StatePhase 1Phase 2Phase 3
pf_user_rolesActiveDeprecatedRead-onlyArchived
pf_user_role_assignmentsActiveActiveActiveActive
pf_role_permissionsActiveActiveActiveActive
pf_custom_rolesActiveActiveActiveActive
pf_module_permissionsActiveActiveActiveActive

Migration Checklist

For Developers

Code Changes

  • Replace user.role === 'admin' with useHasPermission('module.entity.admin')
  • Replace hasMinimumRole(role, 'staff') with hasPermission('module.entity.view')
  • Add permission property to all navigation items
  • Update RLS policies to use pf_has_permission() helper
  • Remove direct references to pf_user_roles table
  • Add permission property to module nav items
  • Add permission property to nav groups
  • Keep minRole as fallback (Phase 1 only)
  • Test navigation filtering with V2 enabled

Testing

  • Update unit tests to mock V2 permission hooks
  • Add RLS tests for permission-based policies
  • Test navigation visibility for different roles
  • Verify custom roles work correctly

For Org Admins

  • Enable V2 in Organization Settings → Security → Permissions
  • Verify all users can access expected features
  • Create custom roles if specialized access needed
  • Assign permissions to custom roles
  • Review audit logs for permission denials

Rollback Procedure

Quick Rollback (Disable V2) - NO LONGER SUPPORTED

Note: V2 is now mandatory. Rollback to V1 is not supported. The permissions_v2_enabled column exists for historical purposes only and is not checked by the application code. If critical issues arise, contact the Platform Foundation team for assistance.

Full Rollback (Admin Only)

If critical issues require complete rollback:
-- Run the rollback function
SELECT pf_rollback_v2_migration();
This will:
  • Delete all pf_user_role_assignments records tagged with _migrated_from_v1
  • Delete all system role permission mappings from pf_role_permissions
  • NOT delete records from the original pf_user_roles table (preserved for safety)

Re-Migrate After Rollback

If you need to re-migrate after a rollback:
-- Re-run the migration
SELECT pf_migrate_to_v2_permissions();

-- Verify the migration
SELECT pf_verify_v2_migration();

Compatibility Matrix

FeatureV1 (minRole)V2 (permission)Migration Path
Role hierarchy✅ (via system roles)Automatic
Site-scoped accessNew feature
Custom rolesNew feature
Granular permissionsNew feature
Navigation filtering✅ (minRole)✅ (permission)Add permission prop
RLS policies✅ (role-based)✅ (permission-based)Update policies

Code Examples

Before (V1)

// Component
if (hasMinimumRole(userRole, 'org_admin')) {
  return <AdminPanel />;
}

// Navigation
{
  label: 'Settings',
  path: '/settings',
  minRole: 'org_admin',
}

// RLS Policy
CREATE POLICY "admin_access" ON some_table
USING (pf_get_user_role(auth.uid()) IN ('org_admin', 'platform_admin'));

After (V2)

// Component
import { useHasPermission, PermissionGate } from '@/platform/permissions';

const hasAdminAccess = useHasPermission('module.admin');
if (hasAdminAccess) {
  return <AdminPanel />;
}

// Or using PermissionGate
<PermissionGate permission="module.admin">
  <AdminPanel />
</PermissionGate>

// Navigation
{
  label: 'Settings',
  path: '/settings',
  permission: 'system.settings.admin',
  minRole: 'org_admin', // Fallback for V1 orgs
}

// RLS Policy
CREATE POLICY "admin_access" ON some_table
USING (pf_has_permission(auth.uid(), organization_id, 'module.admin'));

Monitoring

Key Metrics to Track

During the deprecation period, monitor:
  1. Permission check latency - V2 should be <50ms
  2. V1 fallback rate - Should decrease over time
  3. Permission denial rate - Watch for unexpected increases
  4. Custom role adoption - Measure V2 feature usage

Telemetry Events

The PermissionService logs the following events:
EventDescription
permission.check.v2V2 permission check executed
permission.check.v1_fallbackFell back to V1 role check
permission.deniedPermission was denied
permission.cache.hitCache hit (performance)

Contact

For questions about this deprecation:
  • Spec Owner: Platform Foundation Team
  • Documentation: See specs/pf/permissions-v2-migration.md
  • Rollout Guide: See specs/pf/permissions-v2-rollout.md

Changelog

DateVersionChange
2025-12-121.0.0Initial deprecation plan created
2026-01-262.0.0Phase 2 (Hard Deprecation) marked complete - V2 is mandatory, feature flag removed