2:I[7012,["4765","static/chunks/4765-f5afdf8061f456f3.js","9856","static/chunks/9856-3b185291364d9bef.js","6687","static/chunks/app/docs/%5B...slug%5D/page-e07536548216bee4.js"],"MarkdownRenderer"] 4:I[9856,["4765","static/chunks/4765-f5afdf8061f456f3.js","9856","static/chunks/9856-3b185291364d9bef.js","6687","static/chunks/app/docs/%5B...slug%5D/page-e07536548216bee4.js"],""] 5:I[4126,[],""] 7:I[9630,[],""] 8:I[4278,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"HeadingProvider"] 9:I[1476,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"Header"] a:I[3167,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"Sidebar"] b:I[7409,["9856","static/chunks/9856-3b185291364d9bef.js","8172","static/chunks/8172-b3a2d6fe4ae10d40.js","3185","static/chunks/app/layout-2814fa5d15b84fe4.js"],"PageFrame"] 3:T61af, # VoiceAssist Client Architecture Overview ## Three-Domain Architecture The VoiceAssist platform is deployed across three dedicated domains, each serving a specific purpose: ``` ┌─────────────────────────────────────────────────────────────┐ │ VoiceAssist Platform │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌────────────┐ │ │ │ assist.asimo.io │ │ admin.asimo.io │ │ docs.asimo │ │ │ │ │ │ │ │ .io │ │ │ │ Main Web App │ │ Admin Panel & │ │ Docs Hub │ │ │ │ Chat Interface │ │ KB Editor │ │ (canonical)│ │ │ │ Real-time │ │ User Mgmt │ │ │ │ │ │ Messaging │ │ Settings │ │ │ │ │ └────────┬─────────┘ └────────┬─────────┘ └─────┬──────┘ │ │ │ │ │ │ │ └────────────┬────────┘ │ │ │ │ │ │ │ ┌─────────▼─────────┐ │ │ │ │ │ │ │ │ │ Backend Services │ │ │ │ │ (assist.asimo.io)│ │ │ │ │ │ │ │ │ │ • REST API │ │ │ │ │ • WebSocket │ │ │ │ │ • Auth │ │ │ │ └───────────────────┘ │ │ │ │ │ │ ┌──────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌────────────────┐ │ │ │ │ │ │ │ Next.js + │ │ │ │ Markdown docs │ │ │ └────────────────┘ │ └──────────────────────────────────────────────────────────────┘ ``` ### Domain Purposes #### 1. assist.asimo.io (Main Application) **Primary Purpose:** End-user chat interface with real-time AI assistant **Key Features:** - Chat interface with WebSocket streaming - Message history with virtualization - Citation display and references - File attachment support - Markdown rendering with code highlighting - Math equation support (KaTeX) - User authentication and session management **Technology Stack:** - React 18.2+ with TypeScript - Vite build system - React Router v6 - Zustand state management - react-virtuoso for message virtualization - react-markdown for content rendering - WebSocket for real-time communication **Key Endpoints:** - `GET /` - Main app (SPA) - `GET /api/health` - Health check - `POST /api/auth/login` - Authentication - `POST /api/auth/register` - User registration - `GET /api/conversations` - List conversations - `POST /api/conversations` - Create conversation - `WS /api/realtime` - WebSocket streaming endpoint - `POST /api/attachments/upload` - File upload --- #### 2. admin.asimo.io (Administration) **Primary Purpose:** Administrative control panel and knowledge base management **Key Features:** - User management and roles - Knowledge base editing - Document upload and indexing - System settings and configuration - Analytics and usage metrics - Audit logs **Technology Stack:** - React 18.2+ with TypeScript - Shared component library with main app - Tailwind CSS for styling - Role-based access control (RBAC) **Key Endpoints:** - `GET /` - Admin panel (SPA) - `GET /api/admin/users` - User management - `POST /api/admin/kb/upload` - Document upload - `GET /api/admin/analytics` - Usage metrics - `GET /api/admin/settings` - System configuration --- #### 3. docs.asimo.io (Documentation) **Primary Purpose:** Technical documentation and API reference **Key Features:** - Comprehensive technical documentation - API reference documentation - Integration guides - Development tutorials - Architecture diagrams - Deployment guides **Technology Stack:** - Next.js 14 (App Router) - Markdown content sourced from monorepo `docs/` - Tailwind Typography styling - Reverse proxy at Apache2 → Next.js runtime on port 3001 - Version control via Git **Content Structure:** ``` docs/ ├── overview/ │ ├── architecture.md │ └── getting-started.md ├── client-implementation/ │ ├── folder-structure.md │ ├── testing-guide.md │ └── deployment.md ├── api-reference/ │ ├── rest-api.md │ ├── websocket-events.md │ └── authentication.md └── realtime/ ├── proxy-spec.md └── streaming-protocol.md ``` --- ## Client Folder Structure ``` apps/web-app/ # Main application (assist.asimo.io) ├── src/ │ ├── components/ │ │ ├── auth/ # Authentication components │ │ │ ├── LoginForm.tsx │ │ │ ├── RegisterForm.tsx │ │ │ └── ProtectedRoute.tsx │ │ ├── chat/ # Chat interface components │ │ │ ├── MessageList.tsx # Virtualized message list │ │ │ ├── MessageBubble.tsx # Individual message rendering │ │ │ ├── MessageInput.tsx # Message input with auto-expansion │ │ │ ├── CitationDisplay.tsx # Citation rendering │ │ │ ├── ConnectionStatus.tsx # WebSocket status indicator │ │ │ ├── ChatErrorBoundary.tsx # Error boundary for chat │ │ │ └── __tests__/ # Component unit tests │ │ ├── conversations/ # Conversation management │ │ │ ├── ConversationList.tsx # Conversation list sidebar │ │ │ ├── ConversationListItem.tsx # Individual conversation item │ │ │ └── __tests__/ # Conversation tests │ │ ├── layout/ # Layout components │ │ │ ├── MainLayout.tsx │ │ │ ├── Header.tsx │ │ │ └── Sidebar.tsx │ │ └── common/ # Shared components │ │ ├── Button.tsx │ │ ├── Input.tsx │ │ └── LoadingSpinner.tsx │ ├── pages/ │ │ ├── LoginPage.tsx │ │ ├── RegisterPage.tsx │ │ ├── HomePage.tsx │ │ ├── ChatPage.tsx # Main chat interface │ │ ├── ProfilePage.tsx │ │ └── OAuthCallbackPage.tsx │ ├── hooks/ │ │ ├── useAuth.ts │ │ ├── useChatSession.ts # WebSocket chat hook │ │ └── __tests__/ # Hook unit tests │ ├── stores/ │ │ ├── authStore.ts # Zustand auth store │ │ └── conversationStore.ts │ ├── lib/ │ │ ├── api.ts # REST API client │ │ ├── websocket.ts # WebSocket utilities │ │ └── validators.ts │ ├── __tests__/ │ │ └── integration/ # Integration tests │ │ └── ChatFlow.test.tsx │ ├── App.tsx │ ├── main.tsx │ └── vite-env.d.ts ├── public/ │ └── assets/ ├── index.html ├── package.json ├── vite.config.ts ├── vitest.config.ts └── tsconfig.json packages/ ├── types/ # Shared TypeScript types │ ├── src/ │ │ └── index.ts # Message, Citation, WebSocket types │ └── package.json └── ui-components/ # Shared component library ├── src/ │ ├── Button/ │ ├── Input/ │ └── index.ts └── package.json ``` --- ## Data Flow Architecture ### 1. User Message Flow ``` ┌─────────────┐ │ User │ │ (Browser) │ └──────┬──────┘ │ 1. Types message │ 2. Clicks Send / Presses Enter ▼ ┌────────────────────────┐ │ MessageInput.tsx │ │ - Validates input │ │ - Triggers onSend │ └──────┬─────────────────┘ │ 3. sendMessage(content, attachments?) ▼ ┌────────────────────────┐ │ useChatSession Hook │ │ - Checks WebSocket │ │ - Adds to messages[] │ │ - Sends to server │ └──────┬─────────────────┘ │ 4. WebSocket send ▼ ┌────────────────────────┐ │ Backend API │ │ /api/realtime │ │ - Processes message │ │ - Calls OpenAI API │ └──────┬─────────────────┘ │ 5. Streaming response ▼ ┌────────────────────────┐ │ useChatSession Hook │ │ - Receives delta │ │ - Updates streaming │ │ - Emits message.done │ └──────┬─────────────────┘ │ 6. State update ▼ ┌────────────────────────┐ │ MessageList.tsx │ │ - Renders messages │ │ - Shows streaming │ │ - Auto-scrolls │ └────────────────────────┘ ``` ### 2. Authentication Flow ``` ┌─────────────┐ │ LoginPage │ │ (UI Form) │ └──────┬──────┘ │ 1. Submit credentials ▼ ┌─────────────┐ │ useAuth │ │ Hook │ └──────┬──────┘ │ 2. POST /api/auth/login ▼ ┌────────────────────────┐ │ Backend Auth Service │ │ - Validates │ │ - Issues JWT │ └──────┬─────────────────┘ │ 3. Returns tokens ▼ ┌─────────────┐ │ authStore │ │ (Zustand) │ └──────┬──────┘ │ 4. Stores tokens │ 5. Sets user state ▼ ┌──────────────────┐ │ ProtectedRoute │ │ - Checks auth │ │ - Redirects │ └──────────────────┘ ``` --- ## Real-time Communication ### WebSocket Protocol **Connection URL:** ``` wss://assist.asimo.io/api/realtime?conversationId={id}&token={jwt} ``` **Event Types:** - `delta` - Incremental text update during streaming - `chunk` - Complete text chunk - `message.done` - Final message with citations and metadata - `error` - Error occurred - `ping` - Heartbeat from client - `pong` - Heartbeat response from server **See detailed specification:** [docs/realtime/proxy-spec.md](./realtime/proxy-spec.md) --- ## Conversation Management ### Overview VoiceAssist implements a first-class conversation management system that allows users to organize their chat sessions into distinct conversations with titles, history, and metadata. Each conversation is a logical grouping of messages with its own WebSocket session and persistent history. ### Conversation Data Model ```typescript interface Conversation { id: string; // Unique conversation identifier userId: string; // Owner of the conversation title: string; // User-editable title createdAt: string; // ISO timestamp updatedAt: string; // ISO timestamp messageCount: number; // Total messages in conversation archived?: boolean; // Soft-delete flag lastMessagePreview?: string; // Snippet of last message } ``` **Key Fields:** - `id` - UUID generated on creation, used in URLs and WebSocket connections - `title` - Defaults to "New Conversation", user can rename inline - `archived` - Soft delete flag, archived conversations hidden from main list - `lastMessagePreview` - First ~100 chars of last message for quick preview ### Conversation Routing Model **URL Structure:** ``` /chat → Auto-creates conversation, redirects to /chat/:id /chat/:conversationId → Loads specific conversation with history ``` **Routing Behavior:** 1. **Landing on `/chat`:** - System creates a new conversation via `POST /api/conversations` - Redirects to `/chat/:conversationId` with `replace: true` - WebSocket connects automatically with new conversation ID 2. **Navigating to `/chat/:conversationId`:** - System validates conversation exists via `GET /api/conversations/:id` - If valid: Loads message history, connects WebSocket - If invalid (404): Shows error state with "Back to Conversations" button - If network error: Shows retry interface 3. **Switching Conversations:** - Old WebSocket connection automatically disconnects - Message state clears to prevent cross-contamination - New conversation history loads from API - New WebSocket connection establishes with new conversation ID ### Conversation Lifecycle ``` ┌──────────────┐ │ Created │ POST /api/conversations │ (Active) │ - title: "New Conversation" └──────┬───────┘ - archived: false │ │ User sends messages │ title updates automatically ▼ ┌──────────────┐ │ Active │ PATCH /api/conversations/:id │ (In Use) │ - User can rename └──────┬───────┘ - Messages accumulate │ - lastMessagePreview updates │ │ User archives ▼ ┌──────────────┐ │ Archived │ PATCH /api/conversations/:id │ (Hidden) │ { archived: true } └──────┬───────┘ - Removed from main list │ - Still accessible via URL │ │ User deletes ▼ ┌──────────────┐ │ Deleted │ DELETE /api/conversations/:id │ (Removed) │ - Permanently removed └──────────────┘ - All messages deleted ``` ### UI Components #### ConversationList Component **Location:** `apps/web-app/src/components/conversations/ConversationList.tsx` **Responsibilities:** - Fetches and displays list of conversations - Handles create, rename, archive, delete operations - Sorts by most recently updated - Filters archived vs active conversations - Loading, error, and empty states **States:** ```typescript - Loading: Shows spinner while fetching conversations - Error: Shows error message with retry button - Empty: Shows "No conversations" with create CTA - Populated: Shows scrollable list of conversations ``` **Actions:** ```typescript - Create: Creates new conversation, navigates to /chat/:id - Click: Navigates to /chat/:conversationId - Rename: Inline edit with Enter/Escape handlers - Archive: Soft deletes, removes from list - Delete: Shows confirmation dialog, permanently deletes ``` #### ConversationListItem Component **Location:** `apps/web-app/src/components/conversations/ConversationListItem.tsx` **Features:** - Displays title, last message preview, relative timestamp - Active state highlighting (current conversation) - Inline editing for rename (focus, Enter saves, Escape cancels) - 3-dot menu with Rename, Archive, Delete actions - Delete confirmation dialog to prevent accidents **UX Patterns:** - Truncates long titles and previews with ellipsis - Relative timestamps ("2 minutes ago", "3 hours ago") - Keyboard navigation support (Enter, Escape, Tab) - Confirmation dialog for destructive delete action #### MainLayout Integration **Location:** `apps/web-app/src/components/layout/MainLayout.tsx` **Behavior:** - Detects chat routes via `useLocation()` hook - Conditionally renders ConversationList in sidebar when on `/chat` routes - Shows traditional navigation (Home, Settings, etc.) on other routes - Responsive: Collapsible sidebar on mobile devices ```typescript const isChatRoute = location.pathname.startsWith('/chat'); // In sidebar: {isChatRoute ? ( ) : ( )} ``` #### ChatPage Integration **Location:** `apps/web-app/src/pages/ChatPage.tsx` **Conversation Initialization:** ```typescript 1. Extract conversationId from URL params 2. If no conversationId: - Create new conversation - Redirect to /chat/:newId 3. If conversationId present: - Validate conversation exists - Load message history - Connect WebSocket with conversationId 4. If invalid conversationId: - Show error state - Provide "Back to Conversations" button ``` **Error Handling:** - `not-found`: Conversation doesn't exist (404) - `failed-create`: Couldn't create conversation - `failed-load`: Network error loading conversation - `websocket`: Real-time connection errors ### API Integration **Conversation Endpoints:** ```typescript GET /api/conversations // List conversations GET /api/conversations/:id // Get specific conversation POST /api/conversations // Create conversation PATCH /api/conversations/:id // Update (rename/archive) DELETE /api/conversations/:id // Delete conversation ``` **Message Endpoints:** ```typescript GET /api/conversations/:id/messages // Get conversation history POST /api/conversations/:id/messages // Send message (REST fallback) ``` **WebSocket Connection:** ``` wss://assist.asimo.io/api/realtime?conversationId={id}&token={jwt} ``` ### State Management **Conversation State:** - Conversation list managed locally in `ConversationList` component - Active conversation stored in `ChatPage` component state - Message history synced between initial load and WebSocket updates **Message State:** - Initial messages loaded from REST API (`GET /messages`) - New messages received via WebSocket streaming - Combined into single message array in `useChatSession` hook **Navigation State:** - Active conversation highlighted in sidebar list - URL param (`conversationId`) drives conversation loading - Browser back/forward properly switches conversations ### Performance Considerations **Conversation List:** - Fetches up to 50 most recent conversations - Sorted by `updatedAt` on backend for efficiency - Frontend filtering for archived vs active - Pagination can be added if user has >50 conversations **Message History:** - Loads last 50 messages on conversation switch - Older messages can be lazy-loaded on scroll to top - Virtualized message rendering handles 1000+ messages **WebSocket Cleanup:** - Automatic disconnect when switching conversations - `useEffect` cleanup ensures no lingering connections - Reconnection logic prevents duplicate connections ### Related Documentation - [CONVERSATIONS_AND_ROUTING.md](./CONVERSATIONS_AND_ROUTING.md) - Detailed routing behavior - [REALTIME_PROXY_SPEC.md](./REALTIME_PROXY_SPEC.md) - WebSocket protocol - [TESTING_PHASE3.md](./TESTING_PHASE3.md) - Conversation testing plan --- ## Testing Architecture ### Test Coverage ``` apps/web-app/src/ ├── components/chat/__tests__/ │ ├── MessageBubble.test.tsx # Unit tests (14 cases) │ ├── MessageList.test.tsx # Unit tests (19 cases) │ ├── CitationDisplay.test.tsx # Unit tests (20 cases) │ └── MessageInput.test.tsx # Unit tests (28 cases) ├── hooks/__tests__/ │ └── useChatSession.test.ts # Unit tests (22 cases) └── __tests__/integration/ └── ChatFlow.test.tsx # Integration tests (8 flows) ``` **Test Stack:** - Vitest 4.0+ for test runner - @testing-library/react for component testing - @testing-library/user-event for user interactions - jsdom for DOM environment **See detailed testing guide:** [docs/client-implementation/TESTING_PHASE2.md](./TESTING_PHASE2.md) --- ## Deployment Architecture ### Build Process ```bash # Install dependencies pnpm install # Run tests pnpm test # Build for production pnpm build # Output: # apps/web-app/dist/ (static files for assist.asimo.io) ``` ### Production Deployment **Static Hosting:** - Main app (`assist.asimo.io`) served via CDN or static hosting - Admin panel (`admin.asimo.io`) served separately - Docs site (`docs.asimo.io`) proxied to Next.js runtime with `assistdocs.asimo.io` 301-redirected to the canonical host **Environment Variables:** ```bash VITE_API_URL=https://assist.asimo.io/api VITE_WS_URL=wss://assist.asimo.io/api/realtime VITE_ADMIN_URL=https://admin.asimo.io VITE_DOCS_URL=https://docs.asimo.io ``` --- ## Performance Optimizations ### Current Optimizations 1. **Message Virtualization** - react-virtuoso for efficient rendering of long message lists - Only visible messages are rendered in DOM - Supports 1000+ messages without performance degradation 2. **Component Memoization** - `MessageBubble` wrapped in `React.memo` to prevent unnecessary re-renders - Callbacks memoized with `useCallback` in `useChatSession` 3. **Streaming Optimizations** - Functional setState to avoid stale closures - Batched updates via React's state management - Ref-based streaming message to reduce state updates 4. **Code Splitting** - Lazy loading of routes with React.lazy - Syntax highlighter loaded on-demand - KaTeX loaded only when math equations present ### TODO: Future Optimizations - Implement pagination for conversations with >1000 messages - Add lazy loading of older messages on scroll to top - Implement message caching/indexing for very large histories - Add service worker for offline support - Implement request deduplication for API calls --- ## Security Considerations ### Authentication - JWT-based authentication with refresh tokens - Tokens stored in memory (not localStorage for XSS protection) - Automatic token refresh before expiration - Protected routes with `ProtectedRoute` component ### WebSocket Security - Token-based authentication in WebSocket URL - Connection validation on server - Rate limiting on message sending - Input sanitization on both client and server ### Content Security - Markdown sanitization via `react-markdown` - XSS prevention with proper escaping - HTTPS-only connections - Content Security Policy (CSP) headers --- ## Monitoring and Observability ### Client-Side Metrics **Performance Metrics:** - Message render time - WebSocket connection latency - Streaming latency (first token, total time) - Component re-render counts **Error Tracking:** - Error boundaries for graceful degradation - WebSocket connection errors - API request failures - User interaction errors **User Analytics:** - Message send frequency - Average conversation length - Feature usage (citations, attachments) - Connection quality metrics --- ## Related Documentation - [Client Folder Structure](./CLIENT_FOLDER_STRUCTURE.md) - [Real-time Proxy Specification](./REALTIME_PROXY_SPEC.md) - [Phase 2 Testing Plan](./TESTING_PHASE2.md) - [Development Workflow](./DEVELOPMENT_WORKFLOW.md) - [API Reference](../api-reference/rest-api.md) 6:["slug","client-implementation/ARCHITECTURE_OVERVIEW","c"] 0:["X7oMT3VrOffzp0qvbeOas",[[["",{"children":["docs",{"children":[["slug","client-implementation/ARCHITECTURE_OVERVIEW","c"],{"children":["__PAGE__?{\"slug\":[\"client-implementation\",\"ARCHITECTURE_OVERVIEW\"]}",{}]}]}]},"$undefined","$undefined",true],["",{"children":["docs",{"children":[["slug","client-implementation/ARCHITECTURE_OVERVIEW","c"],{"children":["__PAGE__",{},[["$L1",["$","div",null,{"children":[["$","div",null,{"className":"mb-6 flex items-center justify-between gap-4","children":[["$","div",null,{"children":[["$","p",null,{"className":"text-sm text-gray-500 dark:text-gray-400","children":"Docs / Raw"}],["$","h1",null,{"className":"text-3xl font-bold text-gray-900 dark:text-white","children":"Architecture Overview"}],["$","p",null,{"className":"text-sm text-gray-600 dark:text-gray-400","children":["Sourced from"," ",["$","code",null,{"className":"font-mono text-xs","children":["docs/","client-implementation/ARCHITECTURE_OVERVIEW.md"]}]]}]]}],["$","a",null,{"href":"https://github.com/mohammednazmy/VoiceAssist/edit/main/docs/client-implementation/ARCHITECTURE_OVERVIEW.md","target":"_blank","rel":"noreferrer","className":"inline-flex items-center gap-2 rounded-md border border-gray-200 dark:border-gray-700 px-3 py-1.5 text-sm text-gray-700 dark:text-gray-200 hover:border-primary-500 dark:hover:border-primary-400 hover:text-primary-700 dark:hover:text-primary-300","children":"Edit on GitHub"}]]}],["$","div",null,{"className":"rounded-lg border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 p-6","children":["$","$L2",null,{"content":"$3"}]}],["$","div",null,{"className":"mt-6 flex flex-wrap gap-2 text-sm","children":[["$","$L4",null,{"href":"/reference/all-docs","className":"inline-flex items-center gap-1 rounded-md bg-gray-100 px-3 py-1 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700","children":"← All documentation"}],["$","$L4",null,{"href":"/","className":"inline-flex items-center gap-1 rounded-md bg-gray-100 px-3 py-1 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700","children":"Home"}]]}]]}],null],null],null]},[null,["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","docs","children","$6","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children","docs","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/7f586cdbbaa33ff7.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","className":"h-full","children":["$","body",null,{"className":"__className_f367f3 h-full bg-white dark:bg-gray-900","children":[["$","a",null,{"href":"#main-content","className":"skip-to-content","children":"Skip to main content"}],["$","$L8",null,{"children":[["$","$L9",null,{}],["$","$La",null,{}],["$","main",null,{"id":"main-content","className":"lg:pl-64","role":"main","aria-label":"Documentation content","children":["$","$Lb",null,{"children":["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L7",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]]}]]}]}]],null],null],["$Lc",null]]]] c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Architecture Overview | Docs | VoiceAssist Docs"}],["$","meta","3",{"name":"description","content":"The VoiceAssist platform is deployed across three dedicated domains, each serving a specific purpose:"}],["$","meta","4",{"name":"keywords","content":"VoiceAssist,documentation,medical AI,voice assistant,healthcare,HIPAA,API"}],["$","meta","5",{"name":"robots","content":"index, follow"}],["$","meta","6",{"name":"googlebot","content":"index, follow"}],["$","link","7",{"rel":"canonical","href":"https://assistdocs.asimo.io"}],["$","meta","8",{"property":"og:title","content":"VoiceAssist Documentation"}],["$","meta","9",{"property":"og:description","content":"Comprehensive documentation for VoiceAssist - Enterprise Medical AI Assistant"}],["$","meta","10",{"property":"og:url","content":"https://assistdocs.asimo.io"}],["$","meta","11",{"property":"og:site_name","content":"VoiceAssist Docs"}],["$","meta","12",{"property":"og:type","content":"website"}],["$","meta","13",{"name":"twitter:card","content":"summary"}],["$","meta","14",{"name":"twitter:title","content":"VoiceAssist Documentation"}],["$","meta","15",{"name":"twitter:description","content":"Comprehensive documentation for VoiceAssist - Enterprise Medical AI Assistant"}],["$","meta","16",{"name":"next-size-adjust"}]] 1:null