Skip to content

Конфігурація ​

Бекенд налаштовується лише через змінні оточення. Значення за замовчуванням і правила обов'язковості нижче взято з коду конфігураційних модулів, а не з .env.example.

Як завантажується конфігурація ​

  • .env читає dotenv через import "dotenv/config". Цей рядок стоїть першим у точці входу src/index.ts, у src/sentry-bootstrap.ts, у скриптах src/db/create-database.ts, src/db/seed.ts та src/scripts/send-test-email.ts. Файл шукається в поточній робочій директорії процесу, тобто зазвичай це packages/backend/.env.
  • Кожен файл у src/config/ один раз читає env з node:process під час імпорту й повертає Object.freeze(...). Якщо змінити змінну після старту, процес її не побачить.
  • PostgreSQL-налаштування збирає одна функція resolveDatabaseConfig() у src/config/database.ts. Її використовують застосунок, db:create (create-database.ts) і drizzle.config.ts, тож defaults однакові всюди. drizzle.config.ts не імпортує dotenv.
  • Булеві та цілі значення розбирає одна пара функцій, parseBoolean і parseInteger, через createEnvReader. Правила — у розділі Булеві та цілі значення.
  • Після імпорту конфігурацій src/index.ts викликає validateRuntimeConfig(). Вона кидає помилку й зупиняє старт, якщо комбінація змінних неприпустима. Нижче ці перевірки позначено як «throw на старті».

Булеві та цілі значення ​

Усі булеві та цілі змінні .env читає той самий код (env-reader.ts). Він збирає всі знайдені проблеми одного модуля й повідомляє їх разом через validateRuntimeConfig() (Invalid <область> configuration: ...), з назвою змінної.

ТипПриймаєтьсяПорожньо / не заданоІнше значення
booleantrue, 1, yes, on → true; false, 0, no, off → false. Регістр і пробіли по краях неважливіdefault змінноїпомилка старту (не «false»)
integerдесяткові цифри, без знака, у межах змінної {min, max} (включно), безпечне цілеdefault змінноїпомилка старту (1e3, 0x10, -5, 1.5, 5ms)

Це змінило поведінку порівняно з окремими парсерами, які були раніше: AUTH_PHONE_ENABLED=yes тепер true (раніше auth.ts знав лише 1/true); True та TRUE тепер true скрізь (раніше parseBoolean був чутливий до регістру, і APP_IS_PRODUCTION=True давав false); одруківка в булевій змінній (CSRF_ENFORCE=flase) більше не тихо дає false, а зупиняє старт; AUTH_*=1e3 і PORT=abc більше не приймаються і не підміняються default-ом (раніше PORT, SMTP_PORT мовчки поверталися до 3000/587); порожнє значення в змінних rate limit більше не помилка, а default. Прості строкові змінні, розміри в байтах (APP_MAX_BODY_SIZE, ...), тривалості (SESSION_ANON_TTL) і частки (SENTRY_TRACES_SAMPLE_RATE) мають власні правила, описані біля змінних.

Production-like режим ​

appConfig.isProductionLike дорівнює APP_IS_PRODUCTION, якщо змінну задано. Інакше він дорівнює true, коли APP_ENV (або NODE_ENV, якщо APP_ENV відсутня) після trim().toLowerCase() має значення production або prod. Від цього режиму залежить таке:

  • SESSION_COOKIE_HOST_PREFIX за замовчуванням вмикається, і cookie сесії отримує назву __Host-uapi. Тоді APP_URL має починатися з https://, інакше на старті буде throw.
  • AUTH_SMS_PROVIDER=fake заборонено: на старті буде throw.

Окремо від isProductionLike, APP_ENV впливає на інші місця напряму:

  • secure у cookie (cookies.ts, session.ts) дорівнює APP_ENV !== 'local'.
  • CSP connect-src у csp.ts не пропускає ws: та http:, коли APP_ENV дорівнює production або prod. Тут порівняння точне, без нормалізації.

Застосунок і сервер ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
APP_NAMEНазва застосункуuwebsockets-apiНіapp.ts
APP_KEYСекрет застосунку; запасний ключ для хешування OTPнемає (undefined)Так, якщо AUTH_PHONE_ENABLED=true і немає AUTH_OTP_HMAC_KEY: потрібно ≥ 32 символи, інакше throw на стартіapp.ts
APP_ENVНазва оточення: production-like режим, secure у cookie, CSP, default для Sentry environmentнемаєНі, але без неї cookie мають secure: true, бо undefined !== 'local'app.ts, cookies.ts, session.ts, csp.ts
NODE_ENVЗапасне джерело назви оточення, коли APP_ENV не заданонемаєНіapp.ts
APP_IS_PRODUCTIONЯвно вмикає або вимикає production-like режимвиводиться з APP_ENV/NODE_ENVНіapp.ts
APP_URLПублічний URL бекенда (кінцевий / обрізається)""Так, якщо SESSION_COOKIE_HOST_PREFIX увімкнено: має бути https://, інакше throwapp.ts
FRONTEND_URLURL фронтенда для посилань у листахзначення APP_URLНіapp.ts
LANDING_URLURL лендингу""Ніapp.ts
DOMAINХост (і порт, якщо не 80/443) для wsUrl: фронтенд підключається до ws(s)://<DOMAIN>/<API_PATH_PREFIX>/websocket (get-ws-url-service.ts). Локально — 127.0.0.1:3000127.0.0.1Ніapp.ts
HOSTАдреса, на якій слухає сервер0.0.0.0Ніapp.ts
PORTTCP-порт3000 (так само для значень поза 1–65535)Ніapp.ts
APP_UNIX_PATHШлях до Unix-сокета замість TCP. Порожнє значення (APP_UNIX_PATH=) означає «не задано»немаєНіapp.ts
SERVE_STATICРоздавати статичні файли з бекендаfalseНіapp.ts
STATIC_MAX_MEMORY_FILE_SIZEНайбільший файл статики в RAM, байти; більші віддаються стрімінгом з диска1048576Ніapp.ts
STATIC_MAX_MEMORY_TOTALБюджет RAM для статики разом зі стислими варіантами, байти67108864Ніapp.ts
DOC_PAGEВмикає GET /<prefix>/doc/routes (лише разом з APP_ENV=manual-test і SERVE_STATIC=true, див. маршрутизацію)falseНіapp.ts

Маршрутизація і CDN ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
API_PATH_PREFIXПрефікс HTTP-маршрутів (крайні / прибираються)apiНіapp.ts
CDN_URLБазовий URL CDN""Ніapp.ts

Ліміти тіла запиту ​

Значення задаються в байтах: лише додатне безпечне ціле число, записане цифрами (пробіли навколо допускаються). Будь-що інше — abc, 0, -1, 1.5, 1e6, 0x10, Infinity, число понад Number.MAX_SAFE_INTEGER — замінюється на default. Ліміт за типом тіла описано в Життєвому циклі запиту.

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
APP_MAX_BODY_SIZEЗагальний ліміт тіла2097152 (2 MiB)Ніapp.ts
APP_MAX_JSON_BODY_SIZEЛіміт для JSON2097152 (2 MiB)Ніapp.ts
APP_MAX_MULTIPART_BODY_SIZEЛіміт для multipart52428800 (50 MiB)Ніapp.ts
APP_MAX_OCTET_BODY_SIZEЛіміт для application/octet-stream52428800 (50 MiB)Ніapp.ts

Чому такі defaults:

  • 2 MiB для JSON і решти типів. Реальні JSON-тіла значно менші, а зниження до 1 MiB змінило б поведінку без вигоди.
  • 50 MiB для multipart — політика сумісності. Фактична потреба менша: файлові ліміти сервісів — 10 MB для аватара (avatar-service.ts) і 5 MB для скриншота бази знань (knowledge-base-service.ts), плюс невелика multipart-обгортка. Тож ліміт тіла можна знизити, не зачепивши наявні маршрути.
  • 50 MiB для octet. octet-маршрутів у шаблоні немає.

Під час розгортання:

  • Проксі. Ліміт проксі перед backend (client_max_body_size у nginx, ліміти CDN) має бути не меншим за потрібний ліміт тіла, інакше великі запити відріже проксі зі своєю відповіддю, а не backend з 413.
  • Пам'ять. Тіло збирається в пам'яті. Приблизна оцінка самих буферів тіла: ≈ кількість одночасних запитів × maxMultipartBodySize × 2. Це не верхня межа пам'яті процесу: парсери ще створюють рядки, об'єкти й копії даних. Для аварійного зниження є APP_MAX_MULTIPART_BODY_SIZE.

Безпека: CORS, CSRF, проксі, CSP ​

Докладніше про ці механізми див. на сторінці Безпека.

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
ENABLED_CORSВмикає обробку CORSfalseНіcors.ts
CORS_ALLOWED_ORIGINSWhitelist origin через кому, без wildcard[]Ні, але з порожнім списком жоден cross-origin запит не пройдеcors.ts
CREDENTIONALS_CORSAccess-Control-Allow-Credentials (назва змінної саме з такою орфографією)falseНіcors.ts
CSRF_ENFORCEВідхиляти CSRF-порушення з 403; false — лише логуватиtrueНіcsrf.ts
CSRF_STRICT_ORIGINВідхиляти небезпечні запити без Origin і ReferertrueНіcsrf.ts
CSRF_ALLOWED_ORIGINSТочні origin для CSRF через кому (без шляху і / в кінці)[]Так у production-like; інакше fallback на APP_URL/FRONTEND_URLcsrf.ts
TRUST_PROXYДовіряти заголовкам проксі для визначення IPfalseНіnetwork.ts
TRUSTED_PROXY_CIDRSCIDR довірених проксі через кому[]Ніnetwork.ts
CSP_ENABLEDВмикає глобальну Content-Security-PolicytrueНіcsp.ts
CSP_REPORT_ONLYНадсилати всі глобальні політики як -Report-OnlyfalseНіcsp.ts
CSP_REPORT_URIАбсолютний http(s) URL отримувача звітів (шлях дозволено)""Ніcsp.ts
CSP_API_ORIGINOrigin HTTP API для connect-src (= VITE_BASE_URL)origin APP_URLНі, якщо API на тому ж origin, що й APP_URLcsp.ts
CSP_WS_ORIGINOrigin WebSocket (ws:/wss:)origin getWsUrl()Ні, але потрібен за проксі з іншим WS-доменомcsp.ts
CSP_SENTRY_ORIGINOrigin Sentry ingest для connect-src""Так, якщо фронтенд шле події в Sentrycsp.ts
CSP_EXTRA_CONNECT_SRCДодаткові origins для connect-src через кому (http(s)/ws(s))""Ніcsp.ts
CSP_EXTRA_IMG_SRCДодаткові origins для img-src через кому (http(s))""Ніcsp.ts

Rate limit ​

Значення читаються за контрактом цілих: дробові, від'ємні, 1e3, Infinity, NaN і нечислові значення валять старт (Invalid rate limit configuration), порожнє значення дає default. Деталі в розділі Обмеження частоти запитів.

ЗміннаПризначенняDefaultОбов'язковістьДжерело
HTTP_GLOBAL_RATE_LIMIT_MAXL1: максимум API-запитів з одного IP за вікно; 0 вимикає600Ніrate-limit.ts
HTTP_GLOBAL_RATE_LIMIT_WINDOW_MSВікно L1 (fixed window), мс, ціле > 060000Ніrate-limit.ts
WS_UPGRADE_RATE_LIMIT_MAXUpgrade рівень 1 (пам'ять процесу): максимум з одного IP за вікно; 0 вимикає120Ніrate-limit.ts
WS_UPGRADE_RATE_LIMIT_WINDOW_MSВікно upgrade-ліміту (sliding log), мс, ціле > 060000Ніrate-limit.ts
WS_UPGRADE_SHARED_RATE_LIMIT_MAXUpgrade рівень 2 (Redis, спільний): максимум з одного IP за вікно; 0 вимикає рівень 260Ніthrottle-policies.ts
WS_UPGRADE_SHARED_RATE_LIMIT_WINDOW_MSВікно рівня 2 (sliding log), мс, ціле > 060000Ніthrottle-policies.ts
WS_ADMIN_RECHECK_INTERVAL_MSЯк часто інстанс перечитує з БД роль своїх admin-з'єднань (Відкликання admin-доступу); межа затримки відкликання; цілі мс30000Ні; не ціле число або поза 100…3600000 — throw на стартіwebsocket.ts
SUPPORT_CHAT_USER_RATE_LIMIT_MAXПовідомлень чату підтримки від одного користувача за вікно (Допуск повідомлення); понад ліміт — відповідь 42920Ні; не ціле число або < 1 — помилка конфігураціїthrottle-policies.ts
SUPPORT_CHAT_USER_RATE_LIMIT_WINDOW_MSВікно цього ліміту, мс60000Ніthrottle-policies.ts
SUPPORT_OPEN_CHAT_USER_RATE_LIMIT_MAXВідкриттів чату (привітань) від одного користувача за вікно5Ніthrottle-policies.ts
SUPPORT_OPEN_CHAT_USER_RATE_LIMIT_WINDOW_MSВікно цього ліміту, мс60000Ніthrottle-policies.ts
RATE_LIMIT_REDIS_TIMEOUT_MSТаймаут команди окремого Redis-з'єднання спільних лімітів, мс50Ніrate-limit.ts

Спільні auth-ліміти (Redis) ​

Читає реєстр throttle-policies.ts. Значення мають бути цілими ≥ 1 (контракт): 0 чи невалідне значення валить старт (Invalid throttle policy configuration), бо захист чутливої дії вимкнути не можна. Повна таблиця політик — у розділі Обмеження частоти запитів.

ЗміннаПризначенняDefault
AUTH_LOGIN_MAX_ATTEMPTS_PER_IPСпроби входу з одного IP за вікно (рахується кожна спроба)20
AUTH_LOGIN_MAX_ATTEMPTS_PER_IDENTIFIERСпроби входу на один email/телефон за вікно; скидається після успіху40
AUTH_LOGIN_WINDOW_SECONDSВікно обох login-лімітів, с900
AUTH_CHANGE_PASSWORD_MAX_ATTEMPTS_PER_USERСпроби зміни пароля на користувача за вікно; скидається після успіху10
AUTH_CHANGE_PASSWORD_WINDOW_SECONDSВікно ліміту зміни пароля, с900
AUTH_FORGOT_PASSWORD_MAX_REQUESTS_PER_IP_PER_HOURЗапити листа скидання пароля з одного IP10
AUTH_FORGOT_PASSWORD_MAX_REQUESTS_PER_EMAIL_PER_HOURЗапити листа скидання пароля на один email3
AUTH_RESEND_VERIFICATION_MAX_PER_USER_PER_HOURПовторні листи підтвердження email на користувача3
AUTH_LOGIN_UNVERIFIED_RESEND_INTERVAL_MSІнтервал, не частіше за який лист підтвердження надсилається повторно після входу в непідтверджений акаунт (мс)300000
AUTH_RESET_PASSWORD_MAX_ATTEMPTS_PER_IP_PER_HOURСпроби скидання пароля за токеном з одного IP20
AUTH_VERIFY_EMAIL_MAX_ATTEMPTS_PER_IP_PER_HOURСпроби підтвердження email за токеном з одного IP20

Наявні AUTH_SMS_*, AUTH_EMAIL_REGISTER_* і AUTH_EMAIL_LINK_* (розділ «Автентифікація: email і телефон» нижче) теж потрапляють у реєстр і з тією самою валідацією.

Сесія і cookies ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
SESSION_COOKIE_HOST_PREFIXCookie __Host-uapi замість uapiзначення isProductionLikeНі; якщо увімкнено, cookie має бути secure (APP_ENV ≠ local), а APP_URL має бути https://, інакше throwsession.ts
SESSION_ANON_TTLСтрок дії анонімної сесії (cookie і запис anon_session у Redis), ковзний; формат metautil duration: 2h, 30m2hНі; не додатна тривалість — throw на стартіsession.ts
SESSION_TOKEN_CHECK_TIMEOUT_MSДедлайн читання users.session_token на кожен автентифікований запит (Відкликання сесій). Це statement_timeout окремого пулу з 5 зʼєднань (сервер скасовує запит) і межа очікування зʼєднання; цей самий пул обмежує періодичну перевірку ролей WS-адмінів (Відкликання admin-доступу); пул додається до основного (10), тож у max_connections має бути запас; цілі мс2000Ні; не ціле число або поза 1…60000 — throw на стартіsession.ts

Строк життя сесії (24 год), httpOnly, sameSite: 'Lax' і maxAge cookie (3600) задані в коді й через env не змінюються.

Автентифікація: email і телефон ​

Числові значення розбираються через Number(). Значення, що не є скінченним числом, замінюється на default.

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
AUTH_STRICT_REGISTRATIONСтрогий режим реєстраціїtrueНіauth.ts
AUTH_PHONE_ENABLEDВмикає вхід за телефономfalseНіauth.ts
AUTH_OTP_HMAC_KEYКлюч HMAC для OTPнемає, fallback на APP_KEYТак, якщо AUTH_PHONE_ENABLED=true і APP_KEY порожній: потрібно ≥ 32 символи, інакше throwauth.ts
AUTH_SMS_PROVIDERSMS-провайдерunsupportedНі; значення fake має додаткові умови (дивіться нижче)auth.ts
AUTH_SMS_PROVIDER_ALLOW_FAKEДозволяє провайдер fakefalseТак (true), якщо AUTH_SMS_PROVIDER=fake, інакше throwauth.ts
AUTH_FAKE_SMS_CODEКод, який повертає fake-провайдер123456Так (непорожній), якщо AUTH_SMS_PROVIDER=fake, інакше throwauth.ts
AUTH_SMS_CHALLENGE_TTL_SECONDSСтрок дії SMS-челенджу600Ніauth.ts
AUTH_SMS_RESEND_COOLDOWN_SECONDSПауза перед повторною відправкою SMS60Ніauth.ts
AUTH_SMS_MAX_INVALID_ATTEMPTSЛіміт невдалих спроб введення коду5Ніauth.ts
AUTH_SMS_MAX_CONFIRM_ATTEMPTS_PER_IP_PER_HOURЛіміт підтверджень з одного IP за годину20Ніauth.ts
AUTH_SMS_MAX_SENDS_PER_PHONE_PER_HOURЛіміт SMS на номер за годину3Ніauth.ts
AUTH_SMS_MAX_SENDS_PER_IP_PER_HOURЛіміт SMS з одного IP за годину10Ніauth.ts
AUTH_EMAIL_REGISTER_MAX_ATTEMPTS_PER_EMAIL_PER_HOURЛіміт реєстрацій на email за годину3Ніauth.ts
AUTH_EMAIL_REGISTER_MAX_ATTEMPTS_PER_IP_PER_HOURЛіміт реєстрацій з одного IP за годину10Ніauth.ts
AUTH_EMAIL_LINK_MAX_ATTEMPTS_PER_TARGET_PER_HOURЛіміт email-посилань на адресу за годину3Ніauth.ts
AUTH_EMAIL_LINK_MAX_ATTEMPTS_PER_USER_PER_HOURЛіміт email-посилань на користувача за годину3Ніauth.ts
AUTH_EMAIL_LINK_COOLDOWN_SECONDSПауза між email-посиланнями60Ніauth.ts

Окрім умов у таблиці, AUTH_SMS_PROVIDER=fake у production-like режимі призводить до throw на старті навіть тоді, коли інші умови виконано.

OAuth ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
GOOGLE_CLIENT_IDClient ID Google""Ні (потрібна для Google OAuth)oauth.ts
GOOGLE_CLIENT_SECRETClient secret Google""Ні (потрібна для Google OAuth)oauth.ts
GOOGLE_REDIRECT_URIRedirect URI Google""Ні (потрібна для Google OAuth)oauth.ts
FACEBOOK_CLIENT_IDClient ID Facebook""Ні (потрібна для Facebook OAuth)oauth.ts
FACEBOOK_CLIENT_SECRETClient secret Facebook""Ні (потрібна для Facebook OAuth)oauth.ts
FACEBOOK_REDIRECT_URIRedirect URI Facebook""Ні (потрібна для Facebook OAuth)oauth.ts
GITHUB_CLIENT_IDClient ID GitHub""Ні (потрібна для GitHub OAuth)oauth.ts
GITHUB_CLIENT_SECRETClient secret GitHub""Ні (потрібна для GitHub OAuth)oauth.ts
GITHUB_REDIRECT_URIRedirect URI GitHub""Ні (потрібна для GitHub OAuth)oauth.ts
GITLAB_CLIENT_IDClient ID GitLab""Ні (потрібна для GitLab OAuth)oauth.ts
GITLAB_CLIENT_SECRETClient secret GitLab""Ні (потрібна для GitLab OAuth)oauth.ts
GITLAB_REDIRECT_URIRedirect URI GitLab""Ні (потрібна для GitLab OAuth)oauth.ts
OAUTH_FRONTEND_SUCCESS_URLКуди перенаправити після успішного входу/?oauth=successНіoauth.ts
OAUTH_FRONTEND_ERROR_URLКуди перенаправити після помилки/?error=oauth_failedНіoauth.ts

База даних ​

Порожнє значення вважається незаданим. Докладніше див. на сторінці База даних.

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
DB_CONNECTIONТип клієнта БДpgНіdatabase.ts
PGSQL_HOSTХост PostgreSQL127.0.0.1Ніdatabase.ts
PGSQL_PORTПорт PostgreSQL5432; не ціле число з 1–65535 — throw на стартіНіdatabase.ts
PGSQL_USERКористувач БДpostgresНіdatabase.ts
PGSQL_PASSWORDПароль БД""Залежить від сервера БДdatabase.ts
PGSQL_SSLШифрування з'єднання з PostgreSQL: false, true (TLS з перевіркою сертифіката) або require (TLS без перевірки). Інше значення — throw на старті; у production-like з false — попередженняfalseНіdatabase.ts
PGSQL_DB_NAMEНазва базиvibe_templateНіdatabase.ts

Seed ​

Читає лише db:seed --demo (run-seed.ts); застосунок ці змінні не використовує. Якщо email або пароль порожні, відповідний акаунт пропускається (missing_credentials). Див. База даних → Seed.

ЗміннаПризначенняDefaultОбов'язковість (умова)
SEED_ADMIN_EMAILEmail demo-адміна—Ні (лише для --demo)
SEED_ADMIN_PASSWORDПароль demo-адміна—Ні (лише для --demo)
SEED_USER_EMAILEmail звичайного demo-користувача—Ні (опційно)
SEED_USER_PASSWORDПароль звичайного demo-користувача—Ні (опційно)

Redis ​

Для REDIS_HOST, REDIS_PORT, REDIS_PASSWORD і REDIS_PREFIX використовується ||, тому порожній рядок теж замінюється на default. REDIS_PORT (1…65535), REDIS_COMMAND_TIMEOUT_MS і REDIS_LOGOUT_ALL_DEADLINE_MS (цілі >= 1) читаються за контрактом цілих: порожній рядок дає default, інше недійсне значення — помилка старту Invalid Redis configuration: ... з validateRuntimeConfig. Як основний клієнт використовує ці значення — Відмова Redis.

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
REDIS_HOSTХост Redis127.0.0.1Ніredis.ts
REDIS_PORTПорт Redis6379Ніredis.ts
REDIS_PASSWORDПароль RedisnullНіredis.ts
REDIS_PREFIXПрефікс ключів (до 16 символів)uwebsocket:Ніredis.ts
REDIS_COMMAND_TIMEOUT_MSТаймаут команди основного клієнта (сесії, WS-токени), мс500Ніredis.ts
REDIS_LOGOUT_ALL_DEADLINE_MSДедлайн усього циклу SCAN/DEL у logoutAll, мс2000Ніredis.ts

Сховище S3 ​

Жодна змінна з цієї групи не має default (undefined). Усі вони потрібні для роботи з файлами в S3.

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
S3_REGIONРегіоннемаєДля S3disk.ts
S3_ACCESS_KEY_IDAccess keyнемаєДля S3disk.ts
S3_SECRET_ACCESS_KEYSecret keyнемаєДля S3disk.ts
S3_ENDPOINTEndpoint S3-сумісного сховищанемаєДля S3disk.ts
S3_BUCKETBucketнемаєДля S3disk.ts
S3_PREFIXЗагальний префікс ключівнемаєНіdisk.ts
S3_STATIC_DATA_PREFIXПрефікс статичних данихнемаєНіdisk.ts
S3_DYNAMIC_DATA_PREFIXПрефікс динамічних данихнемаєНіdisk.ts

Пошта (SMTP) ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
SMTP_ENABLEDВмикає надсилання поштиfalseНіmail.ts
SMTP_HOSTSMTP-хост""Так, якщо SMTP_ENABLED=truemail.ts
SMTP_PORTSMTP-порт587Ніmail.ts
SMTP_SECUREПряме TLS-з'єднанняfalseНіmail.ts
SMTP_REQUIRE_TLSВимагати STARTTLStrueНіmail.ts
SMTP_IGNORE_TLSНе використовувати STARTTLSfalseНіmail.ts
SMTP_USERЛогін SMTP""Залежить від сервераmail.ts
SMTP_PASSWORDПароль SMTP""Залежить від сервераmail.ts
SMTP_FROM_EMAILАдреса відправника""Так, якщо SMTP_ENABLED=truemail.ts
SMTP_FROM_NAMEІм'я відправника""Ніmail.ts
SMTP_REPLY_TOАдреса Reply-To""Ніmail.ts

Push-сповіщення (Web Push) ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
VAPID_PUBLIC_KEYПублічний VAPID-ключ""Для pushpush.ts
VAPID_PRIVATE_KEYПриватний VAPID-ключ""Для pushpush.ts
VAPID_SUBJECTVAPID subjectmailto:admin@vibe-template.exampleНіpush.ts

AI ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
LOG_LEVELРівень логів pino: fatal, error, warn, info, debug, trace, silent; інше значення зупиняє стартinfoНіlogging.ts
RESPONSE_VALIDATION_CONTRACTРеакція на порушення контракту відповіді (ResponseSchema): strict або log, див. Перевірка відповідей; інше значення зупиняє стартstrict, у production logНіresponse-validation.ts
READINESS_CHECK_TIMEOUT_MSТаймаут кожної перевірки GET /ready (PostgreSQL, Redis), мс, 50–300001000Ніhealth.ts
AI_TEXT_DRIVERТекстовий AI-драйвер: openai, xai або mistral; інше значення зупиняє стартopenaiНіai.ts
AI_REQUEST_TIMEOUT_MSЛіміт на один виклик AI-провайдера (мс, ціле ≥ 1000); перевищення → 504 upstream_timeout60000Ніai.ts
AI_SUPPORT_DAILY_TOKEN_BUDGETТокенів на користувача на добу UTC для чату підтримки (Допуск повідомлення, ADR 0003); понад — відповідь 429 support_budget_exceeded. 0 вимикає облік200000Ні; не невід'ємне ціле — помилка конфігурації; 0 у production-like — помилка стартуai.ts
AI_SUPPORT_PROMPT_ALLOWANCE_TOKENSЗапас у резерві відповіді на системний промпт, контекст бази знань та історію, розмір яких невідомий на допуску8000Ні; не невід'ємне ціле — помилка конфігураціїai.ts
AI_USAGE_STORE_PROMPTSЧи зберігати текст промпту в llm_text_usage.final_prompt (Що журнал зберігає від промпту). За замовчуванням — лише SHA-256 і довжинаfalseНі; не булеве значення за контрактом — помилка конфігураціїai.ts
AI_USAGE_PROMPT_RETENTION_DAYSСкільки днів тримати текст промпту, коли він зберігається; старіший очищає llm:purge-prompts30Ні; не ціле ≥ 1 — помилка конфігураціїai.ts
PROMPT_CACHE_TTL_MSTTL кешу промптів у процесі (мс, ≥ 1000); інші інстанси бачать оновлення промпту із цією затримкою60000Ніai.ts
SUPPORT_DEFAULT_LANGUAGEМова відповідей Support AI, коли клієнт не передав свою (код з APP_LOCALE_CODES)enНіsupport.ts
SUPPORT_EMBEDDING_BATCH_SIZEСтатей в одному запиті embeddings при переіндексації (1–2048)50Ніsupport.ts
SUPPORT_SEARCH_MAX_DISTANCEМаксимальна косинусна відстань статті до запиту (0–2], далі стаття не йде в контекст0.8Ніsupport.ts
OPENAI_API_KEYКлюч OpenAI (чат та embeddings)""Для драйвера openai та embeddingsai.ts
OPENAI_CHAT_MODELМодель чату OpenAIgpt-5.4-miniНіai.ts
OPENAI_CHAT_API_URLEndpoint chat completionshttps://api.openai.com/v1/chat/completionsНіai.ts
OPENAI_EMBEDDING_MODELМодель embeddingstext-embedding-3-smallНіai.ts
OPENAI_EMBEDDING_DIMENSIONSРозмірність embeddings; має дорівнювати розмірності колонки (1536), інакше старт зупиняється1536Ніai.ts
XAI_API_KEYКлюч xAI""Для драйвера xAIai.ts
XAI_CHAT_MODELМодель чату xAIgrok-4.3Ніai.ts
MISTRAL_API_KEYКлюч Mistral""Для драйвера Mistralai.ts
MISTRAL_TEXT_MODELТекстова модель Mistralmistral-medium-latestНіai.ts

Sentry і спостережуваність ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
SENTRY_DSNDSN Sentry; без нього Sentry вимкненонемаєДля Sentrysentry.ts
SENTRY_ENABLEDВимикач Sentry; працює лише разом з непорожнім DSNtrueНіsentry.ts
SENTRY_ENVIRONMENTНазва оточення в Sentryзначення APP_ENVНіsentry.ts
SENTRY_RELEASEРелізнемаєНіsentry.ts
SENTRY_TRACES_SAMPLE_RATEЧастка трасувань, від 0 до 10 (некоректне значення дає warning і 0)Ніsentry.ts

TURN (WebRTC) ​

ЗміннаПризначенняDefaultОбов'язковість (умова)Читає файл
TURN_SECRETСпільний секрет для тимчасових TURN-облікових даних (TTL 3600 с задано в коді)""Для TURNturn.ts
TURN_HOSTХост TURN-сервера""Для TURNturn.ts

Модуль support.ts містить лише системні промпти AI-підтримки й не читає змінних оточення.

Відповідність .env.example ​

packages/backend/.env.example містить усі змінні, які читає бекенд, крім NODE_ENV (запасне джерело для APP_ENV). Змінних, яких код не читає, у файлі немає.

  • TURN_SECRET і TURN_HOST читає config/turn.ts, але цей модуль поки ніхто не імпортує.
  • Назва CREDENTIONALS_CORS містить друкарську помилку, але саме так її читає код, тому змінювати її не можна.

Як запустити проєкт локально, див. на сторінці Початок роботи. Загальний огляд бекенда див. у розділі Backend.

Автор: Олександр Блажейко · blazheiko@gmail.com