Skip to content

Commit c8f04c6

Browse files
committed
feat: add comprehensive environment variable documentation in ENV.md and update validation reference in existing documentation
1 parent eb4cdfd commit c8f04c6

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

.cursor/skills/podverse-api-patterns/01-environment-variables.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
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.
66

7+
**For comprehensive documentation, see [ENV.md](../../ENV.md) in the repository root.**
8+
79
## Validation Pattern
810

911
All environment variables are validated in `src/lib/startup/validation.ts` during application startup. The validation:

ENV.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
# Environment Variables
2+
3+
## Overview
4+
5+
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.
6+
7+
Validation occurs in `src/lib/startup/validation.ts` during application startup. The validation:
8+
9+
1. Checks if each variable is set
10+
2. Validates format/type where applicable (e.g., UUID for JWT secret, numeric for ports)
11+
3. Displays a categorized status for each variable
12+
4. Enforces conditional requirements based on `ACCOUNT_SIGNUP_MODE`
13+
5. Aborts startup if any required variables are missing or invalid
14+
15+
## Always Required Variables
16+
17+
These variables are **always required** regardless of configuration:
18+
19+
### Auth & Security
20+
21+
- **`AUTH_JWT_SECRET`** (Required)
22+
- Must be a valid UUID
23+
- Used for JWT token generation
24+
- Example: `123e4567-e89b-12d3-a456-426614174000`
25+
- Generate with: `uuidgen` (macOS/Linux) or use an online UUID generator
26+
27+
- **`USER_AGENT`** (Required)
28+
- Format: `BrandName Bot Environment/AppName/Version`
29+
- Must include "Bot" in the first part (before the first slash)
30+
- Example: `Podverse Bot Local/API/5`
31+
- Used for external API requests
32+
33+
### Database
34+
35+
- **`DB_HOST`** (Required) - Database hostname
36+
- **`DB_PORT`** (Required) - Database port (must be a valid number)
37+
- **`DB_READ_USERNAME`** (Required) - Read-only database username
38+
- **`DB_READ_PASSWORD`** (Required) - Read-only database password
39+
- **`DB_READ_WRITE_USERNAME`** (Required) - Read-write database username
40+
- **`DB_READ_WRITE_PASSWORD`** (Required) - Read-write database password
41+
- **`DB_DATABASE`** (Required) - Database name
42+
- **`DB_SSL_CONNECTION`** (Optional) - Use SSL for database connection (default: `false`)
43+
44+
### API Configuration
45+
46+
- **`API_PORT`** (Required) - API server port (must be a valid number)
47+
- **`API_PREFIX`** (Required) - API route prefix (e.g., `/api`)
48+
- **`API_VERSION`** (Required) - API version (e.g., `v2`)
49+
- **`COOKIE_DOMAIN`** (Required) - Domain for cookies
50+
- **`API_ALLOWED_CORS_ORIGINS`** (Required) - Comma-separated list of allowed CORS origins (must contain at least one origin)
51+
52+
### Web
53+
54+
- **`WEB_PROTOCOL`** (Required) - Web protocol (`http` or `https`)
55+
- **`WEB_DOMAIN`** (Required) - Web domain (e.g., `localhost:3000` or `podverse.fm`)
56+
57+
### Message Queue
58+
59+
- **`MESSAGE_QUEUE_PROTOCOL`** (Required) - Message queue protocol (e.g., `amqp`)
60+
- **`MESSAGE_QUEUE_HOST`** (Required) - Message queue hostname
61+
- **`MESSAGE_QUEUE_USERNAME`** (Required) - Message queue username
62+
- **`MESSAGE_QUEUE_PASSWORD`** (Required) - Message queue password
63+
- **`MESSAGE_QUEUE_PORT`** (Required) - Message queue port (must be a valid number)
64+
65+
### Key-Value DB
66+
67+
- **`KEYVALDB_HOST`** (Required) - Key-value database hostname
68+
- **`KEYVALDB_PORT`** (Required) - Key-value database port (must be a valid number)
69+
- **`KEYVALDB_PASSWORD`** (Required) - Key-value database password
70+
- **`KEYVALDB_CACHE_TTL_SECONDS`** (Required) - Cache TTL in seconds (must be a valid number)
71+
72+
### Podcast Index
73+
74+
- **`PODCAST_INDEX_AUTH_KEY`** (Required) - Podcast Index API authentication key
75+
- **`PODCAST_INDEX_BASE_URL`** (Required) - Podcast Index API base URL
76+
- **`PODCAST_INDEX_SECRET_KEY`** (Required) - Podcast Index API secret key
77+
78+
### Premium/Membership
79+
80+
- **`ACCOUNT_SIGNUP_MODE`** (Required) - Must be either `'sign-up'` or `'contact-only'`
81+
- When set to `'sign-up'`: Enables user registration and requires additional email/mailer configuration
82+
- When set to `'contact-only'`: Disables user registration, email/mailer config becomes optional
83+
84+
## Conditionally Required Variables
85+
86+
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.
87+
88+
### Mailer
89+
90+
- **`MAILER_HOST`** (Required when signup mode is 'sign-up') - SMTP server hostname
91+
- **`MAILER_PORT`** (Required when signup mode is 'sign-up') - SMTP server port (must be a valid number)
92+
- **`MAILER_USERNAME`** (Required when signup mode is 'sign-up') - SMTP username
93+
- **`MAILER_PASSWORD`** (Required when signup mode is 'sign-up') - SMTP password
94+
- **`MAILER_FROM`** (Required when signup mode is 'sign-up') - Email sender address
95+
- **`MAILER_DISABLED`** (Optional) - Disable mailer (default: `false`)
96+
97+
### Email Configuration
98+
99+
- **`EMAIL_BRAND_COLOR`** (Required when signup mode is 'sign-up') - Brand color for email templates
100+
- **`EMAIL_HEADER_IMAGE_URL`** (Required when signup mode is 'sign-up') - URL for email header image
101+
- **`LEGAL_NAME`** (Required when signup mode is 'sign-up') - Legal business name
102+
- **`LEGAL_ADDRESS`** (Required when signup mode is 'sign-up') - Legal business address
103+
104+
### Token Expiration
105+
106+
- **`VERIFY_EMAIL_TOKEN_EXPIRATION`** (Required when signup mode is 'sign-up') - Email verification token expiration in seconds (must be a valid number)
107+
- **`EMAIL_CHANGE_VERIFICATION_TOKEN_EXPIRATION`** (Required when signup mode is 'sign-up') - Email change verification token expiration in seconds (must be a valid number)
108+
- **`RESET_PASSWORD_TOKEN_EXPIRATION`** (Required when signup mode is 'sign-up') - Password reset token expiration in seconds (must be a valid number)
109+
110+
### Page Paths
111+
112+
- **`VERIFY_EMAIL_PAGE_PATH`** (Required when signup mode is 'sign-up') - Path to email verification page (e.g., `/verify-email`)
113+
- **`EMAIL_CHANGE_VERIFICATION_PAGE_PATH`** (Required when signup mode is 'sign-up') - Path to email change verification page (e.g., `/verify-email-change`)
114+
- **`RESET_PASSWORD_PAGE_PATH`** (Required when signup mode is 'sign-up') - Path to password reset page (e.g., `/reset-password`)
115+
116+
## Optional Variables
117+
118+
These variables are optional but will still be validated if set:
119+
120+
### Premium/Membership
121+
122+
- **`PREMIUM_MEMBERSHIP_COST_MONTHLY`** (Optional) - Monthly premium membership cost
123+
- **`PREMIUM_MEMBERSHIP_COST_ANNUALLY`** (Optional) - Annual premium membership cost
124+
- **`FREE_TRIAL_EXPIRATION`** (Optional) - Free trial expiration duration
125+
126+
### Social Media
127+
128+
These variables are used when signup mode is 'sign-up' but are not required:
129+
130+
- **`SOCIAL_FACEBOOK_PAGE_URL`** (Optional) - Facebook page URL
131+
- **`SOCIAL_FACEBOOK_IMAGE_URL`** (Optional) - Facebook image URL
132+
- **`SOCIAL_GITHUB_PAGE_URL`** (Optional) - GitHub page URL
133+
- **`SOCIAL_GITHUB_IMAGE_URL`** (Optional) - GitHub image URL
134+
- **`SOCIAL_REDDIT_PAGE_URL`** (Optional) - Reddit page URL
135+
- **`SOCIAL_REDDIT_IMAGE_URL`** (Optional) - Reddit image URL
136+
- **`SOCIAL_TWITTER_PAGE_URL`** (Optional) - Twitter/X page URL
137+
- **`SOCIAL_TWITTER_IMAGE_URL`** (Optional) - Twitter/X image URL
138+
139+
### PayPal
140+
141+
- **`PAYPAL_CLIENT_ID`** (Optional) - PayPal client ID for payment processing
142+
- **`PAYPAL_CLIENT_SECRET`** (Optional) - PayPal client secret for payment processing
143+
144+
### General
145+
146+
- **`NODE_ENV`** (Optional) - Node environment (`development`, `production`, etc.)
147+
- **`LOG_LEVEL`** (Optional) - Logging level (`error`, `warn`, `info`, `debug`, `verbose`, `silly`, `silent`)
148+
149+
## Validation Rules
150+
151+
### Numeric Validation
152+
153+
Variables containing `PORT`, `EXPIRATION`, or `CACHE_TTL` are automatically validated to ensure they are valid positive numbers:
154+
- `DB_PORT`
155+
- `API_PORT`
156+
- `MESSAGE_QUEUE_PORT`
157+
- `KEYVALDB_PORT`
158+
- `KEYVALDB_CACHE_TTL_SECONDS`
159+
- `MAILER_PORT`
160+
- `VERIFY_EMAIL_TOKEN_EXPIRATION`
161+
- `EMAIL_CHANGE_VERIFICATION_TOKEN_EXPIRATION`
162+
- `RESET_PASSWORD_TOKEN_EXPIRATION`
163+
164+
### Format Validation
165+
166+
- **UUID Format**: `AUTH_JWT_SECRET` must be a valid UUID
167+
- **User-Agent Format**: `USER_AGENT` must follow `BrandName Bot Environment/AppName/Version` and include "Bot" in the first part
168+
- **CORS Origins**: `API_ALLOWED_CORS_ORIGINS` must contain at least one origin (comma-separated)
169+
170+
## Validation Output
171+
172+
During startup, the validation displays:
173+
- A categorized list of all environment variables
174+
- Status indicator (✓ for valid, ✗ for invalid)
175+
- Whether the variable is required or optional
176+
- Conditional requirements (e.g., "required when signup mode is 'sign-up'")
177+
- A message indicating the validation result
178+
- A summary with totals and counts
179+
180+
Example output:
181+
```
182+
=== Environment Variable Validation ===
183+
184+
[Auth & Security]
185+
✓ AUTH_JWT_SECRET - Valid UUID
186+
✓ USER_AGENT - Valid format
187+
188+
[Database]
189+
✓ DB_HOST - Set
190+
✓ DB_PORT - Set
191+
...
192+
193+
=== Validation Summary ===
194+
Total: 45
195+
Passed: 42
196+
Failed: 3
197+
Required Missing: 2
198+
```
199+
200+
## Important Notes
201+
202+
- **No default values**: The application must 100% depend on values from the `.env` file. All defaults have been removed from `config/index.ts`.
203+
- **Conditional requirements**: Always check `ACCOUNT_SIGNUP_MODE` when determining if mailer, email config, social media, token expiration, and page path variables are required.
204+
- **Startup abort**: If any required variable is missing or invalid, the application will abort startup with a clear error message.
205+
- **Validation file**: See `src/lib/startup/validation.ts` for the complete validation implementation.
206+
207+
## Adding New Environment Variables
208+
209+
When adding a new environment variable to the application:
210+
211+
1. **Add to `src/config/index.ts`**:
212+
- Remove any default values (use `process.env.VAR_NAME!`)
213+
- Add the variable to the appropriate config section
214+
215+
2. **Add validation to `src/lib/startup/validation.ts`**:
216+
- Determine if the variable is:
217+
- Always required
218+
- Conditionally required (based on `ACCOUNT_SIGNUP_MODE` or other conditions)
219+
- Optional
220+
- Add appropriate validation call in `validateAllEnvironmentVariables()`
221+
- Use `validateRequired()` for required vars
222+
- Use `validateOptional()` for optional vars
223+
- Add custom validation if format/type checking is needed
224+
225+
3. **Update this file**:
226+
- Add the variable to the appropriate section above
227+
- Document any special requirements (format, type, conditional logic)
228+
229+
4. **Update `.env.example`** (if applicable):
230+
- Add the variable with a comment explaining its purpose

0 commit comments

Comments
 (0)