# Environment Configuration Guide

## 1. Purpose

The environment layer establishes one strict boundary between untrusted deployment text and application configuration. Raw values enter through `.env` or the process environment, are validated once, and then become deeply frozen configuration objects.

The configuration layer does not connect to MySQL, Redis, Telegram, or any external service. Connection capability checks belong to the phases that implement those services.

## 2. Safe setup

1. Copy `.env.example` to `.env` on the deployment host.
2. Restrict the file to the application account where the host supports Unix permissions: `chmod 600 .env`.
3. Replace every `replace-*` and `example.com` value.
4. Set `NODE_ENV=production` only after production values are ready.
5. Run `npm run verify:environment` before migrations or process startup.
6. Keep `.env` outside backups, support messages, screenshots, logs, and version control.

To validate only the distributable template, run:

```bash
npm run verify:environment:example
```

To obtain machine-readable, redacted diagnostics, run:

```bash
node bin/verify-environment.js --json
```

`configuration_preview` is designed for diagnostics, but it should still be handled as operational metadata rather than published publicly.

## 3. Generate independent secrets

Generate every secret independently. Do not reuse a database password, bot token, session secret, or cryptographic key.

```bash
openssl rand -base64 48   # SESSION_SECRET
openssl rand -base64 32   # ENCRYPTION_MASTER_KEY (exactly 32 decoded bytes)
openssl rand -base64 32   # CSRF_SECRET
openssl rand -base64 32   # PASSWORD_PEPPER
openssl rand -base64 32   # IDEMPOTENCY_HMAC_KEY
openssl rand -base64 32   # HEALTH_CHECK_TOKEN
openssl rand -hex 32      # TELEGRAM_WEBHOOK_SECRET
```

Copy only the generated output into the correct secret manager or `.env` field. Telegram supplies `TELEGRAM_BOT_TOKEN`; do not manufacture that value. Rotate a secret immediately if it appears in chat, source control, logs, or an unintended archive.

## 4. Ownership boundary

| Environment/deployment only                          | Admin-managed later                                      |
| ---------------------------------------------------- | -------------------------------------------------------- |
| Bot token and webhook secret                         | Welcome text and button labels                           |
| Database and Redis credentials                       | App name, logo, language, and display timezone           |
| Session, CSRF, encryption, pepper, and HMAC secrets  | Currency presentation and business limits                |
| Primary origin, trusted proxy, CORS, and CSP origins | Tasks, rewards, referrals, and withdrawal rules          |
| Storage roots, request limits, and log destination   | Themes, banners, tutorials, reminders, and feature flags |
| Runtime mode and infrastructure capacity             | Maintenance content and user-facing managed URLs         |

The Admin Panel must never rewrite deployment secrets or the application trust boundary.

## 5. Variable groups

| Group              | Key responsibility                                                             |
| ------------------ | ------------------------------------------------------------------------------ |
| Application        | Runtime mode, canonical origin, bind address, proxy trust, graceful timeout    |
| MySQL              | Host, credentials, pool limits, timeouts, timezone, TLS policy                 |
| Redis              | Availability, URL, namespace, retry limits, TLS verification                   |
| Queue              | Namespace, bounded batches, leases, polling, retries, backoff, job retention   |
| Telegram           | Bot identity, webhook path/secret, init-data freshness, API and Mini App URL   |
| Sessions           | Cookie policy, independent user/admin TTLs, rolling behavior                   |
| Security           | Key material, origins, URL allowlist, CSRF TTL, rate policies/store, body size |
| Uploads            | Root/subdirectories, byte and pixel limits, MIME allowlist, public path        |
| Logging/monitoring | Level, structured format, retention, body logging, optional Sentry destination |
| Admin bootstrap    | One-time Phase 8 administrator setup, disabled when fields are empty           |

The complete key list and documented defaults live in `.env.example`. The parser recognizes exactly those 87 names.

## 6. Important production rules

Production validation fails unless all of these are true:

- `APP_ORIGIN` and `TELEGRAM_WEB_APP_URL` use HTTPS, use a deployable hostname, and share the same origin.
- `CORS_ALLOWED_ORIGINS` contains the primary application origin.
- `TRUST_PROXY` is an explicit trusted subnet label or hop count; broad `true` and disabled `false` are rejected.
- `SESSION_COOKIE_SECURE` is `true` or `auto`; resolved production cookies are secure and HTTP-only.
- `REDIS_ENABLED=true` and `RATE_LIMIT_STORE=redis`.
- Authentication and sensitive-route limits cannot exceed the global request budget.
- A `rediss:` URL keeps certificate verification enabled.
- `TELEGRAM_API_BASE_URL` is `https://api.telegram.org`.
- JSON logging is enabled and request/response bodies are not logged.
- User and Admin idle TTLs are shorter than their corresponding absolute TTLs.
- Public, private, and quarantine upload directories are distinct and contain no traversal.
- Bootstrap administrator credentials are either both absent or both present; production bootstrap requires TOTP.

These checks are configuration safeguards, not substitutes for Cloudflare, Nginx, database permissions, encrypted backups, or secret management.

## 7. Load precedence

Runtime configuration merges values in this order:

1. Values read from `.env` (or the explicitly selected file).
2. Recognized process environment values, which override the file.

Unrelated hosting variables such as `PATH` are ignored. Unknown names inside the selected environment file fail validation so misspellings cannot silently use defaults. Duplicate keys within a file fail before parsing.

## 8. Application usage

Application modules should import a complete validated configuration rather than reading `process.env` directly:

```js
import { loadConfiguration } from './src/config/index.js';

const config = await loadConfiguration();
```

The returned object contains `app`, `database`, `telegram`, `session`, `redis`, `queue`, `security`, `upload`, and `logger` sections. It is deeply frozen to prevent accidental runtime mutation.

MySQL driver options deliberately keep big integers and decimals as strings. Telegram IDs and `amount_minor BIGINT` values must not be converted to JavaScript `number`.

## 9. Failure handling

The verifier exits with status `1` and lists key names plus safe error messages. It never includes rejected secret values in an error. Fix every reported issue before starting any process.

Common causes:

- A placeholder remains from `.env.example`.
- An origin contains a path, query, credentials, or non-HTTPS production scheme.
- A secret is short, low-diversity, or reused as another protected value.
- Redis/TLS, proxy, cookie, or logging settings are unsafe for production.
- A variable is misspelled or repeated.
- Numeric limits or TTL relationships are outside safe bounds.

Never bypass the verifier to make deployment appear healthy.
