RIO Web App
The React + TypeScript frontend. Consumes every backend service through the single App Layer gateway, authenticating with Cognito OIDC.
Service Overview
The user-facing application. React 18 + TypeScript on Vite 6, with TailwindCSS for styling and ApexCharts for visualisation.
It is included in this catalog because it is the platform’s only human-facing consumer — knowing which endpoints it actually calls tells you which parts of the backend are genuinely in use.
Notably, it is built as a Module Federation remote (@originjs/vite-plugin-federation), exposed
as rioUi with a ./bootstrap entry and a default base path of /rio/. It is designed to be mounted
inside a host shell rather than served standalone.
One base URL, one front door
Every request goes through a single environment variable, VITE_API_BASE_URL (src/lib/env.ts:31),
pointing at the Application Layer Service.
src/lib/httpClient.ts is the only client: it attaches Authorization: Bearer <token> and
X-User-Id, raises a typed ApiError, and redirects to /auth/login on a 401.
There are no per-service hostnames anywhere in src/, which independently confirms that all
traffic is funnelled through the gateway.
Authentication is Cognito via react-oidc-context, matching the Lambda authorizer on the gateway side.
Which service each screen actually talks to
| Frontend module | Endpoints | Backing service |
|---|---|---|
features/auth/authService.ts | /users/tenants, /tenants/{t}/users/{u} | Identity |
features/admin/api/usersService.ts | /tenants/{t}/users | Identity |
features/admin/api/rolesService.ts | /tenants/{t}/roles | Identity |
features/admin/api/userGroupsService.ts | /tenants/{t}/user-groups | Identity |
features/admin/api/hierarchyService.ts | /tenants/{t}/hierarchy, .../actions, .../nodes/{n} | Identity |
features/admin/api/tagsService.ts | /tenants/{t}/tags | Identity |
features/admin/api/regionsService.ts | /tenants/{t}/regions | Identity |
features/admin/api/timezonesService.ts | /tenants/{t}/timezones | Identity |
features/admin/api/auditService.ts | /tenants/{t}/audits | Audit |
features/forecast/api/forecastService.ts | /tenants/{t}/forecast/* | Commit |
features/quota/api/quotaService.ts | /tenants/{t}/quotas* | Commit |
features/forecast/api/opportunityService.ts | /tenants/{t}/opportunities* | Opportunity |
features/deal-desk/api/dealDeskBriefService.ts | .../quotes*, .../sales-team, .../install-base, /products/discount-benchmarks, /activity/opportunities/{id}/email-summary, .../threads | Opportunity + Activity Signal |
Two things worth knowing
One module bypasses the shared client. features/admin/api/auditService.ts builds its URL by
hand (${env.apiBaseUrl}/tenants/${tenantId}/audits…, line 137) and calls raw fetch (line 153)
instead of going through httpClient. So it does not get the shared 401-redirect or ApiError
handling that every other module gets.
Several screens are still fixture-driven. src/mocks/fixtures/ and src/mocks/handlers/ supply
mock data for the dashboard, assess, deal desk, exec dashboard, coverage-behind-call, admin console
and chart surfaces. Those pages render from fixtures, not from live APIs — so “the UI shows it” is
not evidence that an endpoint exists.
It uses no events
The web app has no EventBridge, WebSocket, SSE or GraphQL client. All communication is request / response over HTTPS through the gateway. It also does not call Cube or the MCP server directly.