Skip to content

[Due for payment 2026-05-29] [Workspace Roles] Release 0: Build frontend permission system foundation #90496

@flodnv

Description

@flodnv

Part of the Workspace Roles project. This is the shared foundation all subsequent frontend releases depend on and must land first.

Goal: Add the constants, types, and hasPolicyPermission utility that let the rest of the app gate UI by feature and access level instead of by role.

src/CONST/index.ts — add constants

POLICY: {
  ROLE: {
    ADMIN: 'admin',
    AUDITOR: 'auditor',
    USER: 'user',
    CARD_ADMIN: 'cardAdmin',
    PEOPLE_ADMIN: 'peopleAdmin',
    PAYMENTS_ADMIN: 'paymentAdmin',
  },
  FEATURE: {
    EXPENSIFY_CARD: 'expensifyCard',
    COMPANY_CARDS: 'companyCards',
    WORKFLOWS_APPROVALS: 'workflowsApprovals',
    WORKFLOWS_PAYMENTS: 'workflowsPayments',
    MEMBERS: 'members',
    ASSIGN_ELEVATED_ROLES: 'assignElevatedRoles',
    OVERVIEW: 'overview',
  },
  FEATURE_ACCESS: {
    WRITE: 'write',
    READ: 'read',
    NONE: 'none',
  },
}

src/CONST/index.ts — add ROLE_PERMISSION_BUNDLES

Define a map from each role to its feature access levels using CONST.POLICY.FEATURE_ACCESS constants inline (no intermediate variable):

const ROLE_PERMISSION_BUNDLES: Record<string, Record<string, ValueOf<typeof CONST.POLICY.FEATURE_ACCESS>>> = {
  admin:          { overview: 'write', expensifyCard: 'write', companyCards: 'write', ... },
  auditor:        { overview: 'read', expensifyCard: 'read', ... },
  cardAdmin:      { overview: 'read', expensifyCard: 'write', companyCards: 'write', members: 'read', ... },
  peopleAdmin:    { overview: 'read', members: 'write', workflowsApprovals: 'write', assignElevatedRoles: 'write', ... },
  paymentAdmin:   { overview: 'read', workflowsPayments: 'write', members: 'read', ... },
  user:           { overview: 'read', members: 'read' },
};

(Full bundle per design doc)

src/libs/PolicyUtils.ts — add hasPolicyPermission

function hasPolicyPermission(
  policy: OnyxEntry<Policy>,
  login: string,
  feature: ValueOf<typeof CONST.POLICY.FEATURE>,
  requiredAccess: ValueOf<typeof CONST.POLICY.FEATURE_ACCESS>,
): boolean
  • Look up the member's role in policy.employeeList[login]
  • Fetch the bundle from ROLE_PERMISSION_BUNDLES[role]
  • write implies read; none or missing → false

src/types/onyx/PolicyEmployee.ts

  • Change role?: string to role?: ValueOf<typeof CONST.POLICY.ROLE>
Issue OwnerCurrent Issue Owner: @mallenexpensify

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionDailyKSv2EngineeringNewFeatureSomething to build that is a new item.

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions