Конфиги и переменные окружения (libs/apis/configs)
libs/apis/configs — набор Nx-библиотек-конфигов поверх @nestjs/config. Каждый конфиг инкапсулирует одну группу env-переменных, валидирует их через Joi и предоставляет типобезопасный сервис-геттер. Разделены на:
shared/*— общие для нескольких приложений:app,redis,s3,smtp,rabbit.auth-api/*— специфичные для аутентификации:jwt-customer,jwt-employee,jwt-admin.
Паттерн конфига
Заголовок раздела «Паттерн конфига»Каждый конфиг состоит из 4 (иногда 5) файлов. Разберём на примере shared/app:
-
app.env.ts— читает «сырые» переменные изprocess.env, приводит типы (напримерparseInt(APP_PORT)), задаёт дефолты и описывает TS-интерфейс:export const getAppEnvironment = (): AppEnvironmentVariables => {const { APP_ENV, APP_PORT } = process.env as Record<string, string>;return { APP_ENV, APP_PORT: parseInt(APP_PORT, 10) || 3000 };}; -
app.config.ts— регистрирует namespaced-конфиг черезregisterAs('app', ...), раскладывая env в структуру:export const appConfig = registerAs('app', () => {const env = getAppEnvironment();return { env: env.APP_ENV, port: env.APP_PORT };}); -
app-config.validation.ts— Joi-схема валидации значенийprocess.env..required()означает обязательность:export const validationSchema = Joi.object({APP_ENV: Joi.string().valid('development', 'production', 'stage'),APP_PORT: Joi.number(),}); -
app-config.service.ts— инъектируемый сервис-обёртка надConfigServiceс типизированными геттерами:@Injectable()export class AppConfigService {constructor(private configService: ConfigService<Record<string, unknown>, true>) {}get env(): string { return this.configService.get<string>('app.env'); }get port(): number { return this.configService.get<number>('app.port'); }} -
app-config.module.ts— модуль, подключающий namespaced-конфиг и схему валидации, экспортирующий сервис:@Module({imports: [ConfigModule.forRoot({ load: [appConfig], validationSchema })],providers: [ConfigService, AppConfigService],exports: [ConfigService, AppConfigService],})export class AppConfigModule {}
Остальные конфиги повторяют этот паттерн один-в-один (у jwt-admin есть дополнительный пустой jwt-admin.module.ts — заглушка). Потребители импортируют *ConfigModule и инжектят *ConfigService.
Полная таблица ВСЕХ env-переменных
Заголовок раздела «Полная таблица ВСЕХ env-переменных»Столбец «Обязательна» отражает Joi-схему: Да — есть .required(); Нет — переменная в схеме без .required() (валидируется по типу, но не обязательна); Да (default N) — .required()/наличие с дефолтом. Дефолты в скобках берутся из *.env.ts (parseInt || N).
| Переменная | Конфиг-модуль | Тип | Обязательна | Назначение |
|---|---|---|---|---|
APP_ENV | shared/app (AppConfigModule) | string (development/production/stage) | Нет | Текущее окружение; влияет на уровень логов Prisma |
APP_PORT | shared/app | number (default 3000) | Нет | HTTP-порт приложения |
REDIS_HOST | shared/redis (RedisConfigModule) | string | Да | Хост Redis |
REDIS_PORT | shared/redis | number (default 6379) | Да | Порт Redis |
REDIS_PASSWORD | shared/redis | string (allow '') | Да | Пароль Redis (может быть пустым) |
S3_ENDPOINT | shared/s3 (S3ConfigModule) | string | Да | Endpoint S3-совместимого хранилища |
S3_REGION | shared/s3 | string | Да | Регион S3 |
S3_ACCESS_KEY_ID | shared/s3 | string | Да | Access key ID |
S3_SECRET_ACCESS_KEY | shared/s3 | string | Да | Secret access key |
S3_BUCKET | shared/s3 | string | Да | Имя бакета (аватары, портфолио) |
SMTP_HOST | shared/smtp (SmtpConfigModule) | string | Да | Хост SMTP-сервера |
SMTP_PORT | shared/smtp | number (default 587) | Да | Порт SMTP |
SMTP_USER | shared/smtp | string | Да | Логин SMTP (маппится в username) |
SMTP_PASSWORD | shared/smtp | string | Да | Пароль SMTP |
SMTP_FROM | shared/smtp | string | Да | Адрес отправителя (from по умолчанию) |
RABBITMQ_HOST | shared/rabbit (RabbitConfigModule) | string | Да | Хост RabbitMQ |
RABBITMQ_PORT | shared/rabbit | number (default 5672) | Да | Порт RabbitMQ |
RABBITMQ_USERNAME | shared/rabbit | string | Да | Логин RabbitMQ |
RABBITMQ_PASSWORD | shared/rabbit | string (allow '') | Да | Пароль RabbitMQ |
RABBITMQ_PREFETCH | shared/rabbit | number (default 50) | Да (default 50) | Prefetch канала |
RABBITMQ_REQUEST_QUEUE | shared/rabbit | string | Да | Очередь запросов |
RABBITMQ_REQUEST_EXCHANGE | shared/rabbit | string | Да | Exchange запросов |
RABBITMQ_REQUEST_EXCHANGE_TYPE | shared/rabbit | string | Да | Тип exchange запросов |
RABBITMQ_RESPONSES_QUEUE | shared/rabbit | string | Да | Очередь ответов |
RABBITMQ_RESPONSES_EXCHANGE | shared/rabbit | string | Да | Exchange ответов |
RABBITMQ_RESPONSES_EXCHANGE_TYPE | shared/rabbit | string | Да | Тип exchange ответов |
JWT_CUSTOMER_ACCESS_SECRET_KEY | auth-api/jwt-customer (JwtCustomerConfigModule) | string | Нет | Секрет access-токена клиента |
JWT_CUSTOMER_ACCESS_EXPIRES_IN | auth-api/jwt-customer | number (default 3600) | Нет | TTL access-токена клиента (сек) |
JWT_CUSTOMER_REFRESH_SECRET_KEY | auth-api/jwt-customer | string | Нет | Секрет refresh-токена клиента |
JWT_CUSTOMER_REFRESH_EXPIRES_IN | auth-api/jwt-customer | number (default 7200) | Нет | TTL refresh-токена клиента (сек) |
JWT_EMPLOYEE_ACCESS_SECRET_KEY | auth-api/jwt-employee (JwtEmployeeConfigModule) | string | Нет | Секрет access-токена сотрудника |
JWT_EMPLOYEE_ACCESS_EXPIRES_IN | auth-api/jwt-employee | number (default 3600) | Нет | TTL access-токена сотрудника (сек) |
JWT_EMPLOYEE_REFRESH_SECRET_KEY | auth-api/jwt-employee | string | Нет | Секрет refresh-токена сотрудника |
JWT_EMPLOYEE_REFRESH_EXPIRES_IN | auth-api/jwt-employee | number (default 7200) | Нет | TTL refresh-токена сотрудника (сек) |
JWT_ADMIN_ACCESS_SECRET_KEY | auth-api/jwt-admin (JwtAdminConfigModule) | string | Да | Секрет access-токена админа |
JWT_ADMIN_ACCESS_EXPIRES_IN | auth-api/jwt-admin | number (default 3600) | Да | TTL access-токена админа (сек) |
JWT_ADMIN_REFRESH_SECRET_KEY | auth-api/jwt-admin | string | Да | Секрет refresh-токена админа |
JWT_ADMIN_REFRESH_EXPIRES_IN | auth-api/jwt-admin | number (default 7200) | Да | TTL refresh-токена админа (сек) |
ADMIN_ALLOWED_DOMAINS | auth-api/jwt-admin | string (CSV) | Да | Список разрешённых доменов админ-почты; парсится в string[] (split по ,, trim, lower-case) |
Примечания
Заголовок раздела «Примечания»- jwt-customer / jwt-employee: секреты и TTL описаны в Joi без
.required(), поэтому формально необязательны, но для реальной работы аутентификации секреты должны быть заданы. TTL имеют дефолты в*.env.ts(3600 / 7200). - jwt-admin — единственный jwt-конфиг со строгой валидацией (
.required()) плюс дополнительный геттерallowedDomains: string[]. REDIS_PASSWORDиRABBITMQ_PASSWORDиспользуютJoi.string().allow('').required()— переменная обязана присутствовать, но может быть пустой строкой.- Значения из
parseInt(... ) || Nв*.env.tsдают запасной дефолт даже если Joi пропускает пустое значение.