Skip to content

Frontend Tasks Breakdown

This is written as an execution breakdown for the frontend team, aligned with the backend architecture already locked:

  • Auth returns identity and resolved access
  • Platform Core stays behind Auth for commercial entitlements
  • Frontend never decides truth
  • Frontend uses /auth/me and /auth/me/access?companyId=... as the main access inputs
  • Core App is shown only when Basic is active
  • Standalone modules can still work without Basic.

Frontend work should happen in this order:

  1. shared auth/session foundation
  2. company selection + x-org handling
  3. access bootstrap with /auth/me + /auth/me/access
  4. route guards + UI visibility system
  5. Core App tenant-management screens
  6. Platform Admin screens
  7. module frontend integration
  8. error states / refresh / edge cases
  9. observability / QA / rollout

Create one frontend auth/session foundation used by:

  • main app
  • platform admin
  • module UIs
  • define global auth state store

  • define current user state

  • define current session state

  • define current company state

  • define current access-context state

  • define loading states:

    • boot loading
    • login loading
    • access refresh loading
    • company switch loading
  • define logout flow

  • define refresh-token/session restore flow

At minimum:

type SessionState = {
accessToken: string | null
refreshToken: string | null
isAuthenticated: boolean
isBootstrapping: boolean
}
type UserState = {
id: string
email: string
name: string
globalRole: string | null
authType: string
isVendor: boolean
} | null
type ActiveCompanyState = {
companyId: string | null
xOrg: string | null
}
type AccessState = {
loaded: boolean
loading: boolean
data: AccessContext | null
error: string | null
}
  • app can persist session safely
  • app can restore session after refresh/reload
  • app can cleanly reset all state on logout

Create one shared HTTP client pattern for all frontend apps/modules.

  • build shared API client wrapper

  • automatically attach:

    • Authorization: Bearer <token>
    • x-org when request is tenant-scoped
  • centralize handling for:

    • 401 unauthorized
    • 403 forbidden
    • 404 not found
    • 429 rate-limited
    • 5xx server errors
  • support transparent refresh flow when access token expires

  • support retry after refresh if safe

  • never manually attach token in random components
  • never manually attach x-org in each module screen
  • use one central request layer
  • all frontend requests use one common client
  • token and company context are consistently attached

1.3 Frontend environment and routing setup

Section titled “1.3 Frontend environment and routing setup”

Prepare all frontend applications to work with the new auth/access flow.

Define environment variables for:

  • Auth base URL
  • Admin backend base URL
  • Basic backend base URL
  • Finance backend base URL
  • Market backend base URL
  • Touring backend base URL
  • Venue backend base URL
  • AI backend base URL

Define route groups for:

  • public routes
  • authenticated routes
  • platform-admin routes
  • tenant/core-app routes
  • module routes
  • frontend can switch dev/staging/prod cleanly
  • routing structure matches backend separation

Implement login for all relevant user types.

  • build login form

  • submit to POST /auth/login

  • handle success:

    • store tokens
    • call /auth/me
    • determine next route
  • handle failure states:

    • invalid credentials
    • pending approval
    • registration rejected
    • inactive account
    • rate limited
  • show loading state on submit
  • show API error message cleanly
  • prevent double-submit
  • clear stale session state before new login if needed
  • login works for normal users
  • login works for platform admins
  • auth errors are mapped correctly to UI

Restore session on reload without forcing user to log in again.

On app bootstrap:

  1. check stored access token

  2. if token exists, call /auth/me

  3. if token is expired or rejected, call /auth/refresh

  4. if refresh succeeds:

    • store new access token
    • re-run /auth/me
  5. if refresh fails:

    • clear session
    • send user to login
  • page reload does not log the user out unnecessarily
  • expired access token can recover via refresh flow
  • invalid refresh token forces clean logout

Implement clean logout UX.

  • call POST /auth/logout or POST /auth/logout-all depending on UI action

  • clear:

    • tokens
    • user state
    • company selection
    • access state
    • module caches
  • redirect to login

  • logout clears all auth-sensitive client state
  • user cannot continue navigating in cached protected routes

Make active-company selection explicit and safe.

  • after /auth/me, if multiple companies exist:

    • show company selector
  • if only one company exists:

    • auto-select it
  • when company selected:

    • set active company state
    • set x-org
    • call /auth/me/access?companyId=...
  • company switch must invalidate old access context in frontend state
  • company switch must trigger new access fetch
  • route guards must re-evaluate against new company context
  • user can switch company safely
  • UI updates correctly when company changes

Ensure tenant-scoped requests always use the correct company.

  • centralize x-org derivation from active company state

  • attach x-org automatically in shared HTTP client for:

    • Core App requests
    • module backend requests
  • do not attach x-org to public auth routes where not needed

  • tenant requests always carry correct company context
  • company switch immediately affects outgoing API calls

Load identity and membership summary after login/session restore.

  • create loadCurrentUser() action

  • call GET /auth/me

  • store:

    • user identity
    • session info
    • memberships summary
  • use response to decide:

    • platform-admin routes available?
    • company selector needed?
    • tenant routes available?
  • frontend can boot from /auth/me without needing full access context yet

Use one endpoint as the main access source for the current company.

  • create loadAccessContext(companyId) action

  • call GET /auth/me/access?companyId=...

  • store:

    • company
    • entitlements
    • membership granted modules
    • effective modules
    • permissions
    • delegation
    • meta/access version info
type AccessContext = {
user: {
id: string
email: string
name: string
}
company: {
id: string
tenantRole: string
}
entitlements: {
hasBasic: boolean
enabledModules: string[]
basePackage: string | null
addons: string[]
}
membership: {
grantedModules: string[]
effectiveModules: string[]
}
permissions: string[]
delegation: {
canManageUsers: boolean
grantableModules: string[]
grantablePermissions: string[]
}
meta: {
accessVersion: number
entitlementVersion: number
cached: boolean
generatedAt: string
}
}
  • frontend can fully render allowed UI based on this object
  • no module UI depends on guessing

Keep access context fresh.

  • login
  • hard reload
  • company switch
  • refresh-token recovery
  • after grant/revoke changes
  • after company subscription/add-on changes
  • after module purchase/upgrade
  • after 403 response that indicates stale access.
  • stale UI access is minimized
  • user sees updated modules and permissions quickly

5. Shared Route Guards and UI Authorization

Section titled “5. Shared Route Guards and UI Authorization”

Protect all authenticated routes.

Build guard that checks:

  • token present
  • user loaded
  • session not invalidated locally
  • bootstrapping complete
  • anonymous users cannot enter authenticated routes

Protect platform-admin-only routes.

Build guard that checks:

  • authenticated

  • globalRole is one of:

    • PLATFORM_SUPERADMIN
    • PLATFORM_ADMIN
    • PLATFORM_MODERATOR
  • platform admin dashboard
  • package/add-on/module management
  • organization approval screens
  • platform-level subscription management
  • tenant users cannot enter platform-admin screens

Protect tenant routes by active company + access context.

Build guard that checks:

  • active company selected
  • access context loaded
  • membership valid for company
  • user cannot enter tenant routes without valid company context

Protect module entry and screens.

Build reusable helper:

hasModule(access, "finance")
hasModule(access, "market")
hasModule(access, "basic")
  • Core App routes require:

    • hasBasic === true
    • effectiveModules contains basic
  • standalone module routes require:

    • effectiveModules contains module key
  • remember: modules can still exist even if Basic is false.

  • module navigation is correct for all combinations:

    • Basic only
    • modules only
    • Basic + modules

Protect finer-grained actions inside pages.

Build reusable helper:

hasPermission(access, "finance.expense.view")
hasPermission(access, "market.contract.create")

Use it for:

  • buttons
  • tabs
  • action menus
  • forms
  • create/edit/delete actions
  • bulk actions
  • approval actions
  • frontend visibility matches permission model
  • but backend still enforces final truth

This is the tenant control center when Basic is active.

Build the main tenant UI shell.

  • sidebar / navigation

  • top bar with company selector

  • user menu

  • access-aware navigation

  • route placeholders for:

    • dashboard
    • user management
    • grants/permissions
    • delegation
    • subscription/upgrade view
    • core/basic features
  • Core App appears only when Basic is active and granted
  • shell updates correctly when access changes

Let tenant admins manage users inside the company.

Create screens for:

  • company users list
  • invite/add user to company
  • membership detail page
  • activate/deactivate membership
  • role view/edit
  • business unit membership view if applicable
  • table with filters/search
  • role badge
  • module access summary
  • permission summary
  • delegation summary
  • status labels (active/inactive)
  • Core App can consume Auth tenant-management APIs cleanly

Allow authorized tenant users to assign modules to memberships.

Build UI for:

  • listing company enabled modules
  • showing current membership granted modules
  • toggling grants where allowed
  • do not show grant options for modules company does not own

  • disable controls for modules actor cannot grant

  • show reason if disabled:

    • company does not own module
    • actor delegation does not allow it
    • target role restrictions
  • grant UI reflects both entitlement and delegation

Allow authorized tenant users to assign fine-grained permissions.

Build UI for:

  • module-by-module permission groups
  • current permission assignments
  • add/remove permission actions
  • search/filter for permissions
  • bulk grant/revoke if needed
  • only show permissions belonging to modules company owns
  • only show permissions belonging to modules target user has or may receive
  • disable grant if actor lacks delegation
  • permission management is understandable and safe

Allow upper-role users to define what lower-role users can grant.

Build UI for:

  • see actor’s current delegation powers
  • set grantable modules for target role
  • set grantable permissions for target role
  • toggle canManageUsers style flags if applicable
  • clearly distinguish:

    • what user can use
    • what user can grant
  • avoid mixing access permissions with delegation permissions in same unclear component

  • delegation is manageable without confusing it with normal permissions

Let tenant-side users view or manage commercial state inside Core App, if self-service is enabled.

Build screens for:

  • current Basic status
  • current active add-ons
  • renewal/expiry dates
  • upgrade options
  • request/add module options
  • purchase/checkout initiation (if enabled)

Your doc says:

  • tenant-side purchase/upgrade flows may exist
  • TENANT_SUPERADMIN can buy/upgrade only if self-service billing is enabled for that tenant.

So frontend must:

  • check whether self-service billing is enabled

  • show:

    • “Buy / upgrade” actions when enabled
    • “Contact platform admin” or disabled state otherwise
  • Core App supports both models:

    • self-service billing
    • platform-admin-controlled commercial changes

Integrate Basic business features into Core App.

At minimum, prepare frontend routing/integration for:

  • artist data
  • event creation tools
  • calendar
  • vendor directory
  • venue directory
  • news/updates
  • ticketing creation
  • workspace/task management.

Exact business CRUD routes are still not fully locked in the uploaded docs, so frontend should prepare modular route groups and API adapters instead of hardcoding unfinished contracts.

  • Core App can host Basic features without coupling them to auth logic

This is the global platform-side admin system, distinct from tenant management.

Build the global admin workspace.

  • admin layout
  • platform-admin-only navigation
  • global search / context if needed
  • access-aware admin routes
  • admin session handling via Auth
  • dashboard
  • modules
  • packages
  • add-ons
  • permission types
  • organizations/customers
  • company approval
  • subscription management
  • platform admins have a distinct admin experience
  • tenant users cannot see these screens

Allow platform admins to create/update modules.

Build screens for:

  • list modules

  • create module

  • edit module

  • activate/deactivate module

  • module metadata view:

    • key
    • name
    • type
    • active state
  • admin can manage module catalog via Admin/Core backend

Allow platform admins to manage packages.

Build screens for:

  • list packages
  • create package
  • edit package
  • activate/deactivate package
  • map modules into package
  • inspect package composition
  • package catalog is manageable from frontend cleanly

Allow platform admins to manage add-ons.

Build screens for:

  • list add-ons
  • create add-on
  • edit add-on
  • activate/deactivate add-on
  • map modules into add-on
  • inspect add-on composition
  • add-on catalog is manageable from frontend cleanly

Allow platform admins to define permission catalog/types.

Build screens for:

  • list permission keys
  • create permission key
  • edit permission key
  • assign permission to module
  • group/filter permissions by module/category

Frontend must clearly represent:

  • permission catalog/type management (platform side) vs
  • permission assignment to users (tenant side)
  • no confusion between permission catalog and permission grants

7.6 Organization/customer approval screens

Section titled “7.6 Organization/customer approval screens”

Allow platform admins to approve and activate organizations/customers.

Build screens for:

  • pending organizations/customers
  • company detail
  • approval/rejection action
  • assign initial commercial state
  • set initial activation
  • onboarding is manageable from one admin workflow

7.7 Company subscription management screens

Section titled “7.7 Company subscription management screens”

Allow platform admins to manage company commercial state.

Build screens for:

  • company subscription summary
  • Basic activation/deactivation
  • add-on activation/deactivation
  • effective entitlements preview
  • expiry/renewal visibility
  • status history if available
  • platform admins can fully manage company commercial state from UI

These are the user-facing module UIs.

Make all module frontends follow the same entry and access pattern.

For every module frontend:

  • define entry route
  • check access before render
  • show denied state if module missing
  • use shared API client
  • use shared permission helpers for action visibility
  • do not duplicate auth logic inside each page
  • all modules feel consistent
  • auth/access logic is centralized in frontend helpers

Build frontend integration for Finance.

  • expenses list
  • expense detail
  • create expense
  • edit expense
  • income list
  • finance reports
  • ticketing finance reports
  • gate module entry on finance
  • gate actions on finance.* permissions
  • connect to Finance backend
  • map 403 to correct UI
  • refetch access if action fails due to stale permissions
  • Finance can operate standalone even when Basic is inactive.

Build frontend integration for Market.

  • contacts
  • artist hiring
  • contracts
  • funding/investment flows
  • gate module entry on market
  • gate actions on market.*
  • connect to Market backend
  • map denied states clearly
  • Market works standalone

Build frontend integration for Touring.

  • routing
  • travel
  • accommodation
  • coordination
  • gate module entry on touring
  • gate actions on touring.*
  • connect to Touring backend or shared Market/Touring API adapter
  • keep adapter abstract enough until final backend split is finalized
  • Touring UI can survive backend split decision later

Build frontend integration for Venue.

  • availability list/calendar
  • venue detail
  • search/filter views
  • gate module entry on venue
  • gate actions on venue.*
  • connect to Venue backend
  • Venue works standalone

Build frontend integration for AI.

  • predictions
  • research
  • valuation support
  • chat/tools as designed
  • gate module entry on ai
  • gate actions on ai.*
  • connect to AI backend
  • handle longer-running UI states if AI jobs/streaming are used
  • AI works standalone

Create consistent UX for:

  • unauthenticated
  • expired session
  • no company selected
  • no membership in selected company
  • Basic inactive
  • module not owned by company
  • module not granted to user
  • permission missing
  • stale access requiring refresh
  • users get clear, non-confusing messages
  • developers have one consistent pattern across app/admin/module UIs

Handle cases where frontend access state is stale.

When backend returns 403 for access-sensitive routes:

  • detect if this may be stale access
  • optionally refetch /auth/me/access
  • retry UI state update if appropriate
  • otherwise show forbidden state
  • app recovers gracefully after grant/subscription changes

Define loading UX for:

  • login
  • session restore
  • company switch
  • access fetch
  • module boot
  • admin catalog screens
  • tenant management screens
  • no blank screens during access bootstrap

Centralize access handling.

Create actions for:

  • setActiveCompany(companyId)
  • loadMe()
  • loadAccess(companyId)
  • clearAccess()
  • refreshSession()
  • logout()
  • no ad hoc access-fetch logic scattered in components

Create helpers such as:

  • isPlatformAdmin(user)
  • hasBasic(access)
  • hasModule(access, moduleKey)
  • hasPermission(access, permissionKey)
  • canManageUsers(access)
  • canGrantModule(access, moduleKey)
  • canGrantPermission(access, permissionKey)
  • all UI checks use shared helpers

Test:

  • auth store reducers/actions
  • access helpers
  • module guard helpers
  • permission helper logic
  • stale access handling
  • company switch state reset
  • access logic is test-covered and not only manual

Test:

  • login → /auth/me/auth/me/access
  • company switch
  • Core App visible only with Basic
  • standalone Finance visible without Basic
  • module hidden when not owned
  • permission-hidden actions
  • platform-admin route protection
  • tenant-management flows
  • access refresh after grant/subscription change
  • main user flows are covered

  • platform admin approves organization and activates modules
  • tenant superadmin logs in and sees allowed modules
  • tenant user with Finance only sees Finance and not Basic
  • tenant user loses module access and UI updates correctly
  • expired token refresh recovers session
  • logout clears app completely
  • full architecture assumptions are validated in browser behavior

Track frontend events such as:

  • login success/failure
  • session restore success/failure
  • access fetch success/failure
  • company switch
  • access denied view
  • 403 after action
  • module shown/hidden decisions
  • platform-admin approval actions
  • subscription change actions
  • frontend issues can be correlated with backend access behavior

  • login works
  • refresh works
  • logout works
  • /auth/me loads
  • /auth/me/access loads
  • company selection works
  • x-org propagation works
  • route guards work
  • only visible with Basic
  • tenant user management works
  • grants/permissions/delegation management works
  • tenant subscription visibility works
  • optional self-service purchase flow is supported correctly
  • global admin routes are protected
  • modules/packages/add-ons can be managed
  • organizations/customers can be approved
  • company subscription state can be managed
  • Finance, Market, Touring, Venue, AI all use shared access logic
  • standalone modules work without Basic
  • action-level permission checks are reflected in UI
  • denied states are correct and consistent

After this frontend task breakdown, the next useful artifact is:

  1. App/Core App sprint breakdown
  2. Platform Admin sprint breakdown
  3. Module frontend checklist per module