Admin overview
The Admin section is where an organisation is configured. It appears in the
left nav only for members whose OrgMember.role is admin or superadmin
(managers get a cut-down view of Users only). Every change here takes effect
org-wide and immediately — there is no staging environment.
Routes are mounted under /admin/* and guarded by orgRoleGuard. If you land
on a page with the wrong role you are redirected to the dashboard.
Sections
| Section | Path | Manages | Minimum role |
|---|---|---|---|
| Organizations | /admin/org | Org profile, logo, contact, plan | admin |
| Users | /admin/users | Members, invites, role changes | manager |
| Roles | /admin/roles | Built-in and custom RBAC | superadmin |
| Teams | /teams | Sub-units, leaders, PTT channels | admin |
| Venues | /admin/venues | Named sites with bounding polygons | admin |
| Assets | /admin/assets | Vehicles, radios, batteries, gear | admin |
| Webhooks | /admin/webhooks | Outbound HTTP integrations | admin |
| Workflows | /admin/workflows | Trigger → condition → action automations | admin |
| DJI management | /admin/dji | Paired docks, firmware, FlySafe, logs | admin |
| Subscription | /admin/subscription | Plan tier and feature flags | superadmin |
Org switcher
If your account belongs to more than one org, a selector sits in the top-right
of every admin page. It writes to OrgService.activeOrgId and every list on
the page re-queries against the selected org.
Audit log
Every admin write emits an admin.* event into the org audit stream (for
example admin.user.invited, admin.role.updated, admin.webhook.created,
admin.dji.dock.unpaired). On the Command and Sovereign plans these
events are written to the immutable audit log (WORM-backed); on Tactical
they are rotated after 180 days; Guardian keeps a basic 30-day ring
buffer. See the Subscription page for plan-level
retention.
Who can read vs. write
Admin pages mostly follow the same rule: anyone with the right role sees the
full read view, but mutating actions (Save, Invite, Delete, Unpair, Regenerate
Secret, etc.) are gated a second time by the Firestore rules in
firestore.rules. A user demoted mid-session can still see the page but will
get “permission-denied” toasts on any write.
Some actions have an extra guard on top of role:
- Plan changes are
superadmin-only and are mirrored to/organizations/{orgId}.plan. - Custom role creation requires the Command plan or higher (the page shows a padlock and upgrade hint on lower plans).
- Deactivating an org requires you to type the org name to confirm.
- Unpairing a DJI dock requires a second click on the confirm popover.
Conventions
- TACLINK is the real-time fabric (audio, video, PTT, telemetry). You will
see
taclink.*minute counters on the Subscription page. - Firestore paths use the
/organizations/{orgId}/...prefix for anything org-scoped. Webhooks are the exception (/webhooks/{id}with anorgIdfield). - All forms persist with a toast confirmation; there is no separate “save draft” — closing the form without clicking Save discards changes.
- Destructive actions use the red
tac-btn--dangerstyle and require a popover confirm click-through.