System Architecture
STORM DAY is built on a microservices architecture where all inter-service communication flows through NATS message broker. The Gateway is the single entry point exposed to the internet.
Service Overview
Microservices
| Service | Stack |
|---|---|
| Gateway | Go (chi, gws) |
| User Service | NestJS, PostgreSQL |
| Message Service | Go, PostgreSQL |
| Notification Service | Go |
| Media Service | Go, MinIO |
Key Architectural Decisions
NATS for Inter-Service Communication
All services communicate through NATS pub/sub messaging, not HTTP. This decouples services and enables asynchronous processing.
Gateway as Single Entry Point
The Gateway is the ONLY service exposed to the internet. It handles JWT validation locally without NATS round-trips on every WebSocket frame.
SO_REUSEPORT for WebSocket Scaling
The Gateway uses SO_REUSEPORT to create NumCPU parallel TCP listeners for maximum WebSocket throughput.
Configurable Storage Backend
The message service supports two storage backends via environment variable: STORAGE=memory (default, for tests) or STORAGE=postgres.
NATS Message Flows
Messages flow through NATS subjects following a consistent naming pattern.
Message Broadcast
// Subject pattern for message broadcasts
message.broadcast.conversation:{conversation_id}
// Example: Broadcasting a new message
{
"action": "message",
"room": "conversation:abc123",
"user": "user-id",
"username": "john_doe",
"content": "Hello, world!",
"message_id": "msg-456"
}Typing Indicator
// Typing events are debounced to once per 2 seconds
{
"action": "typing",
"room": "conversation:abc123",
"user": "user-id",
"username": "john_doe"
}Infrastructure
Database Design
The system uses two separate PostgreSQL databases for better separation of concerns:
storm_user_db
User accounts, authentication tokens, and profile information managed by the User Service (NestJS).
storm_chat_db
Messages, conversations, group memberships, and chat-related data managed by the Message Service (Go).