You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

9.7 KiB

Environment Variable Precedence and API Configuration

Date: August 4, 2025
Author: Matthew Raymer

Overview

This document explains the order of precedence for environment variables in the TimeSafari project, how .env files are used, and the API configuration scheme for different environments.

Order of Precedence (Highest to Lowest)

1. Shell Script Overrides (Highest Priority)

Shell scripts can override environment variables for platform-specific needs:

# scripts/common.sh - setup_build_env()
if [ "$BUILD_MODE" = "development" ]; then
    export VITE_DEFAULT_ENDORSER_API_SERVER="http://localhost:3000"
    export VITE_DEFAULT_PARTNER_API_SERVER="http://localhost:3000"
fi

2. Platform-Specific Overrides (High Priority)

Platform-specific build scripts can override for mobile development:

# scripts/build-android.sh
if [ "$BUILD_MODE" = "development" ]; then
    export VITE_DEFAULT_ENDORSER_API_SERVER="http://10.0.2.2:3000"
    export VITE_DEFAULT_PARTNER_API_SERVER="http://10.0.2.2:3000"
fi

3. Environment-Specific .env Files (Medium Priority)

Environment-specific .env files provide environment-specific defaults:

# .env.development, .env.test, .env.production
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000

4. Fallback .env File (Low Priority)

General .env file provides project-wide defaults:

# .env (if exists)
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000

5. app.ts Constants (Lowest Priority - Fallback)

Hardcoded constants in src/constants/app.ts provide safety nets:

export const DEFAULT_ENDORSER_API_SERVER =
  import.meta.env.VITE_DEFAULT_ENDORSER_API_SERVER ||
  AppString.PROD_ENDORSER_API_SERVER;

Build Process Flow

1. Shell Scripts Set Base Values

# scripts/common.sh
setup_build_env() {
  if [ "$BUILD_MODE" = "development" ]; then
    export VITE_DEFAULT_ENDORSER_API_SERVER="http://localhost:3000"
    export VITE_DEFAULT_PARTNER_API_SERVER="http://localhost:3000"
  fi
}

2. Platform-Specific Overrides

# scripts/build-android.sh
if [ "$BUILD_MODE" = "development" ]; then
  export VITE_DEFAULT_ENDORSER_API_SERVER="http://10.0.2.2:3000"
  export VITE_DEFAULT_PARTNER_API_SERVER="http://10.0.2.2:3000"
fi

3. Load .env Files

# scripts/build-web.sh
local env_file=".env.$BUILD_MODE"  # .env.development, .env.test, .env.production
if [ -f "$env_file" ]; then
  load_env_file "$env_file"
fi

# Fallback to .env
if [ -f ".env" ]; then
  load_env_file ".env"
fi

4. Vite Processes Environment

// vite.config.common.mts
dotenv.config();  // Loads .env files

5. Application Uses Values

// src/constants/app.ts
export const DEFAULT_ENDORSER_API_SERVER =
  import.meta.env.VITE_DEFAULT_ENDORSER_API_SERVER ||
  AppString.PROD_ENDORSER_API_SERVER;

API Configuration Scheme

Environment Configuration Summary

Environment Endorser API (Claims) Partner API Image API
Development http://localhost:3000 http://localhost:3000 https://image-api.timesafari.app
Test https://test-api.endorser.ch https://test-partner-api.endorser.ch https://image-api.timesafari.app
Production https://api.endorser.ch https://partner-api.endorser.ch https://image-api.timesafari.app

Mobile Development Overrides

Android Development

  • Emulator: http://10.0.2.2:3000 (Android emulator default)
  • Physical Device: http://{CUSTOM_IP}:3000 (Custom IP for physical device)

iOS Development

  • Simulator: http://localhost:3000 (iOS simulator default)
  • Physical Device: http://{CUSTOM_IP}:3000 (Custom IP for physical device)

.env File Structure

.env.development

# ==========================================
# DEVELOPMENT ENVIRONMENT CONFIGURATION
# ==========================================
# API Server Configuration:
# - Endorser API (Claims): Local development server
# - Partner API: Local development server (aligned with claims)
# - Image API: Test server (shared for development)
# ==========================================

# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.

# iOS doesn't like spaces in the app title.
TIME_SAFARI_APP_TITLE="TimeSafari_Dev"
VITE_APP_SERVER=http://localhost:8080

# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F

# API Servers (Development - Local)
VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000
VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000

# Image API (Test server for development)
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app

# Push Server (disabled for localhost)
#VITE_DEFAULT_PUSH_SERVER... can't be set up with localhost domain

# Feature Flags
VITE_PASSKEYS_ENABLED=true

.env.test

# ==========================================
# TEST ENVIRONMENT CONFIGURATION
# ==========================================
# API Server Configuration:
# - Endorser API (Claims): Test server
# - Partner API: Test server (aligned with claims)
# - Image API: Test server
# ==========================================

# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.

# iOS doesn't like spaces in the app title.
TIME_SAFARI_APP_TITLE="TimeSafari_Test"
VITE_APP_SERVER=https://test.timesafari.app

# This is the claim ID for actions in the BVC project, with the JWT ID on this environment (not production).
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01HWE8FWHQ1YGP7GFZYYPS272F

# API Servers (Test Environment)
VITE_DEFAULT_ENDORSER_API_SERVER=https://test-api.endorser.ch
VITE_DEFAULT_PARTNER_API_SERVER=https://test-partner-api.endorser.ch

# Image API (Test server)
VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app

# Push Server (Test)
VITE_DEFAULT_PUSH_SERVER=https://test.timesafari.app

# Feature Flags
VITE_PASSKEYS_ENABLED=true

.env.production

# ==========================================
# PRODUCTION ENVIRONMENT CONFIGURATION
# ==========================================
# API Server Configuration:
# - Endorser API (Claims): Production server
# - Partner API: Production server (aligned with claims)
# - Image API: Production server
# ==========================================

# Only the variables that start with VITE_ are seen in the application import.meta.env in Vue.

# App Server
VITE_APP_SERVER=https://timesafari.app

# This is the claim ID for actions in the BVC project.
VITE_BVC_MEETUPS_PROJECT_CLAIM_ID=https://endorser.ch/entity/01GXYPFF7FA03NXKPYY142PY4H

# API Servers (Production Environment)
VITE_DEFAULT_ENDORSER_API_SERVER=https://api.endorser.ch
VITE_DEFAULT_PARTNER_API_SERVER=https://partner-api.endorser.ch

# Image API (Production server)
VITE_DEFAULT_IMAGE_API_SERVER=https://image-api.timesafari.app

# Push Server (Production)
VITE_DEFAULT_PUSH_SERVER=https://timesafari.app

Key Principles

1. API Alignment

  • Partner API values follow the same pattern as Claim API (Endorser API)
  • Both APIs use the same environment-specific endpoints
  • This ensures consistency across the application

2. Platform Flexibility

  • Shell scripts can override for platform-specific needs
  • Android emulator uses 10.0.2.2:3000
  • iOS simulator uses localhost:3000
  • Physical devices use custom IP addresses

3. Environment Isolation

  • Each environment has its own .env file
  • Test environment uses test APIs
  • Development environment uses local APIs
  • Production environment uses production APIs

4. Safety Nets

  • Hardcoded constants in app.ts provide fallbacks
  • Multiple layers of configuration prevent failures
  • Clear precedence order ensures predictable behavior

Usage Examples

Development Build

# Uses .env.development + shell script overrides
npm run build:web -- --mode development

Test Build

# Uses .env.test + shell script overrides
npm run build:web -- --mode test

Production Build

# Uses .env.production + shell script overrides
npm run build:web -- --mode production

Android Development

# Uses .env.development + Android-specific overrides
./scripts/build-android.sh --dev

iOS Development

# Uses .env.development + iOS-specific overrides
./scripts/build-ios.sh --dev

Troubleshooting

Environment Variable Debugging

# Show current environment variables
./scripts/build-web.sh --env

# Check specific variable
echo $VITE_DEFAULT_ENDORSER_API_SERVER

Common Issues

  1. Wrong API Server: Check if shell script overrides are correct
  2. Missing .env File: Ensure environment-specific .env file exists
  3. Platform-Specific Issues: Verify platform overrides in build scripts
  4. Vite Not Loading: Check if dotenv.config() is called

Validation

# Validate environment configuration
npm run test-env

Best Practices

  1. Always use environment-specific .env files for different environments
  2. Keep shell script overrides minimal and platform-specific
  3. Document API alignment in .env file headers
  4. Use hardcoded fallbacks in app.ts for safety
  5. Test all environments before deployment
  6. Validate configuration with test scripts