Modern React single-page application for document processing, OCR management, workflow orchestration, document labeling, and human-in-the-loop review.
The frontend provides a comprehensive UI for managing the entire document intelligence lifecycle:
- Document Management - Upload, view, and track document processing status
- Processing Queue - Real-time status monitoring with OCR progress tracking
- Workflow Builder - Visual graph editor for creating custom processing workflows
- Labeling Workspace - Canvas-based document annotation for training data creation
- HITL Review - Human-in-the-loop validation and correction interface
- Settings - API key generation and management
- React 19 - Modern React with concurrent features
- TypeScript - Full type safety throughout the application
- Vite - Lightning-fast development with hot module replacement
- Mantine UI - Modern component library with dark mode support
- React Flow (@xyflow/react) - Visual workflow graph editor
- React Konva - Canvas-based document labeling and bounding box annotation
- React PDF - PDF rendering and viewing
- TanStack Query - Powerful data fetching and caching
- Axios - HTTP client with interceptors
- CodeMirror - JSON editor for workflow configuration
Components:
DocumentUploadPanel- Drag-and-drop file upload with base64 encodingDocumentsList- Document list with status badgesDocumentViewerModal- Full-screen document viewer with OCR overlay
Capabilities:
- Upload multiple file formats (PDF, images)
- Attach custom metadata
- Select OCR model (prebuilt-layout, custom models)
- Specify custom workflow for processing
- Real-time upload progress tracking
Components:
ProcessingQueue- Real-time document status monitoring- Status badges: pre_ocr, ongoing_ocr, completed_ocr, failed
Capabilities:
- View all documents with current processing status
- Click to view document details and OCR results
- Automatic status updates via polling
- Filter and search documents
Pages:
WorkflowListPage- List all user workflowsWorkflowEditorPage- Visual workflow graph editor
Components:
WorkflowEditor- React Flow-based graph editorNodeSelector- Drag-and-drop node palette (Future development)- Node types: Start, OCR, HTTP Request, Azure Blob Read/Write, Conditional, Transform, Join, End
Capabilities:
- Create custom document processing workflows
- Visual node-based editing with drag-and-drop (Future development)
- Configure node parameters (OCR models, HTTP endpoints, conditions, transformations)
- Workflow validation and execution via Temporal
- Save and version workflows
- Execute workflows on document upload
Pages:
ProjectListPage- Manage labeling projectsProjectDetailPage- Project overview with field schema and document listLabelingWorkspacePage- Canvas-based labeling interface
Components:
- Canvas-based bounding box drawing
- Field schema management (string, number, date, signature, selectionMark)
- Document navigator
- Label export for training
Capabilities:
- Create labeling projects with custom field definitions
- Upload documents to projects
- Draw bounding boxes for fields on images/PDFs
- Multi-page document support
- Label validation
- Export labeled data for Azure Document Intelligence training
Pages:
ReviewQueuePage- Queue dashboard with filters and statisticsReviewWorkspacePage- Field-by-field review and correction interface
Capabilities:
- Review OCR results with confidence scores
- Correct field values with action tracking (confirmed, corrected, flagged, deleted)
- Approve or escalate documents
- Queue filtering by status and document type
- Analytics and statistics (accuracy rates, review throughput)
- Session management
Page:
SettingsPage- API key management
Capabilities:
- Generate API keys for programmatic access
- View API key prefix and creation date
- Revoke API keys
- Copy API key to clipboard
src/
├── auth/ # Authentication
│ ├── AuthContext.tsx # React context for auth state, token refresh, and hooks
│ └── README.md # Auth implementation documentation
│
├── components/ # Reusable UI components
│ ├── document/ # Document viewing
│ ├── queue/ # Processing queue
│ ├── upload/ # Upload panel
│ ├── workflow/ # Workflow editor
│ └── [shared components]
│
├── data/ # Data layer
│ ├── hooks/ # React Query hooks
│ ├── services/ # API service classes
│ └── queryClient.ts # TanStack Query client
│
├── features/ # Feature modules
│ └── annotation/
│ ├── core/ # Shared annotation components
│ ├── labeling/ # Labeling workspace
│ │ ├── components/
│ │ └── pages/
│ └── hitl/ # HITL review
│ ├── components/
│ └── pages/
│
├── pages/ # Top-level pages
│ ├── WorkflowListPage.tsx
│ ├── WorkflowEditorPage.tsx
│ └── SettingsPage.tsx
│
├── shared/ # Shared utilities
│ ├── constants/ # App constants
│ ├── types/ # TypeScript types
│ └── utils/ # Helper functions
│
├── types/ # Global type definitions
├── App.tsx # Main app shell
└── main.tsx # Application entry point
- Authentication: React Context (
AuthContext) - Server State: TanStack Query for caching and synchronization
- Local UI State: React hooks (
useState,useReducer)
All API calls go through a centralized ApiService class with:
- Cookie-based authentication (
withCredentials: true) - Automatic CSRF token header injection on state-changing requests
- 401 response interceptor with single-flight token refresh
- Error handling
- Type-safe response wrappers
- Node.js 24+ and npm 10+
- Backend services running on
http://localhost:3002 - Keycloak or other OIDC provider configured
npm installCreate a .env file in apps/frontend/:
# API Configuration (empty for Vite proxy in development)
VITE_API_BASE_URL=
# Application Configuration
VITE_APP_NAME=Document Intelligence Platform
VITE_APP_VERSION=1.0.0Configuration Notes:
VITE_API_BASE_URL— Backend API URL; leave empty during development to use the Vite proxy- All OIDC/OAuth configuration is on the backend; the frontend has no OIDC settings
# Start development server with hot reload
npm run devThe application will be available at http://localhost:3000.
Development Proxy: Vite proxies API requests to the backend:
- Frontend:
http://localhost:3000 - Backend:
http://localhost:3002 - API requests to
/api/*are proxied automatically
This eliminates CORS issues during development.
# Build for production
npm run build
# Preview production build locally
npm run previewProduction build outputs to dist/.
# Run Biome linter
npm run lint
# Auto-fix linting issues
npm run lint:fixComponent: DocumentViewerModal
Full-screen modal for viewing documents with OCR overlays:
- PDF rendering with
react-pdf - Image display
- OCR bounding box overlays
- Key-value pair display
- Confidence score visualization
- Multi-page navigation
Component: WorkflowEditor
Visual graph editor built with React Flow:
- Drag-and-drop node creation (Future development)
- Visual edge connections
- Node configuration panel (Future development)
- Live validation
- Auto-layout with Dagre
- Zoom and pan controls
Node Types:
- Start - Entry point with document context
- OCR - Azure Document Intelligence processing
- HTTP Request - External API calls
- Azure Blob Read/Write - Storage operations
- Conditional - Branching logic with expression evaluation
- Transform - Data transformation with JSONata expressions
- Join - Merge multiple branches
- End - Workflow termination
Component: LabelingWorkspacePage
Canvas-based labeling interface using React Konva:
- Select boxes from initial OCR data
- Associate boxes with field definitions
- Multi-page document navigation
- Zoom and pan
- Label persistence
Component: ReviewWorkspacePage
Field-by-field review interface:
- Display OCR-extracted fields with confidence scores
- Edit field values
- Track correction actions (confirmed, corrected, flagged, deleted)
- Side-by-side document view with highlighting
- Session management
- Approve or escalate documents
The app uses a backend-driven OAuth 2.0 Authorization Code flow with cookie-based sessions:
- User clicks "Login" → browser navigates to
/api/auth/login - Backend generates PKCE challenge, stores verifier in HttpOnly cookie, redirects to Keycloak
- User authenticates with Keycloak
- Keycloak redirects back to backend callback with authorization code
- Backend exchanges code for tokens, sets HttpOnly auth cookies, redirects to SPA
- SPA calls
GET /api/auth/meto load user profile (cookies sent automatically) - Proactive token refresh at 75% of token lifetime via
POST /api/auth/refresh
The frontend never handles raw tokens — all tokens are stored in HttpOnly cookies by the backend. The only cookie readable by JavaScript is csrf_token (for the CSRF double-submit pattern).
Auth Context:
isAuthenticated- Auth statusisLoading- Loading stateuser- User profile (sub, name, email, roles, expires_at)login()- Initiate login flowlogout()- Clear session and logoutrefreshToken()- Manually trigger token refresh
- Mantine UI - Comprehensive component library
- Dark mode - Default color scheme
- CSS Variables - Mantine theme tokens
- Responsive - Mobile-friendly layouts
- Custom CSS - Component-specific styles in
.cssfiles
- Functional Components - Use function components with hooks
- TypeScript - Always use proper types, avoid
any - Props Interface - Define explicit prop interfaces
- Error Boundaries - Wrap unstable components
- Lazy Loading - Code-split large feature modules
- Use TanStack Query - For all server state
- Custom Hooks - Wrap queries in reusable hooks
- Error Handling - Handle loading, error, and success states
- Cache Invalidation - Invalidate queries after mutations
- Local State First - Use
useStatefor component-local state - React Query - For server state and caching
- Context Sparingly - Only for cross-cutting concerns (auth)
- Create page component in
src/pages/orsrc/features/*/pages/ - Add navigation item to
App.tsxnav items - Add route handler in
App.tsxmain content area - Create API hooks in
src/data/hooks/
- Create feature directory in
src/features/ - Structure:
components/,pages/,types/,hooks/ - Export public API from
index.ts - Integrate into main app navigation
- Use
useNodesStateanduseEdgesStatefor state management - Implement
onNodesChange,onEdgesChange,onConnecthandlers - Custom node types: define in separate files, register in
nodeTypesprop - Use
useReactFlowhook for imperative API access
- Use
Stage,Layer,Rect,Textprimitives - Handle mouse events:
onMouseDown,onMouseMove,onMouseUp - Maintain separate state for drawing vs. committed shapes
- Use
transformerfor interactive shape manipulation
# Build image
docker build -t frontend -f Dockerfile .
# Run container
docker run -p 3000:80 frontendThe Dockerfile uses nginx to serve the static build.
Set environment variables at build time:
VITE_API_BASE_URL=https://api.example.com \
npm run buildNote: All OAuth/OIDC configuration is handled by the backend. The frontend has no OIDC settings.
In development, ensure Vite proxy is configured in vite.config.ts.
In production, ensure backend CORS settings allow frontend origin.
- Verify backend SSO environment variables (
SSO_AUTH_SERVER_URL,SSO_REALM, etc.) - Check Keycloak client configuration (allowed redirect URIs)
- Inspect browser console for authentication errors
- Verify backend CORS settings allow frontend origin
- Clear
node_modulesand reinstall:rm -rf node_modules && npm install - Clear Vite cache:
rm -rf node_modules/.vite - Check TypeScript errors:
npx tsc --noEmit
Ensure PDF.js worker is correctly configured:
- Worker loads from CDN by default
- Verify
vite.config.tsMIME type configuration - Check browser console for worker errors
Apache License 2.0