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
| Prefix | Auth Method | Use 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 devEnvironment 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=infoDeployment
- Containerized: Docker support with multi-stage builds
- Multi-instance: Supports horizontal scaling via Redis adapter
- Load Balanced: Works with ALB or NGINX
- Health Checks:
/healthendpoint for container orchestration - Graceful Shutdown: Handles SIGTERM for clean connection termination