The podverse-api application requires comprehensive environment variable validation on startup. All environment variables must be provided through the .env file - no default values are used in the configuration.
Validation occurs in src/lib/startup/validation.ts during application startup. The validation:
- Checks if each variable is set
- Validates format/type where applicable (e.g., UUID for JWT secret, numeric for ports)
- Displays a categorized status for each variable
- Enforces conditional requirements based on
ACCOUNT_SIGNUP_MODE - Aborts startup if any required variables are missing or invalid
These variables are always required regardless of configuration:
-
AUTH_JWT_SECRET(Required)- Must be a valid UUID
- Used for JWT token generation
- Example:
123e4567-e89b-12d3-a456-426614174000 - Generate with:
uuidgen(macOS/Linux) or use an online UUID generator
-
USER_AGENT(Required)- Format:
BrandName Bot Environment/AppName/Version - Must include "Bot" in the first part (before the first slash)
- Example:
Podverse Bot Local/API/5 - Used for external API requests
- Format:
DB_HOST(Required) - Database hostnameDB_PORT(Required) - Database port (must be a valid number)DB_READ_USERNAME(Required) - Read-only database usernameDB_READ_PASSWORD(Required) - Read-only database passwordDB_READ_WRITE_USERNAME(Required) - Read-write database usernameDB_READ_WRITE_PASSWORD(Required) - Read-write database passwordDB_DATABASE(Required) - Database nameDB_SSL_CONNECTION(Optional) - Use SSL for database connection (default:false)
API_PORT(Required) - API server port (must be a valid number)API_PREFIX(Required) - API route prefix (e.g.,/api)API_VERSION(Required) - API version (e.g.,v2)COOKIE_DOMAIN(Required) - Domain for cookiesAPI_ALLOWED_CORS_ORIGINS(Required) - Comma-separated list of allowed CORS origins (must contain at least one origin)
SERVER_ENV(Required) - Server environment- Must be one of:
prod,beta,alpha,local - Controls environment-specific behavior (e.g., bypassing free trial restrictions in non-production environments)
- Must be one of:
WEB_PROTOCOL(Required) - Web protocol (httporhttps)WEB_DOMAIN(Required) - Web domain (e.g.,localhost:3000orpodverse.fm)
MESSAGE_QUEUE_PROTOCOL(Required) - Message queue protocol (e.g.,amqp)MESSAGE_QUEUE_HOST(Required) - Message queue hostnameMESSAGE_QUEUE_USERNAME(Required) - Message queue usernameMESSAGE_QUEUE_PASSWORD(Required) - Message queue passwordMESSAGE_QUEUE_PORT(Required) - Message queue port (must be a valid number)
KEYVALDB_HOST(Required) - Key-value database hostnameKEYVALDB_PORT(Required) - Key-value database port (must be a valid number)KEYVALDB_PASSWORD(Required) - Key-value database passwordKEYVALDB_CACHE_TTL_SECONDS(Required) - Cache TTL in seconds (must be a valid number)
PODCAST_INDEX_AUTH_KEY(Required) - Podcast Index API authentication keyPODCAST_INDEX_BASE_URL(Required) - Podcast Index API base URLPODCAST_INDEX_SECRET_KEY(Required) - Podcast Index API secret key
ACCOUNT_SIGNUP_MODE(Required) - Must be either'sign-up'or'contact-only'(no default value)- Must be explicitly set - no default value is assumed
- When set to
'sign-up': Enables user registration and requires additional email/mailer configuration - When set to
'contact-only': Disables user registration, email/mailer config becomes optional
These variables are required only when ACCOUNT_SIGNUP_MODE is set to 'sign-up'. When ACCOUNT_SIGNUP_MODE is 'contact-only', these variables are optional.
MAILER_HOST(Required when signup mode is 'sign-up') - SMTP server hostnameMAILER_PORT(Required when signup mode is 'sign-up') - SMTP server port (must be a valid number)MAILER_USERNAME(Required when signup mode is 'sign-up') - SMTP usernameMAILER_PASSWORD(Required when signup mode is 'sign-up') - SMTP passwordMAILER_FROM(Required when signup mode is 'sign-up') - Email sender addressMAILER_DISABLED(Optional) - Disable mailer (default:false)
EMAIL_BRAND_COLOR(Required when signup mode is 'sign-up') - Brand color for email templatesEMAIL_HEADER_IMAGE_URL(Required when signup mode is 'sign-up') - URL for email header imageLEGAL_NAME(Required when signup mode is 'sign-up') - Legal business nameLEGAL_ADDRESS(Required when signup mode is 'sign-up') - Legal business address
VERIFY_EMAIL_TOKEN_EXPIRATION(Required when signup mode is 'sign-up') - Email verification token expiration in seconds (must be a valid number)EMAIL_CHANGE_VERIFICATION_TOKEN_EXPIRATION(Required when signup mode is 'sign-up') - Email change verification token expiration in seconds (must be a valid number)RESET_PASSWORD_TOKEN_EXPIRATION(Required when signup mode is 'sign-up') - Password reset token expiration in seconds (must be a valid number)
VERIFY_EMAIL_PAGE_PATH(Required when signup mode is 'sign-up') - Path to email verification page (e.g.,/verify-email)EMAIL_CHANGE_VERIFICATION_PAGE_PATH(Required when signup mode is 'sign-up') - Path to email change verification page (e.g.,/verify-email-change)RESET_PASSWORD_PAGE_PATH(Required when signup mode is 'sign-up') - Path to password reset page (e.g.,/reset-password)
These variables are optional but will still be validated if set:
PREMIUM_MEMBERSHIP_COST_MONTHLY(Optional) - Monthly premium membership costPREMIUM_MEMBERSHIP_COST_ANNUALLY(Optional) - Annual premium membership costFREE_TRIAL_EXPIRATION(Optional) - Free trial expiration duration
These variables are used when signup mode is 'sign-up' but are not required:
SOCIAL_FACEBOOK_PAGE_URL(Optional) - Facebook page URLSOCIAL_FACEBOOK_IMAGE_URL(Optional) - Facebook image URLSOCIAL_GITHUB_PAGE_URL(Optional) - GitHub page URLSOCIAL_GITHUB_IMAGE_URL(Optional) - GitHub image URLSOCIAL_REDDIT_PAGE_URL(Optional) - Reddit page URLSOCIAL_REDDIT_IMAGE_URL(Optional) - Reddit image URLSOCIAL_TWITTER_PAGE_URL(Optional) - Twitter/X page URLSOCIAL_TWITTER_IMAGE_URL(Optional) - Twitter/X image URL
PAYPAL_CLIENT_ID(Optional) - PayPal client ID for payment processingPAYPAL_CLIENT_SECRET(Optional) - PayPal client secret for payment processing
NODE_ENV(Optional) - Node environment (development,production, etc.)LOG_LEVEL(Optional) - Logging level (error,warn,info,debug,verbose,silly,silent)
Variables containing PORT, EXPIRATION, or CACHE_TTL are automatically validated to ensure they are valid positive numbers:
DB_PORTAPI_PORTMESSAGE_QUEUE_PORTKEYVALDB_PORTKEYVALDB_CACHE_TTL_SECONDSMAILER_PORTVERIFY_EMAIL_TOKEN_EXPIRATIONEMAIL_CHANGE_VERIFICATION_TOKEN_EXPIRATIONRESET_PASSWORD_TOKEN_EXPIRATION
- UUID Format:
AUTH_JWT_SECRETmust be a valid UUID - User-Agent Format:
USER_AGENTmust followBrandName Bot Environment/AppName/Versionand include "Bot" in the first part - CORS Origins:
API_ALLOWED_CORS_ORIGINSmust contain at least one origin (comma-separated)
During startup, the validation displays:
- A categorized list of all environment variables
- Status indicator (✓ for valid, ✗ for invalid)
- Whether the variable is required or optional
- Conditional requirements (e.g., "required when signup mode is 'sign-up'")
- A message indicating the validation result
- A summary with totals and counts
Example output:
=== Environment Variable Validation ===
[Auth & Security]
✓ AUTH_JWT_SECRET - Valid UUID
✓ USER_AGENT - Valid format
[Database]
✓ DB_HOST - Set
✓ DB_PORT - Set
...
=== Validation Summary ===
Total: 45
Passed: 42
Failed: 3
Required Missing: 2
- No default values: The application must 100% depend on values from the
.envfile. All defaults have been removed fromconfig/index.ts. - Conditional requirements: Always check
ACCOUNT_SIGNUP_MODEwhen determining if mailer, email config, social media, token expiration, and page path variables are required. - Startup abort: If any required variable is missing or invalid, the application will abort startup with a clear error message.
- Validation file: See
src/lib/startup/validation.tsfor the complete validation implementation.
When adding a new environment variable to the application:
-
Add to
src/config/index.ts:- Remove any default values (use
process.env.VAR_NAME!) - Add the variable to the appropriate config section
- Remove any default values (use
-
Add validation to
src/lib/startup/validation.ts:- Determine if the variable is:
- Always required
- Conditionally required (based on
ACCOUNT_SIGNUP_MODEor other conditions) - Optional
- Add appropriate validation call in
validateAllEnvironmentVariables() - Use
validateRequired()for required vars - Use
validateOptional()for optional vars - Add custom validation if format/type checking is needed
- Determine if the variable is:
-
Update this file:
- Add the variable to the appropriate section above
- Document any special requirements (format, type, conditional logic)
-
Update
.env.example(if applicable):- Add the variable with a comment explaining its purpose