From 9b2ce832292667c1204e31c18417cd353e9b06f2 Mon Sep 17 00:00:00 2001 From: barsa Date: Thu, 25 Dec 2025 18:17:40 +0900 Subject: [PATCH] Refactor Environment Configuration and Update Script for BFF - Updated app.config.ts to use process.cwd() for resolving environment file paths, improving compatibility with pnpm. - Replaced ensure_env function with check_app_env in manage.sh to verify the existence of required environment files for BFF and optional files for Portal, enhancing error handling and user guidance. --- apps/bff/.env.example | 79 ++++++++++++++++++++++++++ apps/bff/src/core/config/app.config.ts | 13 +++-- apps/portal/.env.example | 40 +++++++++++++ scripts/dev/manage.sh | 42 +++++++++----- 4 files changed, 154 insertions(+), 20 deletions(-) create mode 100644 apps/bff/.env.example create mode 100644 apps/portal/.env.example diff --git a/apps/bff/.env.example b/apps/bff/.env.example new file mode 100644 index 00000000..72f3b6ae --- /dev/null +++ b/apps/bff/.env.example @@ -0,0 +1,79 @@ +# ============================================================================= +# Customer Portal BFF - Development Environment +# ============================================================================= +# Copy this file to .env in apps/bff/: +# cp .env.example .env +# +# For environment-specific overrides, use: +# .env.development - development defaults +# .env.development.local - local dev overrides (gitignored) +# .env.local - local overrides for any environment (gitignored) +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Database (Required) +# ----------------------------------------------------------------------------- +DATABASE_URL=postgresql://dev:dev@localhost:5432/portal_dev?schema=public + +# ----------------------------------------------------------------------------- +# Security (Required) +# ----------------------------------------------------------------------------- +# Generate with: openssl rand -base64 32 +JWT_SECRET=dev-secret-change-in-production-min-32-chars + +# ----------------------------------------------------------------------------- +# Redis +# ----------------------------------------------------------------------------- +REDIS_URL=redis://localhost:6379 + +# ----------------------------------------------------------------------------- +# Server +# ----------------------------------------------------------------------------- +BFF_PORT=4000 +APP_BASE_URL=http://localhost:3000 + +# ----------------------------------------------------------------------------- +# CORS +# ----------------------------------------------------------------------------- +CORS_ORIGIN=http://localhost:3000 + +# ----------------------------------------------------------------------------- +# Logging +# ----------------------------------------------------------------------------- +LOG_LEVEL=debug +PRETTY_LOGS=true + +# ----------------------------------------------------------------------------- +# Rate Limiting (relaxed for development) +# ----------------------------------------------------------------------------- +RATE_LIMIT_LIMIT=1000 +AUTH_RATE_LIMIT_LIMIT=10 + +# ----------------------------------------------------------------------------- +# Dev Bypasses (NEVER enable in production!) +# ----------------------------------------------------------------------------- +# DISABLE_CSRF=true +# DISABLE_RATE_LIMIT=true + +# ----------------------------------------------------------------------------- +# External Services (Optional - configure when testing integrations) +# ----------------------------------------------------------------------------- + +# --- WHMCS (Billing) --- +# WHMCS_BASE_URL= +# WHMCS_API_IDENTIFIER= +# WHMCS_API_SECRET= + +# --- Salesforce (CRM) --- +# SF_LOGIN_URL= +# SF_CLIENT_ID= +# SF_USERNAME= +# SF_PRIVATE_KEY_PATH=./secrets/sf-private.key + +# --- Freebit (SIM Management) --- +# FREEBIT_BASE_URL= +# FREEBIT_OEM_KEY= + +# --- SendGrid (Email) --- +# SENDGRID_API_KEY= +# EMAIL_FROM=no-reply@example.com diff --git a/apps/bff/src/core/config/app.config.ts b/apps/bff/src/core/config/app.config.ts index bbd571a3..9b887352 100644 --- a/apps/bff/src/core/config/app.config.ts +++ b/apps/bff/src/core/config/app.config.ts @@ -4,21 +4,22 @@ import { validate } from "./env.validation.js"; const nodeEnv = process.env.NODE_ENV || "development"; +// pnpm sets cwd to the package directory (apps/bff) when running scripts +const bffRoot = process.cwd(); + // Load env files in order of priority (first found wins) // 1. .env.{NODE_ENV}.local - local overrides for specific environment // 2. .env.local - local overrides (not committed) // 3. .env.{NODE_ENV} - environment-specific // 4. .env - default -// Also check monorepo root as fallback export const appConfig: ConfigModuleOptions = { isGlobal: true, expandVariables: true, validate, envFilePath: [ - resolve(process.cwd(), `.env.${nodeEnv}.local`), - resolve(process.cwd(), ".env.local"), - resolve(process.cwd(), `.env.${nodeEnv}`), - resolve(process.cwd(), ".env"), - resolve(process.cwd(), "../../.env"), // Monorepo root fallback + resolve(bffRoot, `.env.${nodeEnv}.local`), + resolve(bffRoot, ".env.local"), + resolve(bffRoot, `.env.${nodeEnv}`), + resolve(bffRoot, ".env"), ], }; diff --git a/apps/portal/.env.example b/apps/portal/.env.example new file mode 100644 index 00000000..de987a58 --- /dev/null +++ b/apps/portal/.env.example @@ -0,0 +1,40 @@ +# ============================================================================= +# Customer Portal Frontend - Development Environment +# ============================================================================= +# Copy this file to .env.local in apps/portal/: +# cp .env.example .env.local +# +# Note: NEXT_PUBLIC_* variables are exposed to the browser. +# In development, Next.js rewrites /api/* to the BFF, so you typically +# don't need to set NEXT_PUBLIC_API_BASE. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# Application Identity +# ----------------------------------------------------------------------------- +NEXT_PUBLIC_APP_NAME=Customer Portal (Dev) +NEXT_PUBLIC_APP_VERSION=1.0.0-dev + +# ----------------------------------------------------------------------------- +# API Configuration +# ----------------------------------------------------------------------------- +# In development: Leave empty or unset - Next.js rewrites /api/* to BFF +# In production: Set to /api (nginx proxies to BFF) or full BFF URL +# NEXT_PUBLIC_API_BASE= + +# BFF URL for Next.js rewrites (server-side only, not exposed to browser) +BFF_URL=http://localhost:4000 + +# ----------------------------------------------------------------------------- +# Development Tools +# ----------------------------------------------------------------------------- +NEXT_PUBLIC_ENABLE_DEVTOOLS=true + +# ----------------------------------------------------------------------------- +# Salesforce Embedded Service (Optional - for Agentforce widget) +# ----------------------------------------------------------------------------- +# NEXT_PUBLIC_SF_EMBEDDED_SERVICE_URL= +# NEXT_PUBLIC_SF_ORG_ID= +# NEXT_PUBLIC_SF_EMBEDDED_SERVICE_DEPLOYMENT_ID= +# NEXT_PUBLIC_SF_EMBEDDED_SERVICE_SITE_URL= +# NEXT_PUBLIC_SF_EMBEDDED_SERVICE_SCRT2_URL= diff --git a/scripts/dev/manage.sh b/scripts/dev/manage.sh index 9bf3ad4f..a6d39fc1 100755 --- a/scripts/dev/manage.sh +++ b/scripts/dev/manage.sh @@ -109,20 +109,29 @@ preflight() { ######################################## # Env handling ######################################## -ensure_env() { - if [ ! -f "$ENV_FILE" ]; then - warn "Environment file not found at $ENV_FILE" - if [ -f "$ENV_EXAMPLE_FILE" ]; then - log "Creating .env from example..." - cp "$ENV_EXAMPLE_FILE" "$ENV_FILE" - warn "Please edit $ENV_FILE with your actual values." - else - warn "No .env.example found at $ENV_EXAMPLE_FILE. Creating empty .env..." - : > "$ENV_FILE" - fi + +# Check that per-app env files exist +check_app_env() { + local missing=0 + + if [ ! -f "$PROJECT_ROOT/apps/bff/.env" ] && [ ! -f "$PROJECT_ROOT/apps/bff/.env.development" ]; then + warn "BFF env file not found. Create one with:" + warn " cp apps/bff/.env.example apps/bff/.env" + missing=1 + fi + + # Portal env is optional - Next.js has sensible defaults for dev + if [ ! -f "$PROJECT_ROOT/apps/portal/.env.local" ] && [ ! -f "$PROJECT_ROOT/apps/portal/.env.development" ]; then + log "💡 Portal env file not found (optional). Create one with:" + log " cp apps/portal/.env.example apps/portal/.env.local" + fi + + if [ "$missing" -eq 1 ]; then + fail "Required env files missing. See messages above." fi } +# Load root .env for Docker Compose services (postgres, redis config) load_env_exported() { # Export so child processes see env (compose, pnpm etc.) set +u @@ -205,7 +214,6 @@ find_free_port() { start_services() { preflight "start" cd "$PROJECT_ROOT" - ensure_env load_env_exported log "🚀 Starting development services..." @@ -251,7 +259,6 @@ start_services() { start_with_tools() { preflight "tools" cd "$PROJECT_ROOT" - ensure_env load_env_exported log "🛠️ Starting development services with admin tools..." @@ -320,6 +327,9 @@ start_apps() { preflight "apps" cd "$PROJECT_ROOT" + # Verify app env files exist before proceeding + check_app_env + cleanup_dev if ! services_running; then @@ -424,8 +434,12 @@ Commands: reset - Reset development environment help - Show this help +Setup (first time): + cp apps/bff/.env.example apps/bff/.env + cp apps/portal/.env.example apps/portal/.env.local # optional + Environment overrides: - PROJECT_ROOT, COMPOSE_FILE, ENV_FILE, ENV_EXAMPLE_FILE, PROJECT_NAME + PROJECT_ROOT, COMPOSE_FILE, PROJECT_NAME DEV_STACK (full|services|auto) # default: full POSTGRES_USER, POSTGRES_DB, POSTGRES_PASSWORD, DB_WAIT_SECS NEXT_PORT, BFF_PORT