A comprehensive fitness tracking and advice application built with a microservices architecture.
- api-service: Main API gateway using Go + Gin (authentication, JWT, middleware, client routing)
- user-service: User registration, profile management, and user data operations (Go + stdlib http)
- meal-service: Meal planning, nutrition tracking, and meal data operations (Go + stdlib http)
- tracking-service: Daily check-ins, weight, mood, sleep, activity tracking (Go + stdlib http)
- web-client: React.js + Mantine UI library for mobile-first responsive design
- Mobile Detection:
react-device-detectfor reliable device type detection - Responsive Design: Mobile-first CSS with
100dvhviewport units and CSS safe-area insets - Progressive Web App: iOS Safari meta tags, manifest.json, and fullscreen support
- Touch Optimization: Enhanced mobile scrolling and address bar hiding for iOS Safari
- Mobile Detection:
- PostgreSQL running in Docker container
- PostHog integration for usage analytics and user behavior tracking
- API Gateway: Go 1.23 + Gin framework (authentication, middleware)
- Microservices: Go 1.23 + gRPC (internal service communication)
- Database: PostgreSQL + sqlx (direct SQL queries)
- Frontend: React.js + Mantine UI + react-device-detect for mobile-first responsive design
- Containerization: Docker + Docker Compose
- Build Images:
golang:1.24.6-alpine(Alpine-based for lightweight builds) - Runtime Images:
alpine:latest(Alpine Linux for development troubleshooting)
- Build Images:
- Fault Tolerance: failsafe-go library with circuit breaker pattern
- Communication:
- External: HTTP/REST APIs via API Gateway
- Internal: gRPC between microservices
- Documentation: Swagger/OpenAPI 3.0 with interactive UI
- Analytics: PostHog (client-side only)
📚 For detailed architecture decisions and conventions, see:
- Ground Rules - Development conventions, database schema, gRPC architecture
- Functional Specifications - Detailed feature requirements and API specs
This application implements multiple layers of security following industry best practices:
- ✅ Alpine Runtime Images: Using
alpine:latestfor development troubleshooting- Lightweight Linux distribution with package manager access
- Shell access for debugging and troubleshooting during development
- Multi-stage Docker builds for optimized image sizes
- ✅ Multi-Stage Docker Builds: Build with full toolchain, deploy with minimal runtime
- ✅ Latest Go Version: Go 1.24.6 with latest security patches and improvements
- ✅ JWT Tokens: Secure, stateless authentication with configurable expiration
- ✅ bcrypt Password Hashing: Industry-standard password encryption (cost factor 10+)
- ✅ Bearer Token Authentication: Standard HTTP Authorization header implementation
- ✅ Protected Routes: Middleware-based route protection with token validation
- ✅ Parameterized Queries: All SQL queries use parameters to prevent injection attacks
- ✅ Connection Pooling: Secure database connection management
- ✅ Environment-Based Credentials: Database credentials via environment variables
- ✅ PostgreSQL: Production-grade database with built-in security features
- ✅ Input Validation: Request payload validation using Go struct tags
- ✅ CORS Configuration: Controlled cross-origin resource sharing
- ✅ Error Handling: Sanitized error responses (no sensitive data leakage)
- ✅ Structured Logging: Secure logging without credential exposure
- ✅ Environment Variable Management: All secrets via environment variables
- ✅ Docker Network Isolation: Services communicate via isolated Docker network
- ✅ Non-Root Container Execution: All containers run as unprivileged users
- ✅ Minimal Dependencies: Reduced attack surface with essential dependencies only
- ✅ Gitignored Secrets: All
.envfiles excluded from version control - ✅ Example Templates:
.env.examplefiles with placeholder values - ✅ Secret Rotation Ready: Environment-based configuration supports easy rotation
- ✅ Development vs Production: Clear separation of development and production configs
- ✅ Rate Limiting Ready: Architecture supports rate limiting implementation
- ✅ HTTPS Ready: TLS termination at load balancer level
- ✅ API Documentation Security: Swagger UI with authentication integration
- ✅ Microservices Isolation: Each service handles specific business logic only
Production Recommendation: Use cloud-native secret management (AWS Secrets Manager, Azure Key Vault, etc.) and implement additional security headers, rate limiting, and monitoring.
- Run the setup script
./scripts/setup-dev.sh
- Update your
.envfile with your actual credentials and PostHog API key.
- Start all services
make up
- Stop all services
make down
- Check logs
make logs
- Use the base URL:
http://localhost:8080 - Ensure all services are running via
docker-compose ps
| Service | Type | Port | URL/Connection |
|---|---|---|---|
| API Gateway | HTTP/REST | 8080 | http://localhost:8080 |
| User Service | gRPC | 8082 | localhost:8082 |
| DB Gateway | gRPC | 8086 | localhost:8086 |
| Web Client | React | 5050 | http://localhost:5050 |
| PostgreSQL | Database | 5432 | postgresql://smartfit:smartfit123@localhost:5432/smartfitgirl |
| Swagger UI | Docs | 8080 | http://localhost:8080/swagger/index.html 📖 |
| Service | Port | Status |
|---|---|---|
| Meal Service | 8083 | 🚧 Not Implemented |
| Check-in Service | 8084 | 🚧 Not Implemented |
| Survey Service | 8085 | 🚧 Not Implemented |
| Notification Service | 8087 | 🚧 Future |
| Analytics Service | 8088 | 🚧 Future |
📋 See Ground Rules for detailed service architecture and communication flow.
# Generate all proto files from project root
make proto-gen# Prerequisites (one-time setup)
brew install protobuf # macOS
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# Generate for specific service
cd services/[service-name]
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
proto/*.proto- Service logs:
docker-compose logs -f [service-name] - Documentation:
- Ground Rules - Conventions and architecture
- Functional Specs - Feature requirements
- Testing Guide - API testing procedures
Before running the application, you must configure your environment variables:
-
Run the setup script (creates
.envfiles from templates):./scripts/setup-dev.sh
-
Update the main
.envfile with your values:# Database Configuration DB_HOST=localhost DB_PORT=5432 DB_NAME=smartfitgirl DB_USER=smartfit DB_PASSWORD=your-secure-password # JWT Configuration JWT_SECRET=your-super-secret-jwt-key # Service Addresses (Docker networking) USER_SERVICE_ADDR=user-service:8082 DB_GATEWAY_ADDR=db-gateway-service:8086 # Service Ports (customizable) API_SERVICE_HOST_PORT=8080 USER_SERVICE_HOST_PORT=8082 DB_GATEWAY_SERVICE_HOST_PORT=8086 WEB_CLIENT_HOST_PORT=5050 # SendGrid Email Service (for password reset) SENDGRID_API_KEY=your-sendgrid-api-key # PostHog Analytics (React client) REACT_APP_POSTHOG_KEY=your-posthog-api-key REACT_APP_POSTHOG_HOST=https://app.posthog.com
.env- Main environment file (gitignored).env.example- Template with placeholder valuesservices/*//.env.example- Service-specific templates
The application uses SendGrid for sending password reset emails. To configure:
-
Create a SendGrid account at sendgrid.com
-
Generate an API Key:
- Go to Settings → API Keys in your SendGrid dashboard
- Click "Create API Key"
- Choose "Restricted Access" for security
- Grant the following permissions:
- Mail Send: Full Access
- Copy the generated API key
-
Update your
.envfile:SENDGRID_API_KEY=SG.your-actual-api-key-here
-
Verify Sender Identity (Required for production):
- Go to Settings → Sender Authentication
- Either verify a single sender email or authenticate your domain
- For development, you can use the single sender verification
-
Update Email Templates (Optional):
- The current implementation uses basic HTML templates
- You can customize the email content in
services/user-service/handlers.go - For production, consider using SendGrid's Dynamic Templates
Testing Password Reset:
# Request password reset
curl -X POST http://localhost:8082/auth/forgot-password \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]"}'
# Reset password with token (check your email for the token)
curl -X POST http://localhost:8082/auth/reset-password \
-H "Content-Type: application/json" \
-d '{
"token":"your-reset-token-from-email",
"newPassword":"newpassword123"
}'- ✅ Environment files are gitignored for security
- ✅ Never commit actual credentials to version control
- ✅ Use cloud secrets management in production
- ✅ PostHog is only configured client-side for simplicity
- ✅ SendGrid API keys should be rotated regularly
- ✅ Password reset tokens expire after 1 hour for security
We follow an API-first approach where APIs are designed and tested before building UI components.
The API service includes comprehensive Swagger documentation with interactive testing:
- Swagger UI:
http://localhost:8080/swagger/index.html - OpenAPI Spec:
http://localhost:8080/swagger/doc.json - Features:
- Interactive endpoint testing
- JWT Bearer token authentication
- Request/response examples
- OpenAPI 3.0 specification
Quick Test with Swagger:
- Start services:
make up - Open Swagger UI:
http://localhost:8080/swagger/index.html - Test
/auth/loginto get JWT token - Click "Authorize" and enter
Bearer <your-token> - Test protected endpoints
- Collections are stored in
/api-tests/collections/ - Environment files in
/api-tests/environments/ - Test data in
/api-tests/data/
- Start backend services:
make up - Import Postman collections from
api-tests/collections/ - Configure Postman environment with:
{ "api_base_url": "http://localhost:8080", "user_service_url": "http://localhost:8082", "meal_service_url": "http://localhost:8083", "tracking_service_url": "http://localhost:8084" } - Test each endpoint thoroughly
- Document any issues or required changes
- Once API is stable, implement corresponding React UI components
You can also test individual services directly:
- User Service:
http://localhost:8082/users/health - Meal Service:
http://localhost:8083/meals/health - Tracking Service:
http://localhost:8084/tracking/health
🏗️ See Ground Rules for the complete service architecture diagram and communication patterns.
- 8080: Reserved for API Gateway (never use for internal services)
- 8082-8089: gRPC microservices
- 5000-5999: Web applications
- 5432: PostgreSQL database
| Port | Service | Status |
|---|---|---|
| 8080 | API Gateway | ✅ Active |
| 8082 | User Service | ✅ Active |
| 8083 | Meal Service | 🚧 Planned |
| 8084 | Check-in Service | 🚧 Planned |
| 8085 | Survey Service | 🚧 Planned |
| 8086 | DB Gateway | ✅ Active |
| 8087 | Notification Service | 🚧 Future |
| 8088 | Analytics Service | 🚧 Future |
| 5050 | Web Client | ✅ Active |
| 5432 | PostgreSQL | ✅ Active |
- Start services:
make upordocker-compose up -d - View logs:
make logsordocker-compose logs -f [service-name] - Stop services:
make downordocker-compose down - Rebuild after code changes:
docker-compose build [service-name]
During development, you can test services directly:
curl http://localhost:8080/health # API Service (HTTP)
curl http://localhost:8082/health # User Service (gRPC - if HTTP health endpoint enabled)
# Note: gRPC services may not have HTTP health endpoints by default# Get all users
curl http://localhost:8082/users
# Create a user with full profile
curl -X POST http://localhost:8082/users \
-H "Content-Type: application/json" \
-d '{
"fullName": "Jane Smith",
"email": "[email protected]",
"password": "password123",
"phoneNumber": "+1234567890",
"city": "New York",
"stateProvince": "NY",
"postalCode": "10001",
"countryCode": "US",
"locale": "en-US",
"timezone": "America/New_York",
"utcOffset": -5
}'
# Get user by ID
curl http://localhost:8082/users/1
# Update user (partial update)
curl -X PUT http://localhost:8082/users/1 \
-H "Content-Type: application/json" \
-d '{
"city": "San Francisco",
"stateProvince": "CA",
"postalCode": "94105",
"timezone": "America/Los_Angeles",
"utcOffset": -8
}'
# Upsert user (create or update by email)
curl -X POST http://localhost:8082/users/upsert \
-H "Content-Type: application/json" \
-d '{
"fullName": "John Doe Updated",
"email": "[email protected]",
"password": "newpassword123",
"city": "Chicago",
"locale": "es-US"
}'
# Verify user credentials
curl -X POST http://localhost:8082/users/verify \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"password123"}'
# Get all available goals (grouped by category)
curl http://localhost:8082/goals
# Create a fitness survey for user (includes goals selection)
curl -X POST http://localhost:8082/users/1/survey \
-H "Content-Type: application/json" \
-d '{
"currentWeight": 165.5,
"targetWeight": 150.0,
"activityLevel": 4,
"goalIds": [1, 5, 7, 9]
}'
# Get user's latest survey with goals
curl http://localhost:8082/users/1/survey/latest
# Test user Sophia Woytowitz (from seed data)
curl -X POST http://localhost:8082/users/1/survey \
-H "Content-Type: application/json" \
-d '{
"currentWeight": 165.5,
"targetWeight": 150.0,
"activityLevel": 4,
"goalIds": [1, 5, 7, 9]
}'
# Delete user
curl -X DELETE http://localhost:8082/users/1# Login (get JWT token)
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"password123"}'
# Example response:
# {
# "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
# "user": {
# "id": 1,
# "fullName": "Jane Smith",
# "email": "[email protected]",
# "locale": "en-US",
# "timezone": "America/New_York"
# }
# }
# Use JWT token for protected endpoints
export JWT_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
curl -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/users/profile💡 Tip: Use the interactive Swagger UI for easier API testing with built-in authentication!
# Get all meals
curl http://localhost:8083/meals
# Create a meal plan
curl -X POST http://localhost:8083/meals \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JWT_TOKEN" \
-d '{
"name": "Healthy Breakfast",
"calories": 350,
"protein": 20,
"carbs": 45,
"fat": 12
}'# Daily check-in
curl -X POST http://localhost:8084/tracking/checkin \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JWT_TOKEN" \
-d '{
"weight": 150.5,
"mood": 8,
"sleep_hours": 7.5,
"energy_level": 7
}'
# Get tracking history
curl -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8084/tracking/history?days=30# Connect to PostgreSQL (password: smartfit123)
psql -h localhost -p 5432 -U smartfit -d smartfitgirl
# View users table
SELECT * FROM USERS;
# Create password reset table (if not already created)
\i services/user-service/password_resets_table.sql
# View password reset tokens
SELECT * FROM PASSWORD_RESETS;- API Service: Acts as gateway, handles authentication, routes requests
- Microservices: Handle specific business logic (users, meals, tracking)
- Internal Communication: Services communicate via Docker network using service names
- External Access: Use localhost ports for development/testing
- Database: Shared PostgreSQL instance across all services
- Container Security:
- Multi-stage builds with Alpine for lightweight builds
- Alpine runtime images for development troubleshooting
- Multi-stage builds for optimized production images
- Shell access available for debugging during development
- Authentication: JWT tokens with bcrypt password hashing
- International Support: User profiles include
locale,postal_code,timezone,utc_offset - Security:
- Parameterized SQL queries prevent injection attacks
- Alpine container images for development troubleshooting
- Multi-stage builds for optimized production images
- JWT-based authentication with secure token handling
- CRUD Operations: Complete user management with upsert functionality
- Service Discovery: Docker Compose networking for inter-service communication
- API Documentation: Interactive Swagger UI with OpenAPI 3.0 specification
See individual service READMEs for specific development instructions:
- Set up monorepo structure
- Configure Docker and Docker Compose
- Implement basic Web API with health checks
- Set up PostgreSQL with initial schema
- Create basic Data Service with database connection
- Configure failsafe-go for service communication
- User registration and authentication
- User profile management
- Settings and preferences system (system + personal fitness goals)
- Basic security implementation
- PostHog integration for user analytics
- Daily check-in functionality (weight, mood, sleep)
- Data storage and retrieval
- Basic web client with check-in forms
- Track user engagement with PostHog
- Meal planning service
- Weekly meal plan management
- Meal planning UI components
- Analytics on meal planning usage
- Evening check-ins (steps, activities TBD)
- Data visualization (charts and graphs for historical data)
- PostHog dashboards for app usage analytics
- UI/UX improvements based on analytics insights
- Comprehensive testing across all services
- Performance optimization
- Bug fixes and final polish
- Deployment preparation