Parent: Chat Service


REST API Request Flow

sequenceDiagram
    participant Client as Client App
    participant LB as Load Balancer
    participant MW as Express Middleware
    participant Ctrl as Controller
    participant Svc as Service
    participant DB as Database

    Client->>LB: HTTP Request
    LB->>MW: Forward Request
    MW->>MW: Auth (JWT verification)
    MW->>MW: Rate Limiting
    MW->>MW: Request Validation
    MW->>Ctrl: Validated Request
    Ctrl->>Svc: Business Logic
    Svc->>DB: Database Query
    DB-->>Svc: Result
    Svc-->>Ctrl: Processed Data
    Ctrl-->>Client: HTTP Response

WebSocket Message Flow

sequenceDiagram
    participant Client as Client Socket
    participant SocketIO as Socket.IO Server
    participant Auth as Auth Middleware
    participant Handler as Event Handler
    participant Svc as Service Layer
    participant DB as PostgreSQL
    participant Redis as Redis Adapter

    Client->>SocketIO: Connect + JWT
    SocketIO->>Auth: Validate Token
    Auth-->>SocketIO: Authenticated
    SocketIO->>SocketIO: Join Room (session:123)
    SocketIO-->>Client: connected event

    Client->>Handler: message:send
    Handler->>Svc: Process Message
    Svc->>DB: Save Message
    DB-->>Svc: Message ID
    Svc->>SocketIO: Broadcast to Room
    SocketIO->>Redis: Publish to Channel
    Redis-->>SocketIO: Sync Across Instances
    SocketIO-->>Client: message:new

Room-Based Architecture

Each chat session maps to a Socket.IO room named session:{id}. When users connect, they automatically join rooms for all their active chat sessions.

flowchart TB
    subgraph server1 [Server Instance 1]
        Room123_S1[Room: session:123]
        Customer1[Customer Socket]
        Customer1 --> Room123_S1
    end

    subgraph server2 [Server Instance 2]
        Room123_S2[Room: session:123]
        Dentist1[Dentist Socket]
        Dentist1 --> Room123_S2
    end

    subgraph redis [Redis Adapter]
        PubSub[Pub/Sub Channel]
    end

    Room123_S1 <-->|sync| PubSub
    Room123_S2 <-->|sync| PubSub

Key Points:

  • Users can be connected to different server instances
  • Redis adapter syncs room membership and events across instances
  • Messages sent to a room are delivered to all participants regardless of which server they’re connected to

Send Message Flow

flowchart TD
    A[Client sends message] --> B{Via REST or Socket?}
    
    B -->|REST API| C[Authenticate JWT]
    B -->|Socket.IO| D[Already authenticated]
    
    C --> E[Verify session access]
    D --> E
    
    E --> F{Has images?}
    F -->|Yes| G[Upload to S3]
    F -->|No| H[Continue]
    G --> H
    
    H --> I[Save message to PostgreSQL]
    I --> J[Broadcast to Socket.IO room]
    J --> K[Redis adapter syncs to other instances]
    
    K --> L{Recipient online?}
    L -->|Yes| M[Deliver via WebSocket]
    L -->|No| N[Send push notification]
    
    M --> O[Done]
    N --> O

Push Notification Logic

Push notifications are sent when the message recipient is offline (not connected to any Socket.IO server instance).

flowchart TD
    A[Message saved to DB] --> B[Check recipient online status]
    B --> C{Is recipient in any room?}
    C -->|Yes| D[Skip notification]
    C -->|No| E[Lookup OneSignal player ID]
    E --> F{Player ID exists?}
    F -->|No| G[Skip notification]
    F -->|Yes| H[Send push via OneSignal]
    H --> I[Fire and forget]

OneSignal Integration:

  • Player IDs are stored in customer_notification_mapping
  • Notifications include sender name and message preview
  • Deep links open the specific chat in the mobile app

Message Read Flow

sequenceDiagram
    participant Recipient as Recipient Client
    participant Server as Socket.IO Server
    participant DB as PostgreSQL
    participant Sender as Sender Client

    Recipient->>Server: message:read (messageId)
    Server->>DB: Update is_read, read_at
    DB-->>Server: Updated
    Server->>Sender: message:read_receipt
    Note over Sender: UI updates read status

Typing Indicator Flow

sequenceDiagram
    participant UserA as User A (Typing)
    participant Server as Socket.IO Server
    participant UserB as User B (Viewing)

    UserA->>Server: typing:start
    Server->>UserB: typing:indicator (isTyping: true)
    Note over UserB: Show typing indicator

    Note over UserA: User stops typing (3s timeout)
    UserA->>Server: typing:stop
    Server->>UserB: typing:indicator (isTyping: false)
    Note over UserB: Hide typing indicator

Horizontal Scaling

The Chat Service is designed for horizontal scaling without sticky sessions.

flowchart TB
    subgraph clients [Clients]
        C1[Client 1]
        C2[Client 2]
        C3[Client 3]
    end

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

    subgraph servers [Server Pool]
        S1[Instance 1]
        S2[Instance 2]
        S3[Instance 3]
    end

    subgraph redis [Redis]
        Adapter[Socket.IO Adapter]
        Cache[JWKS Cache]
    end

    C1 --> ALB
    C2 --> ALB
    C3 --> ALB

    ALB --> S1
    ALB --> S2
    ALB --> S3

    S1 <--> Adapter
    S2 <--> Adapter
    S3 <--> Adapter

    S1 --> Cache
    S2 --> Cache
    S3 --> Cache

Scaling Mechanisms:

ComponentStrategy
WebSocket connectionsRedis adapter for cross-instance messaging
JWT validationJWKS cached in Redis
Database connectionsConnection pooling per instance
Session stateStateless design - no server-side sessions
Room membershipSynchronized via Redis adapter

Image Upload Flow

flowchart LR
    A[Client uploads image] --> B[Multer middleware]
    B --> C[Validate file type/size]
    C --> D[Generate S3 key]
    D --> E[Upload to S3]
    E --> F[Store S3 key in message]
    F --> G[Generate presigned URL]
    G --> H[Return URL to clients]

S3 Key Format:

chat-service/sessions/{sessionId}/messages/{messageId}/{uuid}.{ext}

Presigned URLs:

  • Generated on-demand when fetching messages
  • Expire after 60 minutes for security
  • Support for multiple images per message (max 5)

Security Measures

MeasureImplementation
AuthenticationJWT verification (Cognito + Django)
AuthorizationUser must be participant in chat session
Rate LimitingPer-user and per-IP limits
Input ValidationRequest body validation via middleware
XSS ProtectionHelmet middleware
CORSConfigured allowed origins
Presigned URLsTime-limited S3 access