State Management
Purpose and Scope
This document describes the frontend state management architecture in Automatos AI, covering the hybrid approach using React Query for server state, Zustand for client state, and React Context for global configuration. For backend API structure, see API Router Organization. For real-time updates via WebSocket/SSE, see Real-Time Updates.
Sources: frontend/package.json:43,70,138
State Management Architecture
The frontend employs a three-layer state management strategy to handle different types of application state:
Architecture Diagram: State Management Layers
Sources: frontend/components/chatbot/chat.tsx:1-100, frontend/package.json:43,70,138
Server State Management (React Query)
React Query (@tanstack/react-query) manages all server-side data fetching, caching, and synchronization. The query client is configured at the application root via QueryClientProvider.
Query Client Configuration
The query client is provided at the top level of the application in the provider hierarchy:
Key characteristics:
Automatic background refetching with 60-second stale time
Workspace-scoped cache keys for multi-tenant isolation
Request deduplication
Optimistic updates for mutations
Admin workspace override support
Sources: frontend/hooks/use-unified-analytics.ts:1-10
Workspace-Scoped Caching
All queries include workspace context in their cache keys to prevent data leakage between workspaces. The wsScope() function provides this scoping:
Cache key structure:
First element: Feature namespace (e.g.,
'unified-analytics')Second element: Workspace scope (e.g.,
'own','__all__', or specific workspace ID)Remaining elements: Resource type and parameters
This ensures that when an admin switches workspaces, the cache correctly refetches data for the new workspace context.
Sources: frontend/hooks/use-unified-analytics.ts:12-38, frontend/lib/api-client.ts:83-91
Admin Workspace Override
The system supports admin users viewing analytics for specific workspaces or all workspaces via a module-level override:
Admin workspace switcher pattern frontend/components/analytics/admin-workspace-switcher.tsx:14-35:
Admin selects workspace from dropdown
Calls
setAdminWorkspaceOverride(workspaceId)orsetAdminWorkspaceOverride('__all__')Invalidates all analytics queries:
queryClient.invalidateQueries({ queryKey: ['unified-analytics'] })Queries refetch with new workspace context
Override is cleared on component unmount
The '__all__' sentinel value instructs backend endpoints to skip workspace filtering and return platform-wide data.
Sources: frontend/lib/api-client.ts:83-91, frontend/components/analytics/admin-workspace-switcher.tsx:1-48
Query Patterns
Server state is accessed through custom hooks that wrap React Query. Analytics hooks follow a consistent pattern:
useAnalyticsOverview(days)
Overview stats
['unified-analytics', wsScope(), 'overview', days]
60s
useAgentAnalytics(days)
Agent stats + memory
['unified-analytics', wsScope(), 'agents', days]
60s
useWorkflowAnalytics(days)
Workflow + recipe stats
['unified-analytics', wsScope(), 'workflows', days]
60s
useCostAnalyticsUnified(days)
Cost breakdown
['unified-analytics', wsScope(), 'costs', days]
60s
useModelComparison(ids, period)
Model comparison
['unified-analytics', wsScope(), 'llm', 'comparison', ids, period]
60s
useAdminDashboard(period)
Platform-wide stats
['unified-analytics', wsScope(), 'admin', 'dashboard', period]
60s
Sources: frontend/hooks/use-unified-analytics.ts:18-38,41-91,105-237
Query Implementation Pattern
Unified analytics queries use a safe request wrapper to prevent cascading failures:
This pattern:
Wraps each API call in
safeRequest()to isolate failuresFalls back to sensible defaults if endpoints fail
Aggregates data from multiple backend endpoints
Uses workspace-scoped cache keys
Sources: frontend/hooks/use-unified-analytics.ts:41-91
Cache Invalidation
Mutations invalidate related queries using query key prefixes:
Common invalidation patterns:
Specific query:
invalidateQueries({ queryKey: ['unified-analytics', wsScope(), 'agents', 30] })Feature namespace:
invalidateQueries({ queryKey: ['unified-analytics'] })Prefix match:
invalidateQueries({ queryKey: ['unified-analytics', 'costs'] })
Sources: frontend/hooks/use-unified-analytics.ts:624-640, frontend/components/analytics/admin-workspace-switcher.tsx:28-35
Client State Management (Zustand)
Zustand manages transient UI state that doesn't need server persistence. The primary store is useWorkspaceStore, which manages the widget architecture.
Workspace Store Architecture
Store location: frontend/stores/workspace-store.ts (inferred from usage)
Sources: frontend/components/chatbot/chat.tsx:20,53-56, frontend/components/workspace/Canvas.tsx:10-14
Widget State Structure
The workspace store maintains widget state as shown in usage patterns:
Widget State Properties (from frontend/components/chatbot/chat.tsx:53-56):
widgetIds: string[]- Ordered list of widget IDswidgets: Record<string, Widget>- Widget data by IDactiveWidgetId: string | null- Currently selected widgetisWidgetTrayOpen: boolean- Tray visibility state
Widget Actions (from frontend/components/chatbot/chat.tsx:54-55,59-63):
addWidget(widgetData)- Create new widgetremoveWidget(id)- Delete widgetupdateWidget(id, updates)- Modify widget datasetActiveWidget(id)- Switch active widgetclearWidgets()- Remove all widgetstoggleWidgetTray()- Show/hide widget tray
Widget Creation Example
From the Chat component's tool-data handler (frontend/components/chatbot/chat.tsx:108-149):
Sources: frontend/components/chatbot/chat.tsx:108-149
Context Providers
React Context provides global configuration and authentication state throughout the application.
Provider Hierarchy
The provider tree structure:
Sources: frontend/middleware.ts:1-18
Authentication Context (Clerk)
Provider: ClerkProvider from @clerk/nextjs
Provides authentication state and user information. The API client uses Clerk tokens for backend authentication:
API client integration frontend/lib/api-client.ts:98-163:
Token is automatically injected into all backend requests as Authorization: Bearer <token> header.
Middleware integration frontend/middleware.ts:1-18:
Route protection via
clerkMiddlewarePublic routes:
/sign-in,/sign-up,/sso-callback,/api/webhooksProtected routes require authentication
Sources: frontend/middleware.ts:1-18, frontend/lib/api-client.ts:98-163
Workspace Context
Provider: WorkspaceProvider
Provides current workspace information:
Workspace ID
Workspace name
Member role
Workspace settings
The workspace ID is sent to the backend via the X-Workspace-ID header in all API requests. The backend's get_request_context_hybrid() dependency resolves this header to create the RequestContext:
All database queries are scoped to workspace_id unless admin_all_workspaces=True (set when admin uses X-Workspace-ID: __all__ header).
Sources: orchestrator/core/auth/dependencies.py:29-42, orchestrator/core/auth/hybrid.py:1-40
Theme Context
Provider: ThemeProvider from next-themes
Manages dark/light mode preferences:
Persisted to localStorage
System preference detection
CSS variable updates
Sources: frontend/package.json:106
State Synchronization Patterns
The system coordinates state between server, client, and UI layers using several patterns.
State Flow Diagram
Sources: frontend/components/chatbot/chat.tsx:98-149
Real-Time Updates
The system uses Server-Sent Events (SSE) for streaming updates from the backend:
Event types (from frontend/components/chatbot/chat.tsx:103-300):
text-delta- Streaming text contenttool-data- Tool execution resultsdata-usage- Token usage updatesrouting-decision- Agent routing information
Handler pattern:
Sources: frontend/components/chatbot/chat.tsx:98-300
Cache Invalidation Events
React Query cache is invalidated on specific events:
Agent created
['agents']
Mutation success
Recipe executed
['recipes', recipeId], ['executions']
Execution complete
Plugin installed
['marketplace'], ['workspace-plugins']
Installation success
Chat deleted
['chats']
Delete mutation
Sources: Architecture diagrams
Usage Patterns and Examples
Pattern 1: Widget Management in Chat
The Chat component demonstrates coordinated state management (frontend/components/chatbot/chat.tsx:52-64,108-212):
Sources: frontend/components/chatbot/chat.tsx:52-212
Pattern 2: Canvas Widget Display
The Canvas component reads from the workspace store (frontend/components/workspace/Canvas.tsx:38-61):
Sources: frontend/components/workspace/Canvas.tsx:38-61
Pattern 3: Server State with Authentication
Components use React Query with Clerk authentication context (frontend/components/chatbot/chat-widget.tsx:118-233):
Sources: frontend/components/chatbot/chat-widget.tsx:118-233
Pattern 4: Tool Suggestions with Analytics
Dynamic tool suggestions combine server state and analytics tracking (frontend/components/chatbot/chat.tsx:410-462):
Sources: frontend/components/chatbot/chat.tsx:410-462, frontend/lib/analytics.ts:1-26
State Persistence
Local Storage
Certain UI preferences are persisted to browser localStorage:
theme
'dark' | 'light' | 'system'
ThemeProvider
clerk_*
Authentication tokens
ClerkProvider
Widget preferences
Canvas layout
(Future enhancement)
Session Storage
Ephemeral session data:
Active chat ID
Draft messages
Temporary widget state
Server-Side Persistence
Server state persisted via PostgreSQL:
User profiles
Agents and configurations
Workflow recipes
Chat history
Marketplace items
Sources: Architecture diagrams
API Client Architecture
The apiClient singleton handles all HTTP communication with the backend, including authentication, workspace headers, and mock data support.
API Client Structure
Sources: frontend/lib/api-client.ts:93-300
Request Header Assembly
Every request includes workspace and authentication headers:
Header flow:
Authorization: Bearer <jwt>→ Backend validates with Clerk JWKSX-Workspace-ID: <uuid>→ Backend filters data to specific workspaceX-Workspace-ID: __all__→ Backend skips workspace filter (admin only)
Sources: frontend/lib/api-client.ts:93-300, orchestrator/core/auth/hybrid.py:20-70
Mock Data System
The API client includes a development-only mock system that falls back to mock data when real APIs fail:
Page-level mock configuration frontend/lib/api-client.ts:55-78:
Components set their page context using:
Sources: frontend/lib/api-client.ts:55-300
Base URL Configuration
The API client resolves the backend URL from multiple sources:
Priority order:
Runtime injection via
window.__NEXT_PUBLIC_API_URL__Build-time environment variable
NEXT_PUBLIC_API_URLRuntime fallback
Empty string (relative URLs)
Sources: frontend/lib/api-client.ts:101-117
State Management Code Symbols
Key Imports
Sources: frontend/hooks/use-unified-analytics.ts:1-10, frontend/lib/api-client.ts:1-100
Store Selectors
Zustand store selectors follow this pattern:
Sources: frontend/components/chatbot/chat.tsx:53-56, frontend/components/workspace/Canvas.tsx:38-42
Performance Considerations
React Query Optimizations
Analytics queries use consistent stale time configuration:
Optimizations:
Stale time: 60 seconds for analytics queries, prevents excessive refetching
Workspace-scoped keys: Cache isolated per workspace, no cross-tenant pollution
Request deduplication: Multiple components requesting same data share single request
Parallel requests:
Promise.all()withsafeRequest()wrapper for fault tolerance
Sources: frontend/hooks/use-unified-analytics.ts:41-91
Safe Request Pattern
The safeRequest() wrapper isolates API failures to prevent cascading errors:
If any endpoint fails, the query returns partial data instead of failing completely.
Sources: frontend/hooks/use-unified-analytics.ts:48-59
Zustand Optimizations
Selector-based subscriptions: Components only re-render when selected state changes
Immer integration: Immutable state updates with mutable syntax
No provider overhead: Direct store access without context
Widget State Optimization
Widget data is stored as a map (Record<string, Widget>) for O(1) lookups:
Sources: frontend/components/workspace/Canvas.tsx:38-49
Admin Dashboard Optimization
The admin analytics page uses period-based queries with selective invalidation:
The wsScope() in cache keys ensures that switching workspaces invalidates only the relevant queries, not the entire cache.
Sources: frontend/components/analytics/analytics-admin.tsx:165-296
Debugging State
React Query Devtools
Enable React Query Devtools in development:
Zustand Devtools
Zustand stores can integrate with Redux DevTools:
State Inspection
Browser console commands:
Sources: frontend/package.json:43,138
Last updated

