Skip to content

Roles

Admin → Roles (/admin/roles) lists the five built-in roles and — on Command+ plans — lets a superadmin define custom roles with fine-grained permissions. The list of built-in roles is fixed; you cannot delete or rename them, only view what they can do.

Only superadmin can open this page. Everyone else gets redirected to the dashboard by the route guard.

The five built-in roles

From OrgRole in org.ts, in descending privilege:

RoleLevelBadgeTypical use
superadminL1redPlatform owner. Sees every org, can change plan, manage roles.
adminL2amberOrg administrator. Invites, billing, DJI, webhooks, workflows.
managerL3cyanTeam/shift lead. Runs missions, invites operators, no billing.
operatorL4greenPilot / field user. Joins missions, pilots drones, uses PTT.
observerL5greyView-only. Watches live feeds, cannot publish.

ADMIN_ROLES in code is ['superadmin', 'admin'] — those are the two roles the Firestore rules check for any write to an org-scoped document outside the user’s own profile.

Capability matrix

Capabilitysuperadminadminmanageroperatorobserver
Create / deactivate orgs, change plan
Invite members, change roles✓ (≤ own)✓ (op/obs)
Pair DJI docks, create venues/assets
Configure webhooks / workflows
Create missions, pilot (DRC), publish TACLINK
Subscribe to TACLINK (listen/watch)
Create custom roles
Export mission reports

The helper roleAtLeast(role, minimum) gates features throughout the code — e.g. roleAtLeast(me.role, 'manager') is the check for “can start a mission”.

Editing a built-in role

Click any built-in role on the left to open its detail pane. You can view the permission list but Edit is disabled — built-ins are the contract the Firestore rules trust. If you need a tweak, clone it into a custom role.

Custom roles (Command+ plans)

Custom roles ship on the Command and Sovereign plans; Guardian and Tactical see a padlock banner reading “Custom roles require Command plan or higher”. The feature flag is PlanFeatures.customRoles and the Firestore rules enforce it at write-time too.

Creating a custom role

Click Create role in the header. The form asks for:

  • Role name — free text, e.g. SAR Team Lead.
  • Description — one-liner shown in the member picker.
  • Hierarchy level — integer 5–99. Lower numbers have more privilege. Built-ins occupy levels 1–5 so custom roles always sit below.
  • Colour — picked from the 12-swatch palette. Drives the badge tint.
  • Permissions — multi-select checkbox grid grouped by module (Missions, Teams, DJI, Webhooks, Reports, …). Each permission is an {action}.{resource} string such as read.mission, write.flight_task, approve.workflow_step.

Save writes the role to /organizations/{orgId}/customRoles/{roleId} and it becomes selectable in the Users page role picker alongside the built-ins.

Assigning a custom role

On Users, the role dropdown shows built-ins then a divider then your custom roles. Assigning one sets OrgMember.customRoleId and leaves OrgMember.role at the built-in base (for Firestore-rules back-compat). The rules check custom roles first and fall back to the base role if the custom role doc is missing.

Deleting a custom role

Popover-confirmed. Any member currently holding the role is automatically downgraded to the base role field. Deletion is logged as admin.role.deleted in the audit stream.