# Configuration Guide

Author: Nguyen Thi Nguyet Que Created on: May 3, 2026 Updated: May 3, 2026 — Simplified
configuration documentation

## Quick Start

```bash
# 1. Copy environment template
cp .env.example .env

# 2. Edit .env with your settings
# - DB_HOST, DB_USER, DB_PASSWORD, DB_NAME
# - JWT_SECRET, TOKEN_ENCRYPTION_KEY (min 32 chars)

# 3. Run
pnpm dev
```

---

## ✅ A. Configuration Priority

1. **`.env`** (highest priority) - Secrets and deployment-specific values
2. **Environment config** (`development.ts`, `production.ts`) - Environment-specific behavior
3. **`base.ts`** (lowest priority) - Default values for all environments

Example:

```typescript
// base.ts: port = 3001
// .env: PORT = 5000
// Final: port = 5000 (from .env)
```

---

## 📁 B. File Structure

```
src/config/
├── schema.ts          # Zod validation schema
├── base.ts            # Default values (all environments)
├── development.ts    # Development overrides (relaxed security)
├── production.ts      # Production overrides (strict security)
└── index.ts           # Merges config + loads .env
```

---

## 🎯 C. When to Edit Each File

| Task                                | File                    |
| ----------------------------------- | ----------------------- |
| Add new config option               | `schema.ts` + `base.ts` |
| Change default for all environments | `base.ts`               |
| Relax security for dev              | `development.ts`        |
| Tighten security for production     | `production.ts`         |
| Set secrets/passwords               | `.env`                  |

---

## ⚙️ D. Common Configuration

### D1. Change Port

```bash
# .env
PORT=3001
```

### Database Connection

```bash
# .env
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password
DB_NAME=bekind
```

### D3. Enable Redis

```bash
# .env
REDIS_ENABLED=true
REDIS_HOST=localhost
REDIS_PORT=6379
```

### D4. JWT Secrets

```bash
# .env (use strong secrets, min 32 chars)
JWT_SECRET=your_super_secret_key_minimum_32_characters
JWT_REFRESH_SECRET=your_refresh_secret_minimum_32_characters
TOKEN_ENCRYPTION_KEY=exactly_32_characters_long_key
```

### D5. Switch Storage Provider

```bash
# .env
STORAGE_PROVIDER=local  # or 'minio'
```

---

## 🔄 E. Development vs Production

| Setting                   | Development | Production |
| ------------------------- | ----------- | ---------- |
| `bcryptRounds`            | 4           | 12         |
| `includeTokensInResponse` | true        | false      |
| `forceSecure`             | false       | true       |
| `csrf.originValidation`   | false       | true       |
| `cors.devDisable`         | true        | false      |
| `storage.provider`        | local       | minio      |
| `redis.enabled`           | false       | true       |
| `virusScan.enabled`       | false       | true       |
| `showStackInErrors`       | true        | false      |

## Add New Configuration

**F1. Add to schema.ts:**

```typescript
export const ConfigSchema = z.object({
	// ... existing fields
	myNewFeature: z.object({
		enabled: z.boolean().default(false),
		apiKey: z.string().optional(),
	}),
});
```

**2. Add to base.ts:**

```typescript
export const baseConfig: Config = {
	// ... existing fields
	myNewFeature: {
		enabled: false,
		apiKey: '',
	},
};
```

**F3. Add to .env.example:**

```bash
MY_NEW_FEATURE_ENABLED=false
MY_NEW_FEATURE_API_KEY=
```

**4. Add to index.ts (for env override):**

```typescript
myNewFeature: {
	...merged.myNewFeature,
	enabled: process.env.MY_NEW_FEATURE_ENABLED === 'true',
	apiKey: process.env.MY_NEW_FEATURE_API_KEY || merged.myNewFeature.apiKey,
},
```

**F5. Override in environment-specific config (optional):**

```typescript
// development.ts
myNewFeature: {
	enabled: true, // Enable by default in dev
}
```

---

## 🌍 G. Environment Selection

| NODE_ENV      | Config File      |
| ------------- | ---------------- |
| `development` | `development.ts` |
| `test`        | `development.ts` |
| `staging`     | `production.ts`  |
| `production`  | `production.ts`  |

---

## 🔐 H. Security Rules

- **NEVER** commit `.env` to git
- Use `.env.example` as template
- Keep secrets only in `.env`
- Never hardcode secrets in TypeScript files

## Troubleshooting

### I1. Config not loading

- Check `NODE_ENV` is set
- Verify `.env` exists in project root
- Restart app after changing `.env`

### I2. Validation errors

- Check `schema.ts` for required fields
- Verify all env vars are set in `.env`
- Review Zod error message
