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.

Date: 2026-02-22
Goal: Ensure organization admins have access to all features (no missing permissions).

Summary

  • Fix applied: Migration 20260222140000_org_admin_all_permissions_and_rh_seed.sql does two things:
    1. RH permission seed — Inserts all RH module permission keys (from src/platform/permissions/constants.ts plus rh.compliance.create and rh.staff-operations.create used in the app) into pf_module_permissions if missing. This ensures keys like rh.beds.view exist so UI permission checks resolve.
    2. Org admin backfill — Grants every active row in pf_module_permissions to the org_admin role where not already granted. So org admins have access to every permission that exists in the system.

Why the Bed Board was blank

  • The Bed Board page is gated by rh.beds.view.
  • If that key was never seeded into pf_module_permissions, or was added in a way that didn’t trigger the existing “auto-grant to org_admin” logic, org admins had no grant and saw the “Access restricted” (or blank) state.
  • The migration fixes this by (1) ensuring rh.beds.view and all other RH keys exist, and (2) guaranteeing org_admin has every active permission.

Permissions added/ensured (RH)

All of the following are inserted with ON CONFLICT (permission_key) DO NOTHING so existing rows are unchanged:
  • Admin: rh.beds.admin, rh.beds.view, rh.beds.edit, rh.programs.admin, rh.programs.view, rh.programs.edit, rh.residences.admin, rh.settings.admin, rh.settings.view
  • Approve: rh.passes.approve
  • Create: rh.attendance.create, rh.charges.create, rh.chores.create, rh.curfew-checks.create, rh.episodes.create, rh.med-audits.create, rh.notes.create, rh.passes.create, rh.residents.create, rh.schedule-templates.create, rh.significant-events.create, rh.transport.create, rh.uds-tests.create, rh.compliance.create, rh.staff-operations.create
  • Edit: rh.attendance.edit, rh.charges.edit, rh.episodes.edit, rh.notes.edit, rh.programs.edit, rh.residents.discharge, rh.residents.edit, rh.significant-events.edit, rh.uds-tests.edit
  • View: rh.audits.view, rh.charges.view, rh.census.export, rh.census.view, rh.compliance.view, rh.dashboard.view, rh.notes.view, rh.passes.view, rh.programs.view, rh.residents.view, rh.transport.view, rh.staff-operations.view

Org admin backfill

  • Statement:
    INSERT INTO pf_role_permissions (system_role, permission_id, organization_id) SELECT 'org_admin', mp.id, NULL FROM pf_module_permissions mp WHERE mp.is_active = true AND NOT EXISTS (...) ON CONFLICT DO NOTHING.
  • Effect: Every active permission in pf_module_permissions is granted to org_admin (for organization_id IS NULL) if not already present. This covers all modules (HR, FA, RH, CL, PM, etc.), not only RH.

After applying the migration

  1. Run migrations (e.g. supabase db push or your usual process).
  2. Org admins will have all active permissions, including rh.beds.view, so the Bed Board and other gated RH (and non-RH) features should be visible.
  3. If you use a cached permission list in the app, users may need to refresh or re-login so the client sees the updated permissions.

Ongoing behavior

  • New permissions added via INSERT INTO pf_module_permissions are auto-granted to org_admin by the existing trigger trg_auto_grant_org_admin (see migration 20260216012710).
  • This migration’s backfill is idempotent and safe to run again; it only inserts missing grants.