Saltar al contenido principal

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

ActorMenu / routesAPI (PlatformAdminGuard)
Active super on FIXX (is_platform_operator)YesYes
Active owner on FIXXYes (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 businessNoNo (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 = true
  • unique_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:

  1. System super → sees all active menu items (existing bypass).
  2. platformBillingModule → shown only when currentBusiness.isPlatformOperator and the user’s role is allowed by the item’s roles.
  3. 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

  1. User must have a business_user row on FIXX with role owner or super and is_active = true.
  2. In the PWA, select FIXX in the business switcher (owners only see the menu while FIXX is current).
  3. Confirm business.is_platform_operator is true for that FIXX id in the current environment.
  • Guard: apps/backend/src/platform-billing/infrastructure/platform-admin.guard.ts
  • Roles constant: PLATFORM_BILLING_ADMIN_ROLES in platform-billing.constants.ts
  • Menu filter: apps/frontend-pwa/src/contexts/MenuAccessProvider.tsx
  • Menu config: config/firebase/remote-config/pwaMenu.json (platformBillingModule)