Files
maternal-app/docs/maternal-app-env-config.md
andupetcu 98e01ebe80 Phase 1 & 2: Authentication and Children Management
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
2025-09-30 18:40:10 +03:00

10 KiB

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

# 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

# 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

# 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

# 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

# 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

# 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

# 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)

# 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)

# 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

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)

# Never commit this file
# Copy from .env.example and fill with real values
cp .env.example .env.local

Production Secrets (AWS Secrets Manager)

# 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

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)

# 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)

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

<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

API_BASE_URL=http://10.0.2.2:3000/api/v1
ENABLE_VOICE_INPUT=true
ENABLE_PROGUARD=false

Configuration Loading Order

Backend (Node.js)

// 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)

// 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

// 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

# .gitignore
.env
.env.*
!.env.example
secrets/
*.key
*.pem
*.p12

Deployment Configuration

Heroku

// app.json
{
  "env": {
    "NODE_ENV": {
      "value": "production"
    },
    "DATABASE_URL": {
      "required": true
    },
    "JWT_SECRET": {
      "generator": "secret"
    }
  }
}

Docker Build Args

ARG NODE_ENV=production
ARG API_VERSION=v1

ENV NODE_ENV=${NODE_ENV}
ENV API_VERSION=${API_VERSION}

CI/CD Variables (GitHub Actions)

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

# Development debugging
DEBUG=maternal:*
LOG_LEVEL=debug
PRETTY_LOGS=true

# Production
LOG_LEVEL=info
LOG_FORMAT=json

Health Check Variables

HEALTH_CHECK_INTERVAL=30000
HEALTH_CHECK_TIMEOUT=3000
HEALTH_CHECK_PATH=/health

Quick Start Commands

Local Development Setup

# 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

# 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