Real-time browser-based chat application with stock quote bot integration.
- Real-time chat with WebSocket
- User authentication (session-based)
- Stock quote bot (
/stock=AAPL.UScommand) - Multiple chatrooms support
- Last 50 messages display (ordered by timestamp)
- Decoupled microservices architecture
- Chat Server: HTTP/WebSocket server for user interactions
- Stock Bot: Decoupled service for fetching stock quotes
- PostgreSQL: Database for users, messages, chatrooms
- RabbitMQ: Message broker for async communication
- Docker & Docker Compose
- Go 1.21+ (for local development)
- Task - Modern task runner (replaces Make)
# macOS
brew install go-task/tap/go-task
# Linux
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin
# Windows (with Scoop)
scoop install task
# Or download binary from https://github.com/go-task/task/releasesPrerequisites: Docker and Docker Compose must be installed and running.
# Start all services (Docker Compose)
task docker:run
# Wait for services to be ready (~30 seconds)
# Chat: http://localhost:8080
# Swagger UI: http://localhost:8081/swagger/
# RabbitMQ Management: http://localhost:15672 (guest/guest)Note: Database migrations run automatically during service startup.
- PostgreSQL 13+
- RabbitMQ 3.12+
- Go 1.21+
# Install and start PostgreSQL
brew install postgresql
brew services start postgresql
# Create database and user
psql -U postgres << EOF
CREATE USER jobsity WITH PASSWORD 'jobsity123';
CREATE DATABASE jobsity_chat OWNER jobsity;
GRANT ALL PRIVILEGES ON DATABASE jobsity_chat TO jobsity;
EOF
psql -U postgres -d jobsity_chat << EOF
GRANT ALL ON SCHEMA public TO jobsity;
GRANT CREATE ON SCHEMA public TO jobsity;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO jobsity;
EOF
# Install and start RabbitMQ
brew install rabbitmq
brew services start rabbitmq
# Download Go dependencies
go mod download# Run chat server (on port 8080)
task run:server
# Run stock bot in another terminal
task run:bot
# In another terminal, run tests
task test # Run all tests (unit + E2E)
task test:unit # Run unit tests only (~2 min, no Docker needed)
task test:e2e # Run E2E tests only (~3 min, requires Docker)Copy .env.example to .env and configure:
DATABASE_URL: PostgreSQL connection stringRABBITMQ_URL: RabbitMQ connection stringSESSION_SECRET: Secret for session encryptionSTOOQ_API_URL: Stock API base URL
POST /api/v1/auth/register- Register new userPOST /api/v1/auth/login- Login userGET /api/v1/auth/me- Get current user infoPOST /api/v1/auth/logout- Logout userGET /api/v1/chatrooms- List chatroomsPOST /api/v1/chatrooms- Create chatroomPOST /api/v1/chatrooms/{id}/join- Join chatroomGET /api/v1/chatrooms/{id}/messages- Get last 50 messagesWS /ws/chat/{chatroom_id}- WebSocket connection for real-time chat
The API is fully documented with OpenAPI 3.0 specification. You can explore and test all endpoints using Swagger UI.
# Start all services including Swagger UI
docker-compose -f containers/docker-compose.yml up -d
# Access Swagger UI (note the /swagger/ path)
open http://localhost:8081/swagger/The Swagger UI will automatically load the OpenAPI specification from artifacts/openapi.yaml and provide:
- π Complete API documentation with examples
- π§ͺ Interactive endpoint testing (try it out!)
- π Request/response schemas
- π Authentication testing with session cookies
If you only want to run Swagger UI:
docker run -p 8081:8080 \
-e SWAGGER_JSON=/api/openapi.yaml \
-e BASE_URL=/swagger \
-v $(pwd)/artifacts:/api \
swaggerapi/swagger-uiThen visit: http://localhost:8081/swagger/
The complete OpenAPI spec is available at artifacts/openapi.yaml and includes:
- All 10 REST endpoints + WebSocket documentation
- Request/response schemas with examples
- Authentication requirements (session-based cookies)
- Error responses and status codes
- Full validation with automatic runtime checks (dev mode)
Services URLs:
- π Chat Application: http://localhost:8080
- π Swagger UI: http://localhost:8081/swagger/
- π° RabbitMQ Management: http://localhost:15672 (guest/guest)
Send /stock=AAPL.US in the chat to get stock quotes.
Bot responds with: AAPL.US quote is $93.42 per share
User sends /stock=AAPL.US
β
Chat Server (WebSocket) receives message
β
Publishes to RabbitMQ: "chat.commands" exchange
β
Stock Bot consumes from "chat.commands" queue
β
Fetches quote from Stooq API
β
Publishes response to RabbitMQ: "chat.responses" exchange
β
ResponseConsumer receives from "chat.responses" queue
β
Broadcasts to WebSocket clients via Hub
β
All users in chatroom see the stock quote
The application includes comprehensive observability features:
- Structured Logging: JSON formatted logs with context (slog)
- Prometheus Metrics:
- HTTP request duration and count (by method, path, status)
- WebSocket active connections (by chatroom)
- WebSocket messages sent (by chatroom)
- Request Tracing: Request IDs propagated through context
Access metrics at: http://localhost:9090 (if Prometheus is configured)
- Unit Tests: 630+ tests covering all packages (fast, no Docker)
- E2E Tests: 63+ tests with real services (PostgreSQL, RabbitMQ, WebSocket)
- Messaging Tests: 11 new E2E tests for RabbitMQ integration
- Coverage: ~77% across the codebase
# Run all tests (unit + E2E)
task tests
# Run unit tests only (fast, ~2 minutes, no Docker required)
task test:unit
# Run E2E tests only (requires Docker, ~3 minutes)
task test:e2e
# Generate coverage report
task coverage
# Run linters
task lint
# Format code
task fmt| Type | Speed | Docker | Command | Use Case |
|---|---|---|---|---|
| Unit | ~2min | β | task test:unit |
Fast feedback during development |
| E2E | ~3min | β | task test:e2e |
Full integration testing |
| All | ~5min | β | task tests |
CI/CD pipeline |
tests/e2e/
βββ setup_test.go # E2E infrastructure (Docker, DB, RabbitMQ)
βββ auth_e2e_test.go # Authentication tests
βββ chatroom_e2e_test.go # Chatroom functionality tests
βββ websocket_e2e_test.go # WebSocket communication tests
βββ repository_e2e_test.go # Database repository tests
βββ messaging_e2e_test.go # RabbitMQ integration tests (NEW)
βββ helpers_test.go # Test utilities and helpers
internal/*/
βββ *_test.go # Unit tests for each package
.
βββ cmd/
β βββ chat-server/ # Chat server entry point
β βββ stock-bot/ # Stock bot entry point
βββ internal/
β βββ config/ # Configuration & database setup
β βββ domain/ # Domain entities (User, Message, etc)
β βββ service/ # Business logic (Auth, Chat)
β βββ repository/postgres/ # PostgreSQL data access layer
β βββ handler/ # HTTP API handlers
β βββ websocket/ # WebSocket hub & client
β βββ middleware/ # HTTP middleware (Auth, CORS, Rate limit)
β βββ messaging/ # RabbitMQ integration & consumer
β βββ stock/ # Stock quote service (Stooq API)
β βββ observability/ # Logging & metrics (slog, Prometheus)
β βββ testutil/ # Test utilities & mocks
βββ tests/
β βββ e2e/ # End-to-end integration tests
β βββ setup_test.go # Docker infrastructure & services
β βββ auth_e2e_test.go # Authentication flow tests
β βββ chatroom_e2e_test.go # Chatroom operations tests
β βββ websocket_e2e_test.go # WebSocket communication tests
β βββ repository_e2e_test.go # Database integration tests
β βββ messaging_e2e_test.go # RabbitMQ integration tests
β βββ helpers_test.go # Test utilities & helpers
βββ migrations/ # Database migrations (SQL)
βββ static/ # Frontend assets (HTML, CSS, JS)
βββ containers/ # Docker configuration
β βββ docker-compose.yml # Multi-service orchestration
β βββ Dockerfile.chat-server # Chat server image
β βββ Dockerfile.stock-bot # Stock bot image
βββ artifacts/ # Generated files
βββ openapi.yaml # OpenAPI 3.0 specification
βββ schemas/ # API schemas
# Build both services (binary in ./bin/)
task build
# Build Docker images
task docker:build# Start all services
task docker:run
# View logs
task docker:logs
# Stop services
task docker:stop
# Stop and remove volumes
task docker:cleanE2E Tests Timeout
# Increase timeout if tests fail due to slow Docker startup
go test -tags=e2e -timeout=300s ./tests/e2eRabbitMQ Connection Failed
# Ensure RabbitMQ is running
brew services start rabbitmq
# Or check Docker container
docker ps | grep rabbitmqDatabase Migration Issues
# Check migration status
task migrate:status
# Rollback last migration if needed
task migrate:down
# Rerun migrations
task docker:migrate:upWebSocket Connection Refused
# Ensure chat server is running on port 8080
lsof -i :8080
# Or restart the service
task run:serverSwagger UI Not Loading (404 Error)
# Verify swagger-ui container is running
docker ps | grep swagger-ui
# Check if openapi.yaml is mounted correctly
docker exec jobsity-swagger-ui ls -la /api/
# View swagger-ui logs
docker logs jobsity-swagger-ui