Application architecture overview
Application architecture overview
What this app is
This repository is a single-page React frontend for the DeepAI OCR platform. The runtime is mounted from src/index.jsx, which renders App into #root. App.jsx is the composition root: it decides which shell a user sees, wires auth and consent state, and mounts the route tree for the whole product.
The app splits into three major runtime shells:
- Public marketing shell via
PublicLayoutand the landing/marketing pages. - Authenticated workspace shell via the main app layout in
App.jsxand the protected route group. - Admin shell via
AdminRouteandAdminLayout.
Root composition and route tiers
App.jsx uses React Router and several providers to compose the UI.
Shell responsibilities
- Public routes: marketing pages, product pages, legal pages, and the in-app documentation site.
- Protected workspace routes: AI Studio, Processing Hub, Contract Analysis, Schema Generator, Prompt Generator, Settings, Help, and models/chat routes.
- Admin routes: dashboard, document types, model types, use case configuration, prompt library, countries, and activity log.
Key providers and shared state
At the root, the app combines several state domains:
AuthProviderandMsalAuthProviderfor legacy and Azure auth state.BackendAuthProviderfor backend token/session exchange.ProcessingHubProvider,SharedDataProvider,LiveTestResultsProvider,SchemaGeneratorProvider,PromptGeneratorProvider, andContractAnalysisProviderfor workspace state.FluentProviderinside the protected shell for theme selection.NotificationContainerandLicenseModalfor cross-cutting UI concerns.
Runtime routing structure
flowchart TD index[src/index.jsx] --> app[App.jsx] app --> public[PublicLayout + public routes] app --> auth[Auth / consent / onboarding routes] app --> workspace[Protected workspace shell] app --> admin[AdminRoute -> Admin layout/routes]
public --> landing[LandingPage] public --> marketing[Platform / Solutions / Resources / Legal] public --> docs[UserDocumentation]
workspace --> models[/models + /models/:id/] workspace --> settings[/settings] workspace --> ai[AI Studio] workspace --> proc[Processing Hub] workspace --> contract[Contract Analysis] workspace --> schema[Schema Generator route family] workspace --> prompt[Prompt Generator route family] workspace --> help[Help]
admin --> dashboard[Admin dashboard] admin --> promptlib[Prompt library] admin --> usecase[Use case configuration] admin --> activity[Activity log]Lazy loading and loading/error boundaries
Most page-level routes are loaded with React.lazy in App.jsx and rendered inside a single Suspense boundary. That keeps the initial shell light while delaying heavy page bundles until navigation.
The protected workspace also wraps its routed content in an ErrorBoundary defined in App.jsx. That boundary is intentionally narrow: it catches render crashes in the content tree and shows a reset button without taking down the whole app shell.
Scroll and layout rules
App.jsx distinguishes between routes that behave like standalone app screens and routes that behave like scrollable content pages.
- App-like routes such as
/schema-generator,/prompt-generator,/processing-hub,/contract-analysis,/prompt-library, and/modelsdisable outer scrolling and rely on internal scroll containers. - Content pages use normal page scrolling within the protected shell.
ScrollToTop resets browser scroll position on every route change for the content shell, preventing stale scroll positions from leaking between pages.
Public shell vs protected shell vs admin shell
The shells are intentionally separate because they solve different UX problems:
PublicLayoutowns marketing navigation, footer, auth modal, and marketing chatbot.- The protected shell in
App.jsxowns the persistent sidebar, topbar, workspace providers, and route-level auth/consent gating. AdminLayoutowns the admin sidebar/topbar, tenant branding display, and admin navigation chrome.
AdminRoute decides whether the admin shell is reachable. It considers both Firebase and Azure auth state and resolves the effective role with resolveEffectiveRole.
Auth and consent boundaries in the root
The root composition is not just navigation; it is also the access-control boundary.
App.jsx reads auth state from useAuth() and useMsalAuth(), then gates the main workspace on consent and login state. The Azure/MSAL path also restores backend user state and tenant selection when available. That means the route tree is coupled to storage-backed auth state, not just in-memory React state.
For the auth details, see Authentication overview. For the consent and tenant flow, see Consent and tenant services.
Entry points and dependencies
src/index.jsxis the browser entrypoint.src/App.jsxis the route composition root.src/components/home/PublicLayout.jsxowns the public shell.src/admin/AdminRoute.jsxandsrc/admin/AdminLayout.jsxown the admin shell.src/components/common/toolshell/ToolPageShell.jsxis the shared inner shell for generator-style pages.src/components/sidebar/Sidebar.jsxandsrc/components/Topbar/Topbar.jsxare the always-visible workspace chrome.
Focused validation
Use the route and shell tests plus the auth/service contracts when changing architecture:
src/components/sidebar/Sidebar.test.jsxfor workspace chrome behavior.src/components/Topbar/Topbar.test.jsxfor topbar behavior.- Contract tests in
tests/contract/client.test.js,tests/contract/schemaService.test.js,tests/contract/promptService.test.js, andtests/contract/modelService.test.jsfor the route-adjacent service surface. - Playwright workflows in
e2e/tests/workflow/*.spec.jsfor end-to-end route and shell behavior.