DEV Community

Cover image for Building a Production-Ready AI ChatBot Platform with Real-Time Analytics
Vivek Yadav
Vivek Yadav

Posted on

Building a Production-Ready AI ChatBot Platform with Real-Time Analytics

๐ŸŽฏ Introduction

In this article, I'll walk you through the architecture and implementation of a complete, production-ready AI chatbot platform that I've built from scratch. This isn't just another chatbot tutorialโ€”it's a comprehensive system featuring OAuth 2.0 authentication, real-time WebSocket communication, OpenAI integration, and a full-featured analytics dashboard.

What makes this project special?

  • ๐Ÿ—๏ธ Microservices Architecture: Four independent services working together seamlessly
  • ๐Ÿ”’ Enterprise-Grade Security: OAuth 2.0 with JWT tokens and role-based access control
  • ๐Ÿ’ฌ Real-Time Communication: WebSocket support for instant messaging
  • ๐Ÿ“Š Integrated Analytics: Live metrics and user activity tracking
  • ๐Ÿš€ Production Ready: Docker deployment, comprehensive testing, and cross-platform support
  • ๐ŸŽจ Modern UI: Beautiful React interface with gradient themes and responsive design

Tech Stack:

  • Frontend: React 18, React Router, WebSocket API
  • Backend: FastAPI (Python 3.12+), SQLAlchemy, JWT
  • AI: OpenAI GPT-4
  • Database: SQLite (easily upgradeable to PostgreSQL)
  • Deployment: Docker, Docker Compose
  • Testing: Pytest, end-to-end test suite

๐Ÿ—๏ธ System Architecture

The platform consists of four microservices:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    React Frontend (Port 3000)               โ”‚
โ”‚  Chat Interface + Analytics Panel + Real-time Updates      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
               โ”‚
               โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚  Auth Service    โ”‚  โ”‚  Chat Service    โ”‚  โ”‚Analytics Service โ”‚
    โ”‚  (Port 8001)     โ”‚  โ”‚  (Port 8000)     โ”‚  โ”‚  (Port 8002)     โ”‚
    โ”‚                  โ”‚  โ”‚                  โ”‚  โ”‚                  โ”‚
    โ”‚ โ€ข User Mgmt      โ”‚  โ”‚ โ€ข Conversations  โ”‚  โ”‚ โ€ข Metrics        โ”‚
    โ”‚ โ€ข JWT Tokens     โ”‚โ—„โ”€โ”ค โ€ข OpenAI API     โ”‚โ”€โ–บโ”‚ โ€ข User Activity  โ”‚
    โ”‚ โ€ข RBAC           โ”‚  โ”‚ โ€ข WebSocket      โ”‚  โ”‚ โ€ข Token Tracking โ”‚
    โ”‚ โ€ข Auto Admin     โ”‚  โ”‚ โ€ข Analytics MW   โ”‚  โ”‚ โ€ข Admin API      โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Enter fullscreen mode Exit fullscreen mode

Why Microservices?

  1. Separation of Concerns: Each service has a single, well-defined responsibility
  2. Scalability: Scale services independently based on load
  3. Maintainability: Easier to understand, test, and modify individual components
  4. Technology Flexibility: Each service can use different technologies if needed
  5. Fault Isolation: If one service fails, others continue functioning

๐Ÿ” Authentication & Authorization

OAuth 2.0 Implementation

The auth service implements OAuth 2.0 with JWT tokens:

# auth-service/auth_server/security/auth.py
from jose import JWTError, jwt
from datetime import datetime, timedelta, timezone
from passlib.context import CryptContext

SECRET_KEY = os.getenv("AUTH_SECRET_KEY")
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 43200  # 30 days

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def create_access_token(data: dict):
    to_encode = data.copy()
    expire = datetime.now(timezone.utc) + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    to_encode.update({"exp": expire})
    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
    return encoded_jwt

def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password: str) -> str:
    return pwd_context.hash(password)
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • BCrypt Password Hashing: Secure password storage with automatic salting
  • JWT Tokens: Stateless authentication with 30-day expiration
  • Role-Based Access Control: Admin, User, Manager roles
  • Timezone-Aware: UTC timestamps for global compatibility

Automatic Admin Setup

One of my favorite featuresโ€”the system automatically creates an admin user on first startup:

# auth-service/auth_server/main.py
@app.on_event("startup")
async def startup_event():
    """Initialize database and create admin user if not exists"""
    create_db_and_tables()

    # Auto-create admin user
    admin_username = os.getenv("ADMIN_USERNAME", "admin")
    admin_password = os.getenv("ADMIN_PASSWORD", "admin123")
    admin_email = os.getenv("ADMIN_EMAIL", "admin@example.com")

    with Session(engine) as session:
        admin_user = session.exec(
            select(User).where(User.username == admin_username)
        ).first()

        if not admin_user:
            # Create admin with both admin and user roles
            admin_user = User(
                username=admin_username,
                email=admin_email,
                hashed_password=get_password_hash(admin_password)
            )
            session.add(admin_user)
            session.commit()
            session.refresh(admin_user)

            # Assign roles
            admin_role = session.exec(select(Role).where(Role.name == "admin")).first()
            user_role = session.exec(select(Role).where(Role.name == "user")).first()

            admin_user.roles.extend([admin_role, user_role])
            session.commit()

            print(f"โœ… Admin user '{admin_username}' created successfully!")
Enter fullscreen mode Exit fullscreen mode

No more manual SQL commands or bootstrap scripts! The admin user is ready to use immediately after deployment.

๐Ÿ’ฌ Real-Time Chat with WebSocket

WebSocket Connection Handler

The chat service uses WebSocket for real-time bidirectional communication:

# openai_web_service/websocket/chat_handler.py
@router.websocket("/ws/{conversation_id}")
async def websocket_endpoint(
    websocket: WebSocket,
    conversation_id: str,
    token: str = Query(None),
    db: Session = Depends(get_db)
):
    await websocket.accept()

    try:
        # Authenticate user from JWT token
        user_data = verify_access_token(token)
        user_id = user_data.get("user_id")

        # Verify conversation ownership
        conversation = get_conversation_by_id(db, conversation_id, user_id)
        if not conversation:
            await websocket.send_json({
                "type": "error",
                "message": "Conversation not found or access denied"
            })
            await websocket.close()
            return

        # Handle messages
        while True:
            data = await websocket.receive_json()

            if data.get("type") == "message":
                # Save user message
                user_message = create_message(
                    db, conversation_id, "user", data.get("content"), user_id
                )

                # Get AI response from OpenAI
                ai_response = await get_openai_response(
                    db, conversation_id, user_message.content
                )

                # Save AI message
                ai_message = create_message(
                    db, conversation_id, "assistant", ai_response, user_id
                )

                # Send to client
                await websocket.send_json({
                    "type": "message",
                    "role": "assistant",
                    "content": ai_response,
                    "message_id": ai_message.id,
                    "timestamp": ai_message.timestamp.isoformat()
                })

    except WebSocketDisconnect:
        print(f"Client disconnected from conversation {conversation_id}")
    except Exception as e:
        await websocket.send_json({
            "type": "error",
            "message": str(e)
        })
        await websocket.close()
Enter fullscreen mode Exit fullscreen mode

Key Features:

  • Token Authentication: Secure WebSocket connections with JWT
  • Conversation Ownership: Users can only access their own conversations
  • Auto-reconnection: Client automatically reconnects on disconnect (max 5 attempts)
  • Error Handling: Graceful error messages and cleanup

OpenAI Integration

The service integrates with OpenAI's GPT-4 API:

# openai_web_service/services/openai_service.py
async def get_openai_response(db: Session, conversation_id: str, user_message: str) -> str:
    """Get response from OpenAI API with conversation context"""

    # Get conversation history
    messages = get_messages_by_conversation(db, conversation_id)

    # Build context
    conversation_history = [
        {"role": msg.role, "content": msg.content}
        for msg in messages[-10:]  # Last 10 messages for context
    ]

    # Add system message
    conversation_history.insert(0, {
        "role": "system",
        "content": "You are a helpful AI assistant."
    })

    # Call OpenAI API
    response = await openai.ChatCompletion.acreate(
        model="gpt-4",
        messages=conversation_history,
        temperature=0.7,
        max_tokens=500
    )

    return response.choices[0].message.content
Enter fullscreen mode Exit fullscreen mode

Context Management: The system maintains conversation context by including the last 10 messages in each API call, ensuring coherent multi-turn conversations.

๐Ÿ“Š Analytics Dashboard

Real-Time Metrics Tracking

The analytics service tracks comprehensive metrics:

# analytics-service/analytics/services/analytics_service.py
class AnalyticsService:
    def get_summary_metrics(self, db: Session) -> dict:
        """Get overall platform statistics"""

        now = datetime.now(timezone.utc)
        today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)

        return {
            "total_users": db.query(UserActivity).distinct(UserActivity.user_id).count(),
            "active_users_today": db.query(UserActivity)
                .filter(UserActivity.timestamp >= today_start)
                .distinct(UserActivity.user_id)
                .count(),
            "total_conversations": db.query(ConversationMetrics).count(),
            "total_messages": db.query(MessageMetrics).count(),
            "total_tokens_used": db.query(func.sum(MessageMetrics.total_tokens)).scalar() or 0,
            "avg_response_time": db.query(func.avg(ApiUsage.response_time))
                .filter(ApiUsage.timestamp >= today_start)
                .scalar() or 0,
            "error_rate": self._calculate_error_rate(db, today_start)
        }
Enter fullscreen mode Exit fullscreen mode

Analytics Middleware

Automatic API usage tracking without cluttering application code:

# openai_web_service/middleware/analytics_middleware.py
@app.middleware("http")
async def analytics_tracking_middleware(request: Request, call_next):
    """Track all API requests for analytics"""

    start_time = time.time()

    # Process request
    response = await call_next(request)

    # Calculate response time
    response_time = time.time() - start_time

    # Extract user info from JWT token
    user_id = None
    if authorization := request.headers.get("authorization"):
        try:
            token = authorization.split("Bearer ")[1]
            user_data = verify_access_token(token)
            user_id = user_data.get("user_id")
        except:
            pass

    # Send to analytics service (fire-and-forget)
    asyncio.create_task(
        send_analytics_event({
            "event_type": "api_request",
            "user_id": user_id,
            "endpoint": str(request.url.path),
            "method": request.method,
            "status_code": response.status_code,
            "response_time": response_time,
            "timestamp": datetime.now(timezone.utc).isoformat()
        })
    )

    return response
Enter fullscreen mode Exit fullscreen mode

Fire-and-forget approach: Analytics tracking is non-blocking and doesn't impact API performance.

Frontend Analytics Panel

React component displaying live metrics:

// chat-frontend/src/components/AnalyticsPanel.js
function AnalyticsPanel({ isOpen, onClose }) {
  const [metrics, setMetrics] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchMetrics = async () => {
      try {
        const data = await analyticsService.getSummary();
        setMetrics(data);
      } catch (error) {
        console.error('Failed to fetch analytics:', error);
      } finally {
        setLoading(false);
      }
    };

    fetchMetrics();
    const interval = setInterval(fetchMetrics, 30000); // Refresh every 30s

    return () => clearInterval(interval);
  }, []);

  return (
    <div className={`analytics-panel ${isOpen ? 'open' : ''}`}>
      <div className="analytics-header">
        <h2>๐Ÿ“Š Analytics Dashboard</h2>
        <button onClick={onClose}>โœ•</button>
      </div>

      {loading ? (
        <Spinner />
      ) : (
        <div className="metrics-grid">
          <MetricCard
            icon="๐Ÿ‘ฅ"
            title="Total Users"
            value={metrics.total_users}
            color="#4a90e2"
          />
          <MetricCard
            icon="๐Ÿ”ฅ"
            title="Active Today"
            value={metrics.active_users_today}
            color="#f5a623"
          />
          <MetricCard
            icon="๐Ÿ’ฌ"
            title="Conversations"
            value={metrics.total_conversations}
            color="#7ed321"
          />
          <MetricCard
            icon="๐Ÿ“จ"
            title="Messages"
            value={metrics.total_messages}
            color="#bd10e0"
          />
          <MetricCard
            icon="๐ŸŽฏ"
            title="Tokens Used"
            value={metrics.total_tokens_used.toLocaleString()}
            color="#ff6b6b"
          />
          <MetricCard
            icon="โšก"
            title="Avg Response"
            value={`${(metrics.avg_response_time * 1000).toFixed(0)}ms`}
            color="#4ecdc4"
          />
        </div>
      )}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Auto-refresh: Metrics update every 30 seconds without user interaction.

๐Ÿณ Docker Deployment

Docker Compose Configuration

Complete stack deployment with one command:

# docker-compose.yml
version: '3.8'

services:
  auth-service:
    build: ./auth-service
    ports:
      - "8001:8001"
    environment:
      - AUTH_SECRET_KEY=${AUTH_SECRET_KEY}
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=admin123
      - ADMIN_EMAIL=admin@example.com
    networks:
      - chatbot-network

  openai_web_service:
    build: ./openai_web_service
    ports:
      - "8000:8000"
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - AUTH_SECRET_KEY=${AUTH_SECRET_KEY}
      - AUTH_SERVICE_URL=http://auth-service:8001
      - ANALYTICS_SERVICE_URL=http://analytics-service:8002
    depends_on:
      - auth-service
      - analytics-service
    networks:
      - chatbot-network

  analytics-service:
    build: ./analytics-service
    ports:
      - "8002:8002"
    environment:
      - AUTH_SECRET_KEY=${AUTH_SECRET_KEY}
      - AUTH_SERVICE_URL=http://auth-service:8001
    depends_on:
      - auth-service
    networks:
      - chatbot-network

  chat-frontend:
    build: ./chat-frontend
    ports:
      - "3000:3000"
    environment:
      - REACT_APP_AUTH_API_URL=http://localhost:8001
      - REACT_APP_CHAT_API_URL=http://localhost:8000
      - REACT_APP_ANALYTICS_API_URL=http://localhost:8002
      - REACT_APP_WS_URL=ws://localhost:8000
    depends_on:
      - auth-service
      - openai_web_service
      - analytics-service
    networks:
      - chatbot-network

networks:
  chatbot-network:
    driver: bridge
Enter fullscreen mode Exit fullscreen mode

Deploy with one command:

docker-compose up --build
Enter fullscreen mode Exit fullscreen mode

๐Ÿš€ Cross-Platform Local Development

Platform-Specific Scripts

I created comprehensive script suites for Windows, macOS, and Linux:

Windows (scripts/windows/):

:: start-all-services.bat
@echo off
cd /d %~dp0..\..

:: Start auth service
start "Auth Service" cmd /k "cd auth-service && venv\Scripts\activate && uvicorn auth_server.main:app --reload --port 8001"

:: Start chat service
start "Chat Service" cmd /k "cd openai_web_service && venv\Scripts\activate && uvicorn main:app --reload --port 8000"

:: Start analytics service
start "Analytics Service" cmd /k "cd analytics-service && venv\Scripts\activate && uvicorn main:app --reload --port 8002"

:: Start frontend
start "Frontend" cmd /k "cd chat-frontend && npm start"

echo All services started!
Enter fullscreen mode Exit fullscreen mode

Linux/Mac (scripts/linux-mac/):

#!/bin/bash
# start-all-services.sh

PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

# Detect terminal emulator
if [[ "$OSTYPE" == "darwin"* ]]; then
    TERMINAL="Terminal"
else
    TERMINAL="gnome-terminal"
fi

# Start auth service
$TERMINAL -- bash -c "cd $PROJECT_ROOT/auth-service && source venv/bin/activate && uvicorn auth_server.main:app --reload --port 8001; exec bash"

# Start chat service
$TERMINAL -- bash -c "cd $PROJECT_ROOT/openai_web_service && source venv/bin/activate && uvicorn main:app --reload --port 8000; exec bash"

# Start analytics service
$TERMINAL -- bash -c "cd $PROJECT_ROOT/analytics-service && source venv/bin/activate && uvicorn main:app --reload --port 8002; exec bash"

# Start frontend
$TERMINAL -- bash -c "cd $PROJECT_ROOT/chat-frontend && npm start; exec bash"

echo "All services started!"
Enter fullscreen mode Exit fullscreen mode

One-command setup:

# Windows
scripts\windows\setup-venv.bat
scripts\windows\start-all-services.bat

# Linux/Mac
scripts/linux-mac/setup-venv.sh
scripts/linux-mac/start-all-services.sh
Enter fullscreen mode Exit fullscreen mode

๐Ÿงช Comprehensive Testing

End-to-End Test Suite

Over 50 test cases covering all functionality:

# tests/test_4_end_to_end.py
import pytest
from datetime import datetime, timezone

class TestEndToEndFlow:
    """Complete user journey tests"""

    def test_complete_user_journey_rest_api(self):
        """Test complete user flow using REST API"""

        # 1. Register user
        register_data = {
            "username": f"user_{int(datetime.now(timezone.utc).timestamp())}",
            "email": f"user_{int(datetime.now(timezone.utc).timestamp())}@test.com",
            "password": "testpass123",
            "full_name": "Test User"
        }
        register_response = requests.post(
            f"{AUTH_BASE_URL}/users/", 
            json=register_data
        )
        assert register_response.status_code == 200

        # 2. Login
        login_data = {
            "username": register_data["username"],
            "password": register_data["password"]
        }
        token_response = requests.post(
            f"{AUTH_BASE_URL}/auth/token",
            data=login_data
        )
        assert token_response.status_code == 200
        token = token_response.json()["access_token"]

        headers = {"Authorization": f"Bearer {token}"}

        # 3. Create conversation
        conv_response = requests.post(
            f"{CHAT_BASE_URL}/conversations/",
            json={"title": "Test Conversation"},
            headers=headers
        )
        assert conv_response.status_code == 200
        conversation_id = conv_response.json()["id"]

        # 4. Send message
        message_response = requests.post(
            f"{CHAT_BASE_URL}/conversations/{conversation_id}/messages",
            json={
                "conversation_id": conversation_id,
                "role": "user",
                "content": "Hello, AI!"
            },
            headers=headers
        )
        assert message_response.status_code == 200

        # 5. Get message history
        history_response = requests.get(
            f"{CHAT_BASE_URL}/conversations/{conversation_id}/messages",
            headers=headers
        )
        assert history_response.status_code == 200
        assert len(history_response.json()) >= 2  # User + AI response

        # 6. Delete conversation
        delete_response = requests.delete(
            f"{CHAT_BASE_URL}/conversations/{conversation_id}",
            headers=headers
        )
        assert delete_response.status_code == 200

    def test_websocket_real_time_messaging(self):
        """Test WebSocket real-time communication"""

        # Register and login
        token = self.get_test_token()

        # Connect WebSocket
        ws_url = f"{WS_BASE_URL}/ws/test-conversation?token={token}"
        ws = websocket.create_connection(ws_url)

        # Send message
        ws.send(json.dumps({
            "type": "message",
            "content": "Test WebSocket message"
        }))

        # Receive AI response
        response = json.loads(ws.recv())
        assert response["type"] == "message"
        assert response["role"] == "assistant"
        assert len(response["content"]) > 0

        ws.close()
Enter fullscreen mode Exit fullscreen mode

Run tests:

pytest tests/ -v --cov=. --cov-report=html
Enter fullscreen mode Exit fullscreen mode

๐ŸŽจ UI/UX Highlights

Responsive Design

The frontend adapts seamlessly to all screen sizes:

/* chat-frontend/src/components/ChatPage.css */
.chat-page {
  display: flex;
  height: 100vh;
}

.sidebar {
  width: 300px;
  min-width: 300px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
}

/* Mobile responsive */
@media (max-width: 768px) {
  .sidebar {
    position: fixed;
    left: -300px;
    transition: left 0.3s ease;
    z-index: 1000;
  }

  .sidebar.open {
    left: 0;
  }

  .analytics-panel {
    width: 100% !important;
  }
}
Enter fullscreen mode Exit fullscreen mode

Gradient Themes

Beautiful gradient color schemes throughout:

/* Conversation list gradients */
.conversation-item {
  background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.2);
}

/* Message bubbles */
.user-message {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.ai-message {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  color: white;
}

/* Analytics metrics */
.metric-card {
  background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%);
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
}
Enter fullscreen mode Exit fullscreen mode

๐Ÿ”ง Configuration Management

3-Tier Environment System

Root .env (shared secrets):

AUTH_SECRET_KEY=your-super-secret-key-here
OPENAI_API_KEY=sk-your-openai-api-key
Enter fullscreen mode Exit fullscreen mode

Service .env files (service-specific):

# auth-service/.env
PORT=8001
HOST=0.0.0.0
CORS_ORIGINS=http://localhost:3000
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123
ADMIN_EMAIL=admin@example.com

# openai_web_service/.env
PORT=8000
HOST=0.0.0.0
AUTH_SERVICE_URL=http://localhost:8001
ANALYTICS_SERVICE_URL=http://localhost:8002
CORS_ORIGINS=http://localhost:3000

# analytics-service/.env
PORT=8002
HOST=0.0.0.0
AUTH_SERVICE_URL=http://localhost:8001
CORS_ORIGINS=http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Frontend .env:

REACT_APP_AUTH_API_URL=http://localhost:8001
REACT_APP_CHAT_API_URL=http://localhost:8000
REACT_APP_ANALYTICS_API_URL=http://localhost:8002
REACT_APP_WS_URL=ws://localhost:8000
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ˆ Performance Optimizations

Database Optimization

Absolute Paths: Databases use absolute paths to prevent multiple database files:

# openai_web_service/engine/database.py
from pathlib import Path

# Get service directory
service_dir = Path(__file__).parent.parent

# Create data directory
data_dir = service_dir / "data"
data_dir.mkdir(parents=True, exist_ok=True)

# Database path
db_path = data_dir / "chatbot.db"
DATABASE_URL = f"sqlite:///{db_path}"
Enter fullscreen mode Exit fullscreen mode

Caching Strategy

Static Asset Caching in Nginx configuration:

# chat-frontend/nginx.conf
server {
    listen 3000;
    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    # Cache static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
Enter fullscreen mode Exit fullscreen mode

WebSocket Connection Pooling

Efficient connection management:

// chat-frontend/src/hooks/useChat.js
const [ws, setWs] = useState(null);
const reconnectAttemptsRef = useRef(0);
const maxReconnectAttempts = 5;

const connect = useCallback(() => {
  if (ws?.readyState === WebSocket.OPEN) {
    ws.close();
  }

  const token = localStorage.getItem('token');
  const websocket = new WebSocket(
    `${WS_URL}/ws/${conversationId}?token=${token}`
  );

  websocket.onopen = () => {
    console.log('WebSocket connected');
    reconnectAttemptsRef.current = 0;
  };

  websocket.onclose = () => {
    if (reconnectAttemptsRef.current < maxReconnectAttempts) {
      setTimeout(() => {
        reconnectAttemptsRef.current++;
        connect();
      }, 2000 * reconnectAttemptsRef.current);
    }
  };

  setWs(websocket);
}, [conversationId]);
Enter fullscreen mode Exit fullscreen mode

๐Ÿ›ก๏ธ Security Best Practices

1. Password Security

  • BCrypt hashing with automatic salting
  • Minimum password complexity requirements
  • Password updates require current password

2. JWT Token Security

  • HS256 algorithm
  • 30-day expiration (configurable)
  • Token refresh mechanism
  • Secure storage in localStorage (HTTPS only in production)

3. CORS Configuration

  • Whitelist specific origins
  • No wildcard (*) in production
  • Credentials support enabled

4. SQL Injection Prevention

  • SQLAlchemy ORM (parameterized queries)
  • Input validation with Pydantic schemas
  • No raw SQL queries

5. XSS Protection

  • React's built-in XSS protection
  • Content Security Policy headers
  • Sanitized user inputs

6. Rate Limiting (Future Enhancement)

# Future implementation
from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)

@app.get("/api/endpoint")
@limiter.limit("5/minute")
async def endpoint():
    pass
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“Š Monitoring & Observability

Health Check Endpoints

All services expose health checks:

@app.get("/health")
async def health_check():
    return {
        "status": "healthy",
        "service": "auth-service",
        "version": "1.1.0",
        "timestamp": datetime.now(timezone.utc).isoformat()
    }
Enter fullscreen mode Exit fullscreen mode

Logging Configuration

Structured logging with levels:

import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('app.log'),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)
Enter fullscreen mode Exit fullscreen mode

Metrics Collection

Analytics service tracks:

  • API response times
  • Error rates
  • Token usage
  • User activity
  • Conversation metrics

๐Ÿšข Deployment Strategies

Docker Production Deployment

# Build images
docker-compose build

# Deploy in detached mode
docker-compose up -d

# View logs
docker-compose logs -f

# Scale services
docker-compose up -d --scale openai_web_service=3
Enter fullscreen mode Exit fullscreen mode

Environment-Specific Configurations

# docker-compose.prod.yml
services:
  openai_web_service:
    environment:
      - ENVIRONMENT=production
      - DEBUG=false
      - LOG_LEVEL=WARNING
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.50'
          memory: 512M
Enter fullscreen mode Exit fullscreen mode

CI/CD Pipeline (Example)

# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run tests
        run: |
          pip install -r requirements.txt
          pytest tests/ -v

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to production
        run: |
          docker-compose -f docker-compose.prod.yml up -d --build
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“š Lessons Learned

1. Start with Microservices from Day One

Breaking the system into services early made scaling and maintenance much easier. Each service can be deployed, tested, and scaled independently.

2. Invest in Developer Experience

Creating platform-specific scripts saved countless hours. One-command setup and deployment significantly lowered the barrier to entry for new contributors.

3. Security is Not Optional

Implementing OAuth 2.0, RBAC, and proper password hashing from the beginning prevented major refactoring later. Security should be baked in, not bolted on.

4. Real-Time Features Require Careful Planning

WebSocket implementation required thinking about connection management, reconnection logic, and error handling upfront. The fire-and-forget analytics tracking pattern kept the main application performant.

5. Documentation is Code

Comprehensive READMEs and setup guides made onboarding new developers seamless. The time invested in documentation paid dividends in reduced support questions.

6. Test Everything

The end-to-end test suite caught numerous edge cases and integration issues. Having 50+ tests gave confidence to refactor and add features.

๐Ÿ”ฎ Future Enhancements

Short-Term (Next 3 Months)

  • [ ] PostgreSQL migration for production
  • [ ] Redis for session management and caching
  • [ ] Rate limiting on API endpoints
  • [ ] Conversation search functionality
  • [ ] Message editing and deletion
  • [ ] File upload support
  • [ ] Voice input/output

Medium-Term (3-6 Months)

  • [ ] Multi-model support (GPT-4, Claude, Gemini)
  • [ ] Conversation sharing and collaboration
  • [ ] Custom AI assistant personas
  • [ ] API key management for users
  • [ ] Advanced analytics (charts, graphs, exports)
  • [ ] Mobile app (React Native)
  • [ ] Email notifications

Long-Term (6-12 Months)

  • [ ] Multi-tenancy support
  • [ ] Plugin system for extensions
  • [ ] Kubernetes deployment
  • [ ] GraphQL API
  • [ ] Real-time collaboration features
  • [ ] Advanced AI features (RAG, function calling)
  • [ ] Marketplace for custom assistants

๐ŸŽ“ Key Takeaways

If you're building a similar system, here are my recommendations:

  1. Architecture: Start with a clear separation of concerns. Microservices may seem overkill initially, but they pay off quickly.

  2. Security: Don't compromise on security. OAuth 2.0, JWT, RBAC, and proper password hashing are table stakes.

  3. Real-Time: WebSocket adds complexity but provides a superior user experience. Plan for connection management and error recovery.

  4. Testing: Write tests as you go. End-to-end tests are especially valuable for catching integration issues.

  5. Documentation: Document everything. Future you (and your team) will thank you.

  6. Developer Experience: Invest in tooling and scripts. One-command setup and deployment are worth the effort.

  7. Observability: Build in logging, metrics, and health checks from day one. You can't debug what you can't see.

๐Ÿ“ฆ Project Repository

GitHub: github.com/vcse59/ConvoAI

Quick Start

# Clone repository
git clone https://github.com/vcse59/ConvoAI.git
cd ConvoAI

# Create .env file
echo "AUTH_SECRET_KEY=your-secret-key" > .env
echo "OPENAI_API_KEY=sk-your-key" >> .env

# Docker deployment
docker-compose up --build

# Or local development (Windows)
scripts\windows\setup-venv.bat
scripts\windows\start-all-services.bat

# Or local development (Linux/Mac)
scripts/linux-mac/setup-venv.sh
scripts/linux-mac/start-all-services.sh

# Access at http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Project Stats

  • Lines of Code: ~15,000+
  • Services: 4 (Frontend, Auth, Chat, Analytics)
  • Test Coverage: 80%+
  • Documentation: 6,000+ lines
  • Scripts: 22 platform-specific automation scripts

๐Ÿค Contributing

Contributions are welcome! Areas where help is needed:

  • Additional language models integration
  • Mobile app development
  • Performance optimizations
  • UI/UX improvements
  • Documentation translations
  • Additional test coverage

๐Ÿ“„ License

MIT License - See LICENSE file for details.

๐Ÿ™ Acknowledgments

  • FastAPI: Amazing Python web framework
  • React: Excellent frontend library
  • OpenAI: GPT-4 API for AI responses
  • SQLAlchemy: Powerful ORM
  • Docker: Simplified deployment

๐Ÿ“ž Contact


Built with โค๏ธ using React, FastAPI, and OpenAI

If you found this article helpful, please give it a โค๏ธ and follow for more content on full-stack development, AI integration, and microservices architecture!


๐Ÿ’ก Questions?

Drop your questions in the comments below! I'm happy to discuss:

  • Architecture decisions and tradeoffs
  • Implementation details
  • Deployment strategies
  • Scaling considerations
  • Security best practices
  • Testing approaches

Let's build amazing things together! ๐Ÿš€

Top comments (0)