Completed Features:
- Full JWT authentication system with refresh tokens
- User registration and login with device fingerprinting
- Child profile CRUD operations with permission-based access
- Family management with roles and permissions
- Database migrations for core auth and family structure
- Comprehensive test coverage (37 unit + E2E tests)
Tech Stack:
- NestJS backend with TypeORM
- PostgreSQL database
- JWT authentication with Passport
- bcrypt password hashing
- Docker Compose for infrastructure
🤖 Generated with Claude Code
507 lines
10 KiB
Markdown
507 lines
10 KiB
Markdown
# Environment Configuration Guide - Maternal Organization App
|
|
|
|
## Environment Structure
|
|
|
|
### Environment Types
|
|
- **Development** (`dev`): Local development with hot reload
|
|
- **Staging** (`staging`): Pre-production testing environment
|
|
- **Production** (`prod`): Live application environment
|
|
- **Testing** (`test`): Automated testing environment
|
|
|
|
---
|
|
|
|
## Backend Environment Variables (.env)
|
|
|
|
### Core Configuration
|
|
```bash
|
|
# Application
|
|
NODE_ENV=development
|
|
APP_NAME=MaternalApp
|
|
APP_VERSION=1.0.0
|
|
API_VERSION=v1
|
|
PORT=3000
|
|
HOST=localhost
|
|
|
|
# URLs
|
|
BACKEND_URL=http://localhost:3000
|
|
FRONTEND_URL=http://localhost:8081
|
|
WEBSOCKET_URL=ws://localhost:3000
|
|
```
|
|
|
|
### Database Configuration
|
|
```bash
|
|
# PostgreSQL Primary
|
|
DATABASE_URL=postgresql://user:password@localhost:5432/maternal_app
|
|
DB_HOST=localhost
|
|
DB_PORT=5432
|
|
DB_NAME=maternal_app
|
|
DB_USER=maternal_user
|
|
DB_PASSWORD=secure_password_here
|
|
DB_SSL=false
|
|
DB_POOL_MIN=2
|
|
DB_POOL_MAX=10
|
|
|
|
# MongoDB (AI Chat History)
|
|
MONGODB_URI=mongodb://localhost:27017/maternal_ai
|
|
MONGODB_DB=maternal_ai
|
|
|
|
# Redis
|
|
REDIS_URL=redis://localhost:6379
|
|
REDIS_PASSWORD=
|
|
REDIS_DB=0
|
|
REDIS_CACHE_TTL=3600
|
|
```
|
|
|
|
### Authentication & Security
|
|
```bash
|
|
# JWT Configuration
|
|
JWT_SECRET=your-256-bit-secret-key-here
|
|
JWT_REFRESH_SECRET=different-256-bit-secret-key-here
|
|
JWT_EXPIRES_IN=1h
|
|
JWT_REFRESH_EXPIRES_IN=30d
|
|
|
|
# Encryption
|
|
ENCRYPTION_KEY=32-character-encryption-key-here
|
|
ENCRYPTION_IV=16-character-iv-here
|
|
|
|
# Device Fingerprinting
|
|
FINGERPRINT_SECRET=device-fingerprint-secret-key
|
|
|
|
# Rate Limiting
|
|
RATE_LIMIT_WINDOW_MS=60000
|
|
RATE_LIMIT_MAX_REQUESTS=100
|
|
```
|
|
|
|
### AI Services
|
|
```bash
|
|
# OpenAI
|
|
OPENAI_API_KEY=sk-your-openai-api-key
|
|
OPENAI_MODEL=gpt-4
|
|
OPENAI_TEMPERATURE=0.7
|
|
OPENAI_MAX_TOKENS=1000
|
|
|
|
# Anthropic Claude (Alternative)
|
|
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key
|
|
ANTHROPIC_MODEL=claude-3-opus-20240229
|
|
|
|
# Whisper (Voice Recognition)
|
|
WHISPER_API_KEY=your-whisper-api-key
|
|
WHISPER_MODEL=whisper-1
|
|
|
|
# LangChain
|
|
LANGCHAIN_TRACING_V2=true
|
|
LANGCHAIN_API_KEY=your-langchain-api-key
|
|
LANGCHAIN_PROJECT=maternal-app
|
|
```
|
|
|
|
### External Services
|
|
```bash
|
|
# Email Service (SendGrid)
|
|
SENDGRID_API_KEY=SG.your-sendgrid-api-key
|
|
SENDGRID_FROM_EMAIL=support@maternalapp.com
|
|
SENDGRID_FROM_NAME=Maternal App
|
|
|
|
# Push Notifications
|
|
FCM_SERVER_KEY=your-firebase-server-key
|
|
FCM_PROJECT_ID=maternal-app-prod
|
|
APNS_KEY_ID=your-apple-key-id
|
|
APNS_TEAM_ID=your-apple-team-id
|
|
|
|
# File Storage (MinIO/S3)
|
|
S3_ENDPOINT=http://localhost:9000
|
|
S3_ACCESS_KEY=minioadmin
|
|
S3_SECRET_KEY=minioadmin
|
|
S3_BUCKET=maternal-uploads
|
|
S3_REGION=us-east-1
|
|
S3_USE_SSL=false
|
|
|
|
# Monitoring
|
|
SENTRY_DSN=https://your-sentry-dsn@sentry.io/project-id
|
|
SENTRY_ENVIRONMENT=development
|
|
SENTRY_TRACES_SAMPLE_RATE=0.1
|
|
```
|
|
|
|
### Compliance & Analytics
|
|
```bash
|
|
# COPPA/GDPR
|
|
COPPA_VERIFICATION_REQUIRED=true
|
|
GDPR_ENABLED=true
|
|
DATA_RETENTION_DAYS=365
|
|
AUDIT_LOG_ENABLED=true
|
|
|
|
# Analytics
|
|
MIXPANEL_TOKEN=your-mixpanel-token
|
|
GA_TRACKING_ID=G-XXXXXXXXXX
|
|
POSTHOG_API_KEY=your-posthog-key
|
|
POSTHOG_HOST=https://app.posthog.com
|
|
```
|
|
|
|
---
|
|
|
|
## Frontend Environment Variables (.env)
|
|
|
|
### React Native Configuration
|
|
```bash
|
|
# API Configuration
|
|
REACT_APP_API_BASE_URL=http://localhost:3000/api/v1
|
|
REACT_APP_GRAPHQL_URL=http://localhost:3000/graphql
|
|
REACT_APP_WS_URL=ws://localhost:3000/ws
|
|
|
|
# Feature Flags
|
|
REACT_APP_ENABLE_VOICE=true
|
|
REACT_APP_ENABLE_AI_CHAT=true
|
|
REACT_APP_ENABLE_DARK_MODE=true
|
|
REACT_APP_ENABLE_OFFLINE=true
|
|
REACT_APP_MAX_CHILDREN_FREE=2
|
|
REACT_APP_AI_QUERIES_FREE=10
|
|
|
|
# App Configuration
|
|
REACT_APP_NAME=Maternal
|
|
REACT_APP_VERSION=1.0.0
|
|
REACT_APP_BUILD_NUMBER=1
|
|
REACT_APP_BUNDLE_ID=com.maternalapp.app
|
|
```
|
|
|
|
### Platform-Specific (iOS)
|
|
```bash
|
|
# iOS Configuration
|
|
IOS_APP_ID=1234567890
|
|
IOS_TEAM_ID=XXXXXXXXXX
|
|
IOS_PROVISIONING_PROFILE=maternal-app-dev
|
|
APPLE_SIGN_IN_SERVICE_ID=com.maternalapp.signin
|
|
```
|
|
|
|
### Platform-Specific (Android)
|
|
```bash
|
|
# Android Configuration
|
|
ANDROID_PACKAGE_NAME=com.maternalapp.app
|
|
ANDROID_KEYSTORE_PATH=./android/app/maternal.keystore
|
|
ANDROID_KEY_ALIAS=maternal-key
|
|
ANDROID_KEYSTORE_PASSWORD=keystore-password
|
|
ANDROID_KEY_PASSWORD=key-password
|
|
```
|
|
|
|
---
|
|
|
|
## Docker Environment Configuration
|
|
|
|
### docker-compose.yml
|
|
```yaml
|
|
version: '3.8'
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
environment:
|
|
POSTGRES_DB: ${DB_NAME}
|
|
POSTGRES_USER: ${DB_USER}
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
ports:
|
|
- "5432:5432"
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
command: redis-server --requirepass ${REDIS_PASSWORD}
|
|
ports:
|
|
- "6379:6379"
|
|
|
|
mongodb:
|
|
image: mongo:6
|
|
environment:
|
|
MONGO_INITDB_DATABASE: maternal_ai
|
|
volumes:
|
|
- mongo_data:/data/db
|
|
ports:
|
|
- "27017:27017"
|
|
|
|
minio:
|
|
image: minio/minio
|
|
command: server /data --console-address ":9001"
|
|
environment:
|
|
MINIO_ROOT_USER: ${S3_ACCESS_KEY}
|
|
MINIO_ROOT_PASSWORD: ${S3_SECRET_KEY}
|
|
volumes:
|
|
- minio_data:/data
|
|
ports:
|
|
- "9000:9000"
|
|
- "9001:9001"
|
|
|
|
volumes:
|
|
postgres_data:
|
|
mongo_data:
|
|
minio_data:
|
|
```
|
|
|
|
---
|
|
|
|
## Secret Management
|
|
|
|
### Development Secrets (.env.local)
|
|
```bash
|
|
# Never commit this file
|
|
# Copy from .env.example and fill with real values
|
|
cp .env.example .env.local
|
|
```
|
|
|
|
### Production Secrets (AWS Secrets Manager)
|
|
```bash
|
|
# Store production secrets in AWS Secrets Manager
|
|
aws secretsmanager create-secret \
|
|
--name maternal-app/production \
|
|
--secret-string file://secrets.json
|
|
|
|
# Retrieve secrets in application
|
|
aws secretsmanager get-secret-value \
|
|
--secret-id maternal-app/production
|
|
```
|
|
|
|
### Kubernetes Secrets
|
|
```yaml
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: maternal-app-secrets
|
|
type: Opaque
|
|
data:
|
|
jwt-secret: <base64-encoded-secret>
|
|
database-url: <base64-encoded-url>
|
|
openai-api-key: <base64-encoded-key>
|
|
```
|
|
|
|
---
|
|
|
|
## Environment File Templates
|
|
|
|
### .env.example (Commit to repo)
|
|
```bash
|
|
# Copy this file to .env.local and fill in values
|
|
NODE_ENV=development
|
|
PORT=3000
|
|
|
|
# Database
|
|
DATABASE_URL=postgresql://user:password@localhost:5432/maternal_app
|
|
|
|
# Add all variables with placeholder values...
|
|
JWT_SECRET=change-this-to-random-256-bit-key
|
|
OPENAI_API_KEY=sk-your-api-key-here
|
|
```
|
|
|
|
### .env.test (Testing)
|
|
```bash
|
|
NODE_ENV=test
|
|
DATABASE_URL=postgresql://test:test@localhost:5432/maternal_test
|
|
REDIS_URL=redis://localhost:6380
|
|
JWT_SECRET=test-jwt-secret-not-for-production
|
|
```
|
|
|
|
---
|
|
|
|
## Platform-Specific Configuration
|
|
|
|
### iOS Info.plist Additions
|
|
```xml
|
|
<key>API_BASE_URL</key>
|
|
<string>$(API_BASE_URL)</string>
|
|
|
|
<key>NSMicrophoneUsageDescription</key>
|
|
<string>Voice input for hands-free logging</string>
|
|
|
|
<key>NSCameraUsageDescription</key>
|
|
<string>Take photos of your child</string>
|
|
```
|
|
|
|
### Android gradle.properties
|
|
```properties
|
|
API_BASE_URL=http://10.0.2.2:3000/api/v1
|
|
ENABLE_VOICE_INPUT=true
|
|
ENABLE_PROGUARD=false
|
|
```
|
|
|
|
---
|
|
|
|
## Configuration Loading Order
|
|
|
|
### Backend (Node.js)
|
|
```javascript
|
|
// config/index.ts
|
|
import dotenv from 'dotenv';
|
|
|
|
// Load in order of precedence
|
|
dotenv.config({ path: '.env.local' }); // Local overrides
|
|
dotenv.config({ path: `.env.${NODE_ENV}` }); // Environment specific
|
|
dotenv.config(); // Default values
|
|
|
|
export const config = {
|
|
app: {
|
|
name: process.env.APP_NAME || 'MaternalApp',
|
|
version: process.env.APP_VERSION || '1.0.0',
|
|
env: process.env.NODE_ENV || 'development',
|
|
},
|
|
// ... rest of config
|
|
};
|
|
```
|
|
|
|
### Frontend (React Native)
|
|
```javascript
|
|
// config/env.js
|
|
import Config from 'react-native-config';
|
|
|
|
export const ENV = {
|
|
dev: {
|
|
API_URL: 'http://localhost:3000/api/v1',
|
|
WS_URL: 'ws://localhost:3000/ws',
|
|
},
|
|
staging: {
|
|
API_URL: 'https://staging-api.maternalapp.com/api/v1',
|
|
WS_URL: 'wss://staging-api.maternalapp.com/ws',
|
|
},
|
|
prod: {
|
|
API_URL: 'https://api.maternalapp.com/api/v1',
|
|
WS_URL: 'wss://api.maternalapp.com/ws',
|
|
},
|
|
}[Config.ENV || 'dev'];
|
|
```
|
|
|
|
---
|
|
|
|
## Security Best Practices
|
|
|
|
### Secret Rotation Schedule
|
|
- **JWT Secrets**: Every 90 days
|
|
- **API Keys**: Every 180 days
|
|
- **Database Passwords**: Every 60 days
|
|
- **Encryption Keys**: Every year
|
|
|
|
### Environment Variable Validation
|
|
```typescript
|
|
// validateEnv.ts
|
|
import { cleanEnv, str, port, url, bool, num } from 'envalid';
|
|
|
|
export const env = cleanEnv(process.env, {
|
|
NODE_ENV: str({ choices: ['development', 'test', 'staging', 'production'] }),
|
|
PORT: port(),
|
|
DATABASE_URL: url(),
|
|
JWT_SECRET: str({ minLength: 32 }),
|
|
OPENAI_API_KEY: str(),
|
|
RATE_LIMIT_MAX_REQUESTS: num({ default: 100 }),
|
|
});
|
|
```
|
|
|
|
### Git Security
|
|
```bash
|
|
# .gitignore
|
|
.env
|
|
.env.*
|
|
!.env.example
|
|
secrets/
|
|
*.key
|
|
*.pem
|
|
*.p12
|
|
```
|
|
|
|
---
|
|
|
|
## Deployment Configuration
|
|
|
|
### Heroku
|
|
```json
|
|
// app.json
|
|
{
|
|
"env": {
|
|
"NODE_ENV": {
|
|
"value": "production"
|
|
},
|
|
"DATABASE_URL": {
|
|
"required": true
|
|
},
|
|
"JWT_SECRET": {
|
|
"generator": "secret"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Docker Build Args
|
|
```dockerfile
|
|
ARG NODE_ENV=production
|
|
ARG API_VERSION=v1
|
|
|
|
ENV NODE_ENV=${NODE_ENV}
|
|
ENV API_VERSION=${API_VERSION}
|
|
```
|
|
|
|
### CI/CD Variables (GitHub Actions)
|
|
```yaml
|
|
env:
|
|
NODE_ENV: production
|
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
|
JWT_SECRET: ${{ secrets.JWT_SECRET }}
|
|
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
```
|
|
|
|
---
|
|
|
|
## Monitoring & Debugging
|
|
|
|
### Debug Configuration
|
|
```bash
|
|
# Development debugging
|
|
DEBUG=maternal:*
|
|
LOG_LEVEL=debug
|
|
PRETTY_LOGS=true
|
|
|
|
# Production
|
|
LOG_LEVEL=info
|
|
LOG_FORMAT=json
|
|
```
|
|
|
|
### Health Check Variables
|
|
```bash
|
|
HEALTH_CHECK_INTERVAL=30000
|
|
HEALTH_CHECK_TIMEOUT=3000
|
|
HEALTH_CHECK_PATH=/health
|
|
```
|
|
|
|
---
|
|
|
|
## Quick Start Commands
|
|
|
|
### Local Development Setup
|
|
```bash
|
|
# 1. Copy environment template
|
|
cp .env.example .env.local
|
|
|
|
# 2. Start Docker services
|
|
docker-compose up -d
|
|
|
|
# 3. Run migrations
|
|
npm run migrate:up
|
|
|
|
# 4. Seed development data
|
|
npm run seed:dev
|
|
|
|
# 5. Start development server
|
|
npm run dev
|
|
```
|
|
|
|
### Environment Verification
|
|
```bash
|
|
# Check all required variables are set
|
|
npm run env:validate
|
|
|
|
# Display current configuration (masked)
|
|
npm run env:debug
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
1. **Missing API Keys**: Ensure all AI service keys are valid
|
|
2. **Database Connection**: Check DATABASE_URL format and credentials
|
|
3. **Redis Connection**: Verify Redis is running and accessible
|
|
4. **CORS Issues**: Confirm FRONTEND_URL is correctly set
|
|
5. **WebSocket Failures**: Check WS_URL matches backend configuration |