Frontend Architecture
Complete frontend architecture - Next.js 14 App Router, React, Apollo Client, Redux state management, component libraries
Frontend Architecture
Introduction
Next.js 14 app using React 18, Apollo Client, and Redux Toolkit. Uses TypeScript and GraphQL code generation for type safety. Real-time updates via Socket.io. UI built with shadcn/ui and NextUI. The app uses Next.js App Router with an 11-layer provider stack for auth, theming, data fetching, and real-time sync.
Technology Stack
Core Framework
- Next.js 14.0.4 - React framework with App Router, server components, and file-based routing
- React ^18 - UI library with concurrent features and automatic batching
- TypeScript ^5.7.3 - Type-safe JavaScript with strict mode enabled
GraphQL Client
- Apollo Client ^3.14.0 - GraphQL client with caching
- GraphQL ^16.9.0 - GraphQL core
- GraphQL Code Generator - TypeScript type generation
- @graphql-codegen/cli 5.0.5
- @graphql-codegen/client-preset 4.6.3
- @graphql-codegen/typescript 4.1.4
- @graphql-codegen/typescript-operations ^4.5.0
- @graphql-codegen/typescript-react-apollo ^4.3.2
State Management
- Redux Toolkit ^2.3.0 - Redux state management
- Redux ^5.0.1 - State container
- Redux Persist ^6.0.0 - State persistence
- React Redux ^9.1.2 - React bindings
Component Libraries
- shadcn/ui - Accessible UI primitives
- Various @radix-ui/react-* packages (alert-dialog, checkbox, dialog, dropdown-menu, select, tabs, toast, tooltip, and more)
- NextUI ^2.2.9 - Pre-styled components
- Lucide React ^0.454.0 - Icons
- React Icons ^4.12.0 - Additional icons
Real-time & Networking
- Socket.io-client ^4.8.1 - Real-time communication
- Axios ^1.7.9 - HTTP client
Styling & Animation
- Tailwind CSS ^3.4.0 - Utility-first CSS
- Framer Motion - Animation library
- class-variance-authority ^0.7.0 - Variant styling
- tailwindcss-animate ^1.0.7 - Animation utilities
- tailwind-merge ^2.5.4 - Class merging
- clsx ^2.1.1 - ClassName utility
Data Visualization
- ApexCharts ^4.0.0 - Time-series charts
- Recharts ^3.1.2 - Composable charts
- react-apexcharts ^1.7.0 - React wrapper
Forms & Validation
- React Hook Form ^7.53.1 - Form management
- Zod ^3.23.8 - Schema validation
- @hookform/resolvers ^3.9.1 - Form resolvers
UI Utilities
- @dnd-kit - Drag and drop
- @dnd-kit/core ^6.1.0
- @dnd-kit/sortable ^8.0.0
- @dnd-kit/utilities ^3.2.2
- cmdk ^1.0.4 - Command menu
- date-fns ^4.1.0 - Date utilities
- Sonner ^2.0.7 - Toast notifications
- react-hot-toast ^2.4.1 - Alternative toasts
Development Tools
- Storybook ^8.4.4 - Component development
- ESLint ^8 - Linting
- Husky ^8.0.3 - Git hooks
- lint-staged ^15.2.0 - Staged file linting
- @graphql-eslint/eslint-plugin ^3.20.1 - GraphQL linting
Dependency Table
| Category | Package | Version | Purpose |
|---|---|---|---|
| Framework | next | 14.0.4 | App Router, SSR, routing |
| UI Library | react | ^18 | Component rendering |
| GraphQL | @apollo/client | ^3.14.0 | GraphQL client & cache |
| GraphQL | graphql | ^16.9.0 | GraphQL core |
| State | @reduxjs/toolkit | ^2.3.0 | State management |
| State | redux | ^5.0.1 | State container |
| State | redux-persist | ^6.0.0 | State persistence |
| Components | @nextui-org/react | ^2.2.9 | Pre-styled components |
| Components | @radix-ui/* | Various | Accessible primitives |
| Real-time | socket.io-client | ^4.8.1 | WebSocket connection |
| Styling | tailwindcss | ^3.4.0 | Utility-first CSS |
| Animation | framer-motion | * | Animations |
| Charts | apexcharts | ^4.0.0 | Data visualization |
| Charts | react-apexcharts | ^1.7.0 | React wrapper for ApexCharts |
| Charts | recharts | ^3.1.2 | Composable charts |
| Forms | react-hook-form | ^7.53.1 | Form state management |
| Validation | zod | ^3.23.8 | Schema validation |
| Dev Tools | storybook | ^8.4.4 | Component development |
| Dev Tools | typescript | ^5.7.3 | Type checking |
| CodeGen | @graphql-codegen/cli | 5.0.5 | Code generation CLI |
Architecture Overview
Next.js App Router
Uses Next.js 14 App Router with:
- File-based routing in
/src/app- folders are routes,page.jsxdefines UI layout.jsxfor shared layouts,[param]for dynamic routes- Server Components by default,
"use client"for interactivity - Metadata API for SEO (
metadataexport orgenerateMetadatafunction)
Layered Architecture
Presentation: Pages, layouts, UI components, feature components State: Redux store (13 slices), Apollo cache, local state, URL state Service: Socket.io wrapper, real-time Redux integration, health monitoring Data: GraphQL API, REST endpoints, Socket.io events, localStorage
Design Patterns
Provider: 11-layer provider hierarchy for auth, theme, data, real-time Container/Presenter: Smart containers fetch data, dumb presenters render UI Custom Hooks: Extract reusable logic (data fetching, real-time, UI helpers) Compound Components: Composable UI pieces (Dialog, Trigger, Content, Title) Code Generation: GraphQL schema → TypeScript types → React hooks
Key Principles
Type Safety: TypeScript strict mode, GraphQL codegen, Zod validation Performance: Code splitting per route, lazy loading, memoization, cache-first GraphQL Accessibility: ARIA attributes, keyboard navigation, focus management, semantic HTML Responsive: Mobile-first Tailwind, user-selectable UI scaling (sm/md/lg/xl), 44px touch targets Real-time: Socket.io with user namespaces, event-driven Redux updates, optimistic UI, auto-reconnect
Provider Hierarchy
11-layer provider stack in /src/app/layout.js (lines 184-218). Order is critical - each provider depends on earlier contexts.
Complete Provider Stack
<ReduxProvider store={store}> {/* 1. Global state */}
<PersistGate loading={null} persistor={persistor}> {/* 2. State rehydration */}
<SizeProviderWrapper> {/* 3. Interface sizing */}
<ThemeProviderWrapper> {/* 4. Theme context */}
<WallpaperApplier> {/* 5. Dynamic wallpapers */}
<ApolloProvider client={apolloClient}> {/* 6. GraphQL client */}
<NextUIProvider> {/* 7. NextUI components */}
<InitialDataLoader> {/* 8. Data fetching */}
<SocketNamespaceGuard> {/* 9. Socket.io auth */}
<RealTimeProvider> {/* 10. Real-time updates */}
<AppContent> {/* 11. Layout & nav */}
{children}
</AppContent>
</RealTimeProvider>
</SocketNamespaceGuard>
</InitialDataLoader>
</NextUIProvider>
</ApolloProvider>
</WallpaperApplier>
</ThemeProviderWrapper>
</SizeProviderWrapper>
</PersistGate>
</ReduxProvider>
Provider Responsibilities
1. ReduxProvider: Injects Redux store. Provides useSelector, useDispatch. Contains 13 domain slices.
2. PersistGate: Rehydrates state from localStorage before rendering. Persists: appSettings, auth, departments, system.
3. SizeProviderWrapper: Interface size context (sm/md/lg/xl). Reads from Redux appSettings.interfaceSize.
4. ThemeProviderWrapper: Theme state (dark/light/system). CSS class-based switching, localStorage persistence.
5. WallpaperApplier: Updates CSS variables for dynamic wallpapers. Reads Redux appSettings.wallpaper.
6. ApolloProvider: GraphQL client. Provides useQuery, useMutation, useLazyQuery. Configured with retry, auth, error links.
7. NextUIProvider: NextUI component context and theme. Works alongside shadcn/ui.
8. InitialDataLoader: Fetches critical data (auth, settings, departments). 15s timeout, proceeds with partial data if needed.
9. SocketNamespaceGuard: Ensures Socket.io namespace (user:{userId}) set before real-time connection.
10. RealTimeProvider: Socket.io connection manager. Provides realTimeService, connectionStatus. Dispatches Redux actions on events.
11. AppContent: Renders sidebar, main content, auth guard. Needs all previous contexts.
Why This Order: Redux/persistence first → visual prefs (theme, size) early → Apollo for data → auth → real-time last. Violating causes errors (e.g., RealTimeProvider before auth = no namespace).
Project Structure
Directory Organization
frontend/
├── src/
│ ├── app/ # App Router pages/layouts
│ │ ├── layout.js # Root layout, provider hierarchy
│ │ ├── auth/signin, signup
│ │ ├── computers/ # VM list, VM details
│ │ ├── departments/[name]/vm/[id]
│ │ ├── users, settings, templates, applications, profile
│ ├── components/
│ │ ├── ui/ # shadcn/ui + size-provider.jsx
│ │ ├── vm/ # Dashboard, health, performance
│ │ ├── auth, security, settings
│ │ ├── AppSidebar, InitialDataLoader, RealTimeProvider
│ ├── state/
│ │ ├── slices/ # 13 Redux slices
│ │ └── store.js
│ ├── gql/ # GraphQL schema, operations, generated hooks
│ ├── hooks/ # Custom React hooks
│ ├── services/ # Socket, real-time, problem services
│ ├── utils/ # Theme, wallpaper, auth, debug
│ ├── contexts/ThemeProvider.jsx
│ ├── styles/ # globals.css, etc.
│ ├── apollo-client.js, init.js
├── public/ # Static assets
├── .storybook/
├── codegen.ts, middleware.js, next.config.js, tailwind.config.js
Naming Conventions
Components: PascalCase.jsx (even with TypeScript)
Hooks: useHookName.js or use-hook-name.js
Services: serviceName.js or ServiceName.js
Redux Slices: sliceName.js (domain-based)
GraphQL: queries.graphql, mutations.graphql
Utilities: utilName.js or util-name.js
Pages: page.js, layout.js, [param] for dynamic routes
Apollo Client - GraphQL Integration
Configured in /src/apollo-client.js with link chain: error handling → retry logic → auth → HTTP.
Client Configuration
HTTP Link: Connects to GraphQL endpoint with 30s timeout, keep-alive for persistent connections.
Retry Link: Retries failed requests (max 3 attempts). Retries on network errors and 5xx server errors with exponential backoff (300ms initial, jitter enabled).
Error Link: Centralized error logging. Logs GraphQL errors (message, location, path) and network errors (operation name, error details).
Auth Link: Injects JWT token from localStorage into request headers. SSR-safe (checks typeof window).
Link Chain: errorLink → retryLink → authLink → httpLink. Request flows forward, response flows backward.
Cache Configuration
InMemoryCache with merge policies that replace existing data with incoming (prevents duplicates). Fields with replace strategy: users, machineTemplates, machines, listFilters, getAvailableFirewallTemplates.
Default Options
watchQuery: cache-and-network (return cache, then update), 30s timeout, notify on network status changes
query: cache-first (use cache if available), 30s timeout, errorPolicy: 'all' (return partial data on errors)
SSR Mode: Enabled on server (typeof window === 'undefined')
DevTools: Development only
Cache Utilities: clearApolloCache() (clear without refetch), resetApolloCache() (clear and refetch all active queries)
GraphQL Code Generation
Configured in /frontend/codegen.ts. Generates TypeScript types and React hooks from schema and operations.
Configuration
Schema: src/gql/schema.graphql (backend schema copied to frontend)
Documents: mutations.graphql, queries.graphql, subdirectories supported, ignores .bak and .tmp
Outputs:
src/gql/: Client preset →gql.ts,graphql.ts,index.ts(type-safe gql tag)src/gql/hooks.ts: React hooks →useXxxQuery,useXxxMutation(with refetch, mutation functions, result types)
Custom Scalars: DateTimeISO → string, JSONObject → object, Upload → File
Usage
Define operation in queries.graphql → run npm run codegen → import hook from @/gql/hooks:
import { useGetVmQuery } from '@/gql/hooks';
const { data, loading } = useGetVmQuery({ variables: { id: vmId } });
Scripts: codegen (generate), codegen:check (verify), codegen:validate (validate), codegen:clean (remove)
Redux State Management
13 domain-specific slices managed by Redux Toolkit. Example: appSettings slice.
AppSettings Slice
State: { settings: { theme, wallpaper, logoUrl, interfaceSize }, loading, error, initialized }
Async Thunks: fetchAppSettings (load from backend), updateAppSettings (persist changes)
Reducers: resetSettings, setThemePreference (optimistic), setSizePreference (optimistic), clearErrors
ExtraReducers: Handles REHYDRATE (Redux Persist), async thunk lifecycle (pending/fulfilled/rejected), validates interfaceSize, falls back to defaults on error
Selectors: selectAppSettings, selectTheme, selectInterfaceSize, etc. (auto-memoized by Redux Toolkit)
Usage
import { useSelector, useDispatch } from 'react-redux';
import { selectTheme, setThemePreference } from '@/state/slices/appSettings';
const theme = useSelector(selectTheme);
dispatch(setThemePreference('dark'));
Redux Slices
| Slice | Purpose | Persisted |
|---|---|---|
| appSettings | UI preferences (theme, wallpaper, size) | ✅ |
| auth | User, token, socketNamespace | ✅ |
| departments, system | Department list, system resources | ✅ |
| vms, templates, users, firewall, health, iso, applications, templateCategories, vmPorts | Dynamic data | ❌ |
Component Libraries
Two complementary libraries: shadcn/ui (customizable, accessible) and NextUI (pre-styled, rapid dev).
shadcn/ui: Copied to /src/components/ui, full source control. Built on Radix UI primitives. Styled with Tailwind + CVA for variants. Components: Dialog, Checkbox, Select, Tabs, Toast, Tooltip, etc.
NextUI: npm package with provider. Pre-styled components for rapid prototyping.
When to Use: shadcn/ui for custom designs and complex interactions, NextUI for simple rapid prototyping, custom components for domain-specific UI.
Initial Data Loading
InitialDataLoader in /src/components/InitialDataLoader.jsx fetches critical data before app renders.
Loading Strategy: Critical services (auth, appSettings) load first, deferred services (departments, templates, users) load in background. Config in /src/init.js.
Flow: 1) Restore auth from localStorage → 2) Fetch critical data (parallel) → 3) Track deferred service status
Error Handling: Auth errors → redirect to login (no blocking). Critical errors → block and require retry. Non-critical → show "Continue Anyway". 15s timeout → proceed with partial data.
Loading UI: Skeleton screen showing sidebar + VM card grid while data loads.
Real-Time Updates
RealTimeProvider in /src/components/RealTimeProvider.jsx manages Socket.io connection and Redux integration.
Connection Lifecycle: 1) Check prerequisites (auth, token, namespace user:{userId}) → 2) Initialize service (100ms delay for React Strict Mode, creates realTimeReduxService) → 3) Cleanup on unmount or auth change
Context: Provides realTimeService, connectionStatus, isConnected, isConnecting, hasError, error
Event Integration: realTimeReduxService dispatches Redux actions on events: vmCreated, vmStatusChanged, healthStatusChange, firewallRuleChanged
Key Feature Components
VM Management (/src/components/vm): VMDashboard, VMStatusCard, VMResourceGraph, VMQuickActions, VMHealth, HealthRecommendations, Performance charts (CPU, RAM, DiskIO, Network). Custom hooks: useVMRecommendations, useVMProblems, usePerformanceData, useHealthTransformation
Firewall UI (/src/components/security): FirewallRules, FirewallTemplates, EffectiveRules. Features: Service presets (HTTPS, SSH, MySQL), custom rules, department rule overrides, pending changes indicator, conflict detection.
Settings (/src/app/settings): Appearance (theme, wallpaper, interface size, logo), Security (password, 2FA, sessions, login history), System (notifications, language, timezone)
Custom Hooks
Data Fetching: useVMRecommendations (polls every 60s), usePerformanceData (aggregates chart data), useFirewallData
Real-Time: useVMNetworkRealTime (listens to Socket.io events), useSocketConnection
UI: use-toast (sonner wrapper), use-mobile (responsive breakpoint detection)
Services Layer
socketService.js: Low-level Socket.io wrapper. API: connect(), disconnect(), on(), off(), emit(), getStatus()
realTimeReduxService.js: Bridges Socket.io events to Redux actions. Maps: vmCreated → addVM, vmStatusChanged → updateVMStatus, healthStatusChange → updateHealthSnapshot, etc.
Problem Services: ProblemTransformationService (health snapshots → problem descriptions), ProblemPriorityService (priority calculation)
Styling System
Tailwind CSS with custom config (infinibay-blue, infinibay-orange colors), CSS variables for theming (.dark class), glass effects (backdrop-filter: blur()), user-selectable UI scaling (sm/md/lg/xl via SizeProvider). See dedicated styling doc for details.
Performance Optimizations
Code Splitting: Per-route automatic, dynamic() for heavy components
Memoization: React.memo, useMemo, useCallback
Apollo: cache-first (static), cache-and-network (dynamic), custom merge policies
Redux: Selective persistence, normalized state, memoized selectors
Images: Next.js Image component (lazy loading, WebP conversion)
Development Workflow
Scripts: dev (port 3000), build, lint, lint:fix, codegen, codegen:check, codegen:validate, storybook (port 6006)
Git Hooks: lint-staged auto-fixes JS/TS/GraphQL files pre-commit, validates GraphQL against schema
Storybook: Component development in isolation, stories in *.stories.jsx
Environment Variables
NEXT_PUBLIC_GRAPHQL_API_URL, NEXT_PUBLIC_SOCKET_URL (exposed to browser). Server-only vars not prefixed with NEXT_PUBLIC_.
Mermaid Diagrams
Frontend Architecture Overview
graph TD
A[User Browser] --> B[Next.js App Router]
B --> C[Provider Layer]
C --> D[Component Layer]
D --> E[State Layer]
E --> F[Service Layer]
F --> G[Data Layer]
G --> H[Backend API]
C --> C1[Redux Provider]
C --> C2[Apollo Provider]
C --> C3[Theme Provider]
C --> C4[Size Provider]
C --> C5[RealTimeProvider]
D --> D1[Pages]
D --> D2[Layouts]
D --> D3[UI Components]
D --> D4[Feature Components]
E --> E1[Redux Slices]
E --> E2[Apollo Cache]
F --> F1[Socket Service]
F --> F2[Real-Time Redux Service]
G --> G1[GraphQL Queries/Mutations]
G --> G2[Socket.io Events]
H --> H1[GraphQL Server]
H --> H2[Socket.io Server]
H2 -->|Real-time Events| F1
F1 --> E1
E1 --> D4
style A fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
style B fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style C fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style C1 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style C2 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style C3 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style C4 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style C5 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style D fill:#a855f7,stroke:#9333ea,stroke-width:2px,color:#fff
style E fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000
style E1 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000
style E2 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000
style F fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style F1 fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style F2 fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style G fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style G1 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style G2 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style H fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
style H1 fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
style H2 fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
Component Hierarchy
graph TD
A[RootLayout] --> B[Provider Stack]
B --> B1[Redux Provider]
B1 --> B2[PersistGate]
B2 --> B3[SizeProvider]
B3 --> B4[ThemeProvider]
B4 --> B5[WallpaperApplier]
B5 --> B6[ApolloProvider]
B6 --> B7[NextUIProvider]
B7 --> B8[InitialDataLoader]
B8 --> B9[SocketNamespaceGuard]
B9 --> B10[RealTimeProvider]
B10 --> B11[AppContent]
B11 --> C[Sidebar]
B11 --> D[Main Content]
D --> E[Page Layouts]
E --> E1[/computers]
E --> E2[/departments]
E --> E3[/settings]
E1 --> F1[VM List Page]
E1 --> F2[VM Details Page]
F2 --> G1[VM Dashboard]
F2 --> G2[VM Health]
F2 --> G3[VM Performance]
G1 --> H1[VM Status Card]
G1 --> H2[VM Resource Graph]
G1 --> H3[VM Quick Actions]
H1 --> I[UI Components]
I --> I1[Button]
I --> I2[Card]
I --> I3[Dialog]
style A fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
style B fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B1 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B2 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B3 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B4 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B5 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B6 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B7 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B8 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B9 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B10 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style B11 fill:#0ea5e9,stroke:#0284c7,stroke-width:2px,color:#fff
style C fill:#a855f7,stroke:#9333ea,stroke-width:2px,color:#fff
style D fill:#a855f7,stroke:#9333ea,stroke-width:2px,color:#fff
style E fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000
style E1 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000
style E2 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000
style E3 fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#000
style F1 fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style F2 fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style G1 fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style G2 fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style G3 fill:#22c55e,stroke:#16a34a,stroke-width:2px,color:#fff
style H1 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style H2 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style H3 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style I fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style I1 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style I2 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
style I3 fill:#ec4899,stroke:#db2777,stroke-width:2px,color:#fff
State Management Flow
sequenceDiagram
participant User
participant Component
participant Dispatch
participant Thunk
participant Reducer
participant Selector
User->>Component: Click Button
Component->>Dispatch: dispatch(fetchVMs())
Dispatch->>Thunk: Async Thunk
Thunk->>Thunk: API Call
Thunk->>Reducer: dispatch(fetchVMs.pending)
Reducer->>Reducer: Update state (loading: true)
Note over Thunk: API Response
Thunk->>Reducer: dispatch(fetchVMs.fulfilled)
Reducer->>Reducer: Update state (vms: [...], loading: false)
Reducer->>Selector: State Changed
Selector->>Component: Select Data
Component->>Component: Re-render
Component->>User: Display VMs
Note over Reducer: Persistence
Reducer->>Reducer: Redux Persist REHYDRATE
GraphQL Data Flow
sequenceDiagram
participant Component
participant Hook
participant Apollo
participant Cache
participant AuthLink
participant RetryLink
participant ErrorLink
participant HTTPLink
participant Backend
Component->>Hook: useGetVMQuery({ vmId })
Hook->>Apollo: Execute Query
Apollo->>Cache: Check Cache
alt Cache Hit (cache-first)
Cache-->>Apollo: Return Cached Data
Apollo-->>Component: data, loading: false
else Cache Miss
Apollo->>ErrorLink: Forward Request
ErrorLink->>RetryLink: Forward Request
RetryLink->>AuthLink: Forward Request
AuthLink->>AuthLink: Add JWT Token
AuthLink->>HTTPLink: Forward Request
HTTPLink->>Backend: HTTP POST /graphql
Backend-->>HTTPLink: GraphQL Response
HTTPLink-->>AuthLink: Response
alt GraphQL Error
AuthLink-->>ErrorLink: Response
ErrorLink->>ErrorLink: Log Error
end
ErrorLink-->>RetryLink: Response
alt Network Error (5xx)
RetryLink->>RetryLink: Retry (max 3)
RetryLink->>AuthLink: Retry Request
end
RetryLink-->>Apollo: Response
Apollo->>Cache: Update Cache
Cache-->>Apollo: Cached
Apollo-->>Component: data, loading: false
end
Component->>Component: Re-render
Document Version: 2.0 Last Updated: 2025-01-18 Sections: Complete (1-20 + Mermaid diagrams) Maintainer: Infinibay Frontend Team