Parent: Chat Service


System Diagram

flowchart TB
    subgraph clients [Client Applications]
        WebApp[Web App]
        MobileApp[Mobile App]
        AdminPanel[Admin Panel]
    end

    subgraph lb [Load Balancer]
        ALB[NGINX / AWS ALB]
    end

    subgraph servers [Server Instances]
        Server1[Server Instance 1<br/>Express + Socket.IO]
        Server2[Server Instance 2<br/>Express + Socket.IO]
        ServerN[Server Instance N<br/>Express + Socket.IO]
    end

    subgraph datastores [Data Stores]
        Redis[(Redis Cluster<br/>Pub/Sub + Cache)]
        PostgreSQL[(PostgreSQL<br/>Chat Data)]
        MySQL[(MySQL Jarvis<br/>Read-only)]
        S3[(AWS S3<br/>Image Storage)]
    end

    subgraph external [External Services]
        Cognito[AWS Cognito<br/>Customer Auth]
        OneSignal[OneSignal API<br/>Push Notifications]
    end

    clients -->|HTTPS/WSS| ALB
    ALB --> Server1
    ALB --> Server2
    ALB --> ServerN

    Server1 --> Redis
    Server2 --> Redis
    ServerN --> Redis

    Server1 --> PostgreSQL
    Server2 --> PostgreSQL
    ServerN --> PostgreSQL

    Server1 --> MySQL
    Server1 --> S3
    Server1 --> Cognito
    Server1 --> OneSignal

Application Layer Architecture

flowchart TB
    subgraph express [Express Application]
        Middleware[Middleware: Helmet, CORS, Compression, Logger, Auth]
        Routes[Routes: /api/chats/* → ChatController]
        Services[Services: ChatService, NotificationService, UploadService]
        Models[Models: ChatSession, ChatMessage, Customer, Dentist]
    end

    subgraph socketio [Socket.IO Server]
        SocketAuth[Auth Middleware]
        RoomMgmt[Room Management]
        EventHandlers[Event Handlers]
        RedisAdapter[Redis Adapter]
    end

    Middleware --> Routes
    Routes --> Services
    Services --> Models

    SocketAuth --> RoomMgmt
    RoomMgmt --> EventHandlers
    EventHandlers --> RedisAdapter

Authentication Flow

sequenceDiagram
    participant Client as Client App
    participant LB as Load Balancer
    participant Server as Express/Socket.IO
    participant Auth as Auth Provider

    Note over Auth: Cognito (Customers)<br/>Django JWT (Dentists)

    Client->>LB: Request + JWT Bearer Token
    LB->>Server: Forward Request
    Server->>Auth: Validate JWT (JWKS)
    Auth-->>Server: Token Valid
    Server->>Server: Extract user type & ID
    Server->>Server: Verify access permissions
    Server-->>Client: Response

Endpoint Types

PrefixAuth MethodUse Case
/api/chats/*JWT (Cognito or Django)User-facing endpoints (mobile/web app)

Key Design Decisions

  • Dual Database Architecture - PostgreSQL for chat data (sessions, messages), MySQL for legacy user data (customers, dentists). MySQL is read-only.

  • Redis Adapter for Socket.IO - Enables horizontal scaling without sticky sessions. Messages are broadcast across all server instances via Redis pub/sub.

  • Room-Based Architecture - Each chat session maps to a Socket.IO room (session:{id}). Both participants join the same room for message delivery.

  • Presigned URLs for Images - S3 images are accessed via time-limited presigned URLs for security.

  • Fire-and-Forget Notifications - Push notifications are sent asynchronously and never block API responses.

Local Development

docker compose up redis -d
 
npm i
 
npm run dev

Environment Variables

# Server
PORT=3000
NODE_ENV=production
 
# PostgreSQL (Chat Data)
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=chat_service
POSTGRES_USER=xxx
POSTGRES_PASSWORD=xxx
 
# MySQL (Jarvis - Read-only)
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_DB=jarvis
MYSQL_USER=xxx
MYSQL_PASSWORD=xxx
 
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=xxx
 
# AWS
AWS_REGION=eu-west-2
AWS_ACCESS_KEY_ID=xxx
AWS_SECRET_ACCESS_KEY=xxx
S3_BUCKET=chat-images-bucket
 
# Authentication
COGNITO_USER_POOL_ID=eu-west-2_XXXXXX
COGNITO_REGION=eu-west-2
DJANGO_JWT_SECRET=xxx
 
# OneSignal (Push Notifications)
ONESIGNAL_APP_ID=xxx
ONESIGNAL_API_KEY=xxx
 
# Logging
LOG_LEVEL=info

Deployment

  • Containerized: Docker support with multi-stage builds
  • Multi-instance: Supports horizontal scaling via Redis adapter
  • Load Balanced: Works with ALB or NGINX
  • Health Checks: /health endpoint for container orchestration
  • Graceful Shutdown: Handles SIGTERM for clean connection termination