Platform Billing — Access Control
Platform Billing is FlowPOS (FIXX) internal staff tooling. It must never be available to a tenant business’s own owner or admins.
Who is allowed
| Actor | Menu / routes | API (PlatformAdminGuard) |
|---|---|---|
Active super on FIXX (is_platform_operator) | Yes | Yes |
Active owner on FIXX | Yes (when FIXX is the selected business) | Yes |
System super (any business selected) | Yes (menu + route bypass) | Only if they also have an active FIXX super/owner business_user link; otherwise API 403 |
| Owner / staff of any other business | No | No (403 FlowPOS staff access only.) |
FIXX is identified by business.is_platform_operator = true (one row per environment). The env-specific FIXX ids are set in migration 2026-07-24t11-00-00-flag-fixx-platform-operator.mjs — do not hardcode those UUIDs in the guard.
Layers
1. Backend — PlatformAdminGuard
Applied to:
GET/PATCH/POST /platform-billing/accounts…/platform-billing/plans…/platform-billing/jobs…/platform-billing/payment-methods…
Checks the DB for an active business_user whose:
business.is_platform_operator = trueunique_role_name∈{ super, owner }(PLATFORM_BILLING_ADMIN_ROLES)
It deliberately does not use RolesGuard / “current business” JWT claims — this surface administers many tenants and must resolve FIXX membership directly.
2. PWA menu — Remote Config + MenuAccessProvider
Remote Config (pwaMenu) declares Platform Billing with roles super and owner and module key platformBillingModule.
That module is not a seeded tenant business_module. Filtering therefore:
- System
super→ sees all active menu items (existing bypass). platformBillingModule→ shown only whencurrentBusiness.isPlatformOperatorand the user’s role is allowed by the item’sroles.- Other modules → still require an enabled business module key.
isPlatformOperator is returned with the user’s businesses payload and mapped in useUserData onto CurrentBusiness. Stale localStorage selections are refreshed when user data loads.
3. Route wrapper — AuthorizedRoute
Paths under /platform-billing/* are gated by authorizedPaths from the filtered menu (system super still bypasses). Pages also treat API 403 as a forbidden state (platformBilling.forbidden).
Operator checklist
- User must have a
business_userrow on FIXX with roleownerorsuperandis_active = true. - In the PWA, select FIXX in the business switcher (owners only see the menu while FIXX is current).
- Confirm
business.is_platform_operatoris true for that FIXX id in the current environment.
Related code
- Guard:
apps/backend/src/platform-billing/infrastructure/platform-admin.guard.ts - Roles constant:
PLATFORM_BILLING_ADMIN_ROLESinplatform-billing.constants.ts - Menu filter:
apps/frontend-pwa/src/contexts/MenuAccessProvider.tsx - Menu config:
config/firebase/remote-config/pwaMenu.json(platformBillingModule)