Skip to content

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:

  1. Public marketing shell via PublicLayout and the landing/marketing pages.
  2. Authenticated workspace shell via the main app layout in App.jsx and the protected route group.
  3. Admin shell via AdminRoute and AdminLayout.

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:

  • AuthProvider and MsalAuthProvider for legacy and Azure auth state.
  • BackendAuthProvider for backend token/session exchange.
  • ProcessingHubProvider, SharedDataProvider, LiveTestResultsProvider, SchemaGeneratorProvider, PromptGeneratorProvider, and ContractAnalysisProvider for workspace state.
  • FluentProvider inside the protected shell for theme selection.
  • NotificationContainer and LicenseModal for 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 /models disable 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:

  • PublicLayout owns marketing navigation, footer, auth modal, and marketing chatbot.
  • The protected shell in App.jsx owns the persistent sidebar, topbar, workspace providers, and route-level auth/consent gating.
  • AdminLayout owns 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.

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.jsx is the browser entrypoint.
  • src/App.jsx is the route composition root.
  • src/components/home/PublicLayout.jsx owns the public shell.
  • src/admin/AdminRoute.jsx and src/admin/AdminLayout.jsx own the admin shell.
  • src/components/common/toolshell/ToolPageShell.jsx is the shared inner shell for generator-style pages.
  • src/components/sidebar/Sidebar.jsx and src/components/Topbar/Topbar.jsx are 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.jsx for workspace chrome behavior.
  • src/components/Topbar/Topbar.test.jsx for topbar behavior.
  • Contract tests in tests/contract/client.test.js, tests/contract/schemaService.test.js, tests/contract/promptService.test.js, and tests/contract/modelService.test.js for the route-adjacent service surface.
  • Playwright workflows in e2e/tests/workflow/*.spec.js for end-to-end route and shell behavior.