# Конфигурация проекта flows-backend

Документ описывает все переменные окружения и способы конфигурирования сервиса.

## Способы конфигурирования

Сервис настраивается **только через переменные окружения**. Разбор выполняется в `src/flow/config.py` через библиотеку [`pydantic-settings`](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) (класс `Settings` и набор вложенных классов `*Settings`).

Особенности разбора:

- у верхнеуровневого класса `Settings` **префикса нет** и не задан `env_nested_delimiter` — его собственные поля задаются переменными с именем поля в верхнем регистре (напр. `BASE_HOST`, `SERVICE_PORT`, `PROXY_PATH_PREFIX`);
- каждая вложенная секция — это **отдельный класс** `BaseSettings` со своим `env_prefix` (`class Config: env_prefix = "..."`), который читает переменные окружения независимо. Поэтому переменные «плоские» с префиксами: `PG_HOST`, `DJANGO_HOST`, `RABBITMQ_PORT`, `TRACING_USE` и т.д. — двойного подчёркивания для вложенности здесь нет;
- отсутствие обязательного поля без дефолта приводит к ошибке старта; большинство полей приложения имеют дефолты (см. таблицы ниже).

Отдельного конфиг-файла (yaml/toml) у приложения нет. Приложение **не загружает `.env` автоматически** (в `config.py` не задан `env_file`, зависимости `python-dotenv` нет) — переменные нужно экспортировать в окружение самому, напр. `set -a && . ./.env && set +a`.

Воркер (`src/worker`) использует **собственные** классы настроек (`src/worker/notifications_config.py`, `src/worker/sync_config.py`, `src/worker/celery.py`) с частично другими префиксами (`FLOWS_DB_`, `ISSUES_DB_`, `RFI_DB_`, `RESOURCES_`, `MAILGUN_`, `WORKFLOWS_NOTIFICATIONS_` и т.д.).

Источники переменных по способам запуска:

| Способ запуска | Откуда берутся переменные |
| --- | --- |
| Локально | Переменные окружения процесса. `.env.example` — шаблон; приложение его **не** загружает автоматически, экспортируйте вручную |
| Контейнер | `Dockerfile` / `Dockerfile.worker`; запуск через `entrypoint.sh` (сначала `alembic upgrade head`, затем gunicorn) |
| Kubernetes (Helm, репозиторий) | `.helm/values.yaml` (`universal-chart`): блоки `envs` (обычные значения) и `secretEnvs` (значения из k8s-секретов) для сервисов `backend`, `worker`, `scheduler` |
| Kubernetes (kustomize, infra) | `iac/apps/flows/base/*.yaml`: env в `backend-deployment.yaml` / `celery-deployment.yaml`; секреты инжектируются агентом **HashiCorp Vault** (`vault.hashicorp.com/agent-inject-*`) и подгружаются в окружение перед стартом |
| CI/CD (GitLab) | `.gitlab-ci.yml`: переменные пайплайна (`workflow.rules`), общий шаблон `generic/common-ci` (`universal-pipeline.yaml`) |

Способы запуска процессов:

| Процесс | Команда | Назначение |
| --- | --- | --- |
| HTTP API | `gunicorn ... flow.main:app` (`entrypoint.sh`) | Публичный и внутренний REST API (FastAPI) |
| Celery worker | `celery -A src.worker worker` | Обработчик фоновых задач (рассылки, синхронизация) |
| Celery beat (scheduler) | `celery -A src.worker beat -l INFO` | Периодические задачи (см. `beat_schedule` ниже) |
| Alembic | `alembic upgrade head` (в `entrypoint.sh`) | Миграции БД при старте контейнера |

Порядок запуска в контейнере (`entrypoint.sh`): миграции (`alembic upgrade head`), затем `gunicorn -w 3 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 --timeout $TIMEOUT ... flow.main:app`.

Периодические задачи воркера (`src/worker/celery.py`, `beat_schedule`):

| Задача | Расписание (UTC) | Назначение |
| --- | --- | --- |
| `sync_reviews` | `*/7` минут | Синхронизация review |
| `notify_users` | пн–пт, 06:00 | Рассылка уведомлений пользователям |
| `notify_admins_about_empty_steps` | пн–пт, 05:30 | Уведомление админов о пустых шагах |

## Переменные приложения (API)

Дефолт `—` означает, что значение обязательно (иначе ошибка старта).

### Общие (`Settings`, без префикса)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `SERVICE_NAME` | string | `review-service` | Имя сервиса |
| `SERVICE_HOST` | string | `0.0.0.0` | Адрес прослушивания (в кластере переопределяется внешним URL API) |
| `SERVICE_PORT` | int | `8000` | Порт |
| `PROXY_PATH_PREFIX` | string | `""` | Root path за реверс-прокси (в кластере `/flows`). Влияет на `root_path` FastAPI и на префикс админки |
| `API_PREFIX` | string | `/api/v1` | Префикс публичного API |
| `API_INTERNAL_PREFIX` | string | `/internal/v1` | Префикс внутреннего API |
| `BASE_HOST` | string | `https://lk.sarex.io` | Базовый внешний URL (для ссылок/писем) |
| `GATEWAY_URL` | string | `https://stage-api.sarex.io/gateway` | URL gateway (используется при `SYNC_RESOURCE_ID=1`) |
| `RESOURCE_URL` | string | `https://stage-api.sarex.io/resources` | URL сервиса ресурсов/IAM (используется при `SYNC_RESOURCE_ID=1`) |
| `REGISTRY` | string | `cr.yandex/crp3ccidau046kdj8g9q` | Реестр образов |
| `JWT_AUTH_ENABLE` | bool | `True` | Включить аутентификацию по JWT. `False` — все запросы идут от дефолтного пользователя (удобно локально) |
| `DEBUG` | bool | `False` | Режим отладки |
| `ENABLE_MAILINGS` | bool | `True` | Включить рассылки |
| `ENABLE_MAILGUN` | bool | `True` | Использовать Mailgun (иначе — SMTP) |
| `ENABLE_CELERY` | bool | `True` | Включить постановку задач в Celery |
| `ENABLE_EVENTS` | bool | `True` | Включить событийную шину |
| `ENABLE_ANALYTICS` | bool | `False` | Отправлять данные в аналитику |
| `SYNC_RESOURCE_ID` | bool | `False` | Определять `resource_id` через gateway/resources при создании review/документов |
| `SMTP_HOST` | string \| null | `None` | SMTP-хост (альтернатива Mailgun) |
| `SMTP_PORT` | int \| null | `None` | SMTP-порт |
| `FROM_EMAIL` | string \| null | `None` | Адрес отправителя писем |

### Logger (`LoggerSettings`, префикс `LOG_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `LOG_LEVEL` | string | `INFO` | Уровень логирования (`INFO`/`DEBUG`/…); JSON-формат вывода |
| `LOG_FORMAT` | string | JSON-шаблон | Формат строки лога |

### Auth

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `JWT_PUBLIC_KEY` | string | — | Публичный RSA-ключ для проверки подписи JWT. В кластере монтируется из секрета и экспортируется как `JWT_PUBLIC_KEY` перед стартом (см. `entrypoint`/Vault) |

> Аутентификация выполняется в `src/flow/middleware.py` (`TokenUserMiddleware`). При наличии заголовка `identity` полезная нагрузка берётся из Zitadel-токена (`urn:zitadel:iam:user:metadata`), иначе — из основного `Authorization: Bearer <jwt>`. Подпись проверяется публичным ключом. Пути `/docs/`, `/openapi.json/`, `/internal/` из проверки исключены.

### Database — основной PostgreSQL (`PostgresSettings`, префикс `PG_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `PG_HOST` | string | `""` | Хост PostgreSQL |
| `PG_PORT` | string | `6432` | Порт PostgreSQL (обычно pgbouncer) |
| `PG_LOGIN` | string | `""` | Пользователь БД |
| `PG_PASSWORD` | string | `""` | Пароль БД |
| `PG_DB` | string | `""` | Имя базы данных |

> Итоговый DSN собирается свойством `PostgresSettings.url`: `postgresql://{login}:{password}@{host}:{port}/{db}`.

### Documentation PG (`DocumentationDBSettings`, префикс `DOCUMENTATION_PG_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `DOCUMENTATION_PG_HOST` | string | `""` | Хост БД документаций |
| `DOCUMENTATION_PG_PORT` | string | `""` | Порт |
| `DOCUMENTATION_PG_USERNAME` | string | `""` | Пользователь |
| `DOCUMENTATION_PG_PASSWORD` | string | `""` | Пароль |
| `DOCUMENTATION_PG_DATABASE` | string | `""` | Имя базы |

### RabbitMQ (`RabbitSettings`, префикс `RABBITMQ_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `RABBITMQ_HOST` | string | `localhost` | Хост |
| `RABBITMQ_PORT` | string | `5672` | Порт |
| `RABBITMQ_USERNAME` | string | `flow` | Пользователь |
| `RABBITMQ_PASSWORD` | string | `flow` | Пароль |
| `RABBITMQ_VHOST` | string | `api` | Виртуальный хост (в кластере `flows`/`flow_preprod`/`flow_prod`) |

### Celery (`CelerySettings`, префикс `CELERY_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `CELERY_QUEUE` | string | `flow` | Очередь задач. Брокер — из `RABBITMQ_*` |

### HTTP-клиенты внешних сервисов

Каждый клиент — отдельный класс с полями `use`/`host`/`timeout` (и своим префиксом). Соединение создаётся httpx-клиентом.

| Секция / префикс | Переменные | Назначение |
| --- | --- | --- |
| Sarex backend (Django) — `DJANGO_` | `DJANGO_USE` (`True`), `DJANGO_HOST` (`http://localhost:8000/api`), `DJANGO_TIMEOUT` (`60`), `DJANGO_TOKEN` (base64 `login:password` для Basic-auth) | Основной backend Sarex |
| Documentations — `DOCUMENTATION_` | `DOCUMENTATION_USE` (`True`), `DOCUMENTATION_HOST`, `DOCUMENTATION_EXTERNAL_HOST`, `DOCUMENTATION_TIMEOUT` (`60`) | Сервис документаций (внутренний и внешний хост) |
| EAV — `EAV_` | `EAV_HOST` (`http://eav-service.eav-prod`), `EAV_TIMEOUT` (`60`) | Сервис EAV (атрибуты) |
| Planning / MSP — `PLANNING_` | `PLANNING_USE` (`True`), `PLANNING_HOST` (`https://api.sarex.io/api/pm/msp`), `PLANNING_TIMEOUT` (`60`) | Планирование |
| Checklists — `CHECKLIST_` | `CHECKLIST_USE` (`True`), `CHECKLIST_HOST`, `CHECKLIST_TIMEOUT` (`60`) | Сервис чек-листов |
| Workflows — `WORKFLOWS_` | `WORKFLOWS_USE` (`True`), `WORKFLOWS_HOST` (`https://lk.sarex.io/workflows/api/v1`), `WORKFLOWS_TIMEOUT` (`60`) | Сервис workflows |

### Event bus (`EventBusSettings`, префикс `EVENTS_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `EVENTS_HOST` | string | `ws://localhost:8000/ws` | Адрес WebSocket событийной шины |
| `EVENTS_CONNECTION_TIMEOUT` | int | `5` | Таймаут подключения (сек) |
| `EVENTS_COUNT_RETRIES` | int | `100` | Число попыток переподключения |

### Admin panel (`AdminPanelSettings`, префикс `ADMIN_PANEL_`)

Админка (`sqladmin`) монтируется по пути `/api/admin/` (с учётом `PROXY_PATH_PREFIX`).

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ADMIN_PANEL_SECRET_KEY` | string | `hex` | Секретный ключ сессии админки |
| `ADMIN_PANEL_TOKEN_MAX_AGE` | int | `86400` | Время жизни токена (сек) |

### Sentry (`SentrySettings`, префикс `SENTRY_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `SENTRY_DSN` | string | `""` | DSN Sentry |
| `SENTRY_ENVIRONMENT` | string | `production` | Окружение |
| `SENTRY_TRACES_SAMPLE_RATE` | float | `1.0` | Доля трейсов |
| `SENTRY_SEND_DEFAULT_PII` | bool | `True` | Отправлять PII |

### OpenTelemetry / трейсинг (`TraceSettings`, префикс `TRACING_`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TRACING_USE` | bool | `False` | Включить трейсинг (при `True` инициализируется OTLP + middleware) |
| `TRACING_HOST` | string | `localhost:4317` | Адрес OTLP-коллектора |
| `TRACING_INSECURE` | bool | `False` | Подключение без TLS |
| `TRACING_SERVICE_NAME` | string | `flows` | Имя сервиса в трейсах |
| `TRACING_ENVIRONMENT` | string | `prod` | Окружение (`stage`/`preprod`/`prod`) |
| `TRACING_MODULE` | string | `flows` | Атрибут `module` |
| `TRACING_TEAM` | string | `team_proc` | Атрибут `team` |
| `TRACING_COMPONENT` | string | `backend` | Атрибут `component` |

## Переменные только для воркера и scheduler

Читаются классами из `src/worker/*`, а не основным приложением.

### Базы данных воркера

| Секция / префикс | Переменные | Назначение |
| --- | --- | --- |
| Flows DB — `FLOWS_DB_` | `FLOWS_DB_HOST`, `FLOWS_DB_PORT`, `FLOWS_DB_DB`, `FLOWS_DB_USERNAME`, `FLOWS_DB_PASSWORD` | БД flows (для задач синхронизации/рассылок) |
| Issues DB — `ISSUES_DB_` | `ISSUES_DB_HOST`, `ISSUES_DB_PORT`, `ISSUES_DB_DB`, `ISSUES_DB_USERNAME`, `ISSUES_DB_PASSWORD` | БД issues |
| RFI DB — `RFI_DB_` | `RFI_DB_HOST`, `RFI_DB_PORT`, `RFI_DB_DB`, `RFI_DB_USERNAME`, `RFI_DB_PASSWORD` | БД RFI |

Все пять полей каждой БД обязательны (без дефолтов).

### Клиенты и рассылки воркера

| Секция / префикс | Переменные | Назначение |
| --- | --- | --- |
| Django-клиент — `DJANGO_` | `DJANGO_BASE_HOST`, `DJANGO_HOST`, `DJANGO_AUTH` (Basic-auth) | Получение пользователей/токенов |
| Resources-клиент — `RESOURCES_` | `RESOURCES_HOST` | Пользователи, сгруппированные по ресурсам |
| Flows-клиент — `FLOWS_` | `FLOWS_HOST` | Внутренние вызовы flows API (`switch_to_next_step`) |
| Глобальные настройки рассылок — `NOTIFICATION_SETTINGS_` | `NOTIFICATION_SETTINGS_ENABLE_MAILINGS` (`True`), `NOTIFICATION_SETTINGS_USE_MAILGUN` (`True`) | Флаги рассылок |
| Mailgun — `MAILGUN_` | `MAILGUN_HOST`, `MAILGUN_API_KEY`, `MAILGUN_SENT_FROM` (`hello@sarex.io`) | Отправка писем через Mailgun |
| Workflows — `WORKFLOWS_` | `WORKFLOWS_HOST`, `WORKFLOWS_TIMEOUT` (`60`) | Постановка job в workflows |
| Уведомления через Workflows — `WORKFLOWS_NOTIFICATIONS_` | `WORKFLOWS_NOTIFICATIONS_TAG` (`email`), `WORKFLOWS_NOTIFICATIONS_REGISTRY`, `WORKFLOWS_NOTIFICATIONS_SMTP_HOST`, `WORKFLOWS_NOTIFICATIONS_SMTP_PORT`, `WORKFLOWS_NOTIFICATIONS_FROM_EMAIL` | Параметры job-рассылки |

## Переменные инфраструктуры, сборки и деплоя

Не читаются кодом приложения, но участвуют в запуске/сборке/деплое.

| Переменная | Где используется | Назначение |
| --- | --- | --- |
| `TIMEOUT` | `entrypoint.sh` | Таймаут gunicorn-воркеров (сек), напр. `120` (stage) / `900` (prod) |
| `ENABLE_METRICS` | `.helm/values.yaml` | Флаг метрик (`0`/`1`), кодом не читается |
| `PIP_INDEX_URL` / `--extra-index-url` | `requirements.txt` | Приватный индекс пакетов Nexus (`fastapi-otel-tools`) |
| `SERVICE_HOST` (в кластере) | `.helm/values.yaml`, kustomize | В кластере в `SERVICE_HOST` кладётся внешний URL API (`https://api.sarex.io/flows/api/v1`), переопределяя дефолт `0.0.0.0` |
| `SAREX_MAILER_HOST` | `.helm/values.yaml` | Хост mailer-сервиса |

## Переменные из Helm-чарта (`.helm/values.yaml`)

Чарт `universal-chart` описывает три сервиса — `backend`, `worker`, `scheduler`. Обычные значения задаются в блоке `envs` (с ключами по окружениям `_default`/`stage`/`preprod`/`production`), значения из секретов — в блоке `secretEnvs` (монтируются как env через `secretKeyRef`).

Значения из секретов (backend):

| Переменная | Секрет (`secretName`) | Ключ (`secretKey`) |
| --- | --- | --- |
| `PG_DB` | `postgres-secret` / `flows-postgresql-secret` | `database` |
| `PG_LOGIN` | `postgres-secret` / `flows-postgresql-secret` | `username` |
| `PG_PASSWORD` | `postgres-secret` / `flows-postgresql-secret` | `password` |
| `PG_HOST` | `postgres-secret` / `flows-postgresql-secret` | `host` |
| `SENTRY_DSN` | `sentry-secret` | `dsn` |
| `SENTRY_ENVIRONMENT` | `sentry-secret` | `env` |
| `DJANGO_TOKEN` | `django-secret` | `token` |
| `RABBITMQ_USERNAME` | `rabbitmq-secret` / `flows-rabbitmq-secret` | `username` |
| `RABBITMQ_PASSWORD` | `rabbitmq-secret` / `flows-rabbitmq-secret` | `password` |
| `ADMIN_PANEL_SECRET_KEY` | `admin-secret` | `key` |
| `JWT_PUBLIC_KEY` | `jwt-secret` | `public_key` |
| `DOCUMENTATION_PG_*` | `documentations-postgresql-secret` / `documentations-postgres-secret` | `database`/`host`/`port`/`username`/`password` |

Воркер дополнительно получает секреты `FLOWS_DB_*`, `ISSUES_DB_*`, `RFI_DB_*` (из соответствующих postgres-секретов), `DJANGO_AUTH` (`django-secret.token`), `MAILGUN_API_KEY` (`mailgun-secret.api-key`).

Чарт также монтирует CA-сертификат PostgreSQL (`pg-cert` → `/root/.postgresql/root.crt`).

## Переменные из kustomize-манифестов (`iac/apps/flows`)

Инфраструктурный репозиторий разворачивает те же образы через kustomize (`base` + оверлеи `brusnika-stage`, `brusnika-prod`, `yc-k8s-test`). Секреты инжектируются агентом **HashiCorp Vault** (аннотации `vault.hashicorp.com/agent-inject-*`) и подгружаются в окружение из файлов `/vault/secrets/*` перед запуском `entrypoint.sh`:

| Секрет Vault | Переменные |
| --- | --- |
| `secrets/data/postgresql/apps/flows` | `PG_DB`, `PG_LOGIN`, `PG_HOST`, `PG_PORT`, `PG_PASSWORD`, `DOCUMENTATION_PG_*` |
| `secrets/data/rabbitmq/apps/flows` | `RABBITMQ_USERNAME`, `RABBITMQ_PASSWORD`, `RABBITMQ_VHOST`, `RABBITMQ_HOST`, `RABBITMQ_PORT` |
| `secrets/data/vault/common/django_auth` | `DJANGO_TOKEN` |
| `secrets/data/vault/common/rsa_keys` | `JWT_PUBLIC_KEY` (public_key) |

Остальные значения (`LOG_LEVEL`, `BASE_HOST`, `DJANGO_HOST`, `DOCUMENTATION_HOST`, `EAV_HOST`, `GATEWAY_URL`, `RESOURCE_URL`, `SERVICE_HOST`, `WORKFLOWS_HOST`, `CHECKLIST_HOST`, `SMTP_HOST`/`SMTP_PORT`, `FROM_EMAIL`, `ENABLE_*`, `SYNC_RESOURCE_ID`, `TIMEOUT` и т.д.) задаются напрямую в блоке `env` deployment-манифеста оверлея.

## Переменные в CI (`.gitlab-ci.yml`)

Пайплайн подключает общие шаблоны из `generic/common-ci` (`common-security-scan.yaml`, `universal-pipeline.yaml`) и переключает окружение по ветке/тегу через `workflow.rules`:

| Условие | STAND | Namespace | CHART_VERSION |
| --- | --- | --- | --- |
| ветка `stage` | `stage` | `proc` | `0.0.1-stage` |
| ветка `master` | `preprod` | `flows-preprod` | `0.0.1-preprod` |
| тег (`CI_COMMIT_TAG`) | `production` | `flows-prod` | `0.0.1-prod` |

Ключевые переменные пайплайна: `SERVICE_NAME=flows-backend`, `DOCKERFILE_PATH=Dockerfile`, `IMAGE_NAME_WORKER` (образ воркера, собирается job-ом `build_worker` из `Dockerfile.worker`), `HELM_SET_ARGS` (проброс образов backend/worker/scheduler и метаданных коммита в чарт).

## Замечания и потенциальные проблемы

- Приложение **не загружает `.env` автоматически** — переменные нужно экспортировать в окружение (см. `.env.example`).
- У `Settings` нет `env_nested_delimiter`, поэтому вложенные секции конфигурируются **плоскими** переменными со своими префиксами (`PG_`, `DJANGO_`, `RABBITMQ_`, …), а не через `__`.
- Поле `service_host` (дефолт `0.0.0.0`) и переменная `SERVICE_HOST` совпадают по имени: в кластере в `SERVICE_HOST` кладётся внешний URL API, что переопределяет адрес прослушивания в объекте настроек. Реальный адрес/порт прослушивания при запуске в контейнере задаёт gunicorn (`-b 0.0.0.0:8000` в `entrypoint.sh`), а не поле настроек.
- Почта: при `ENABLE_MAILGUN=1` используется Mailgun (`MAILGUN_*` — в основном на стороне воркера), иначе — SMTP (`SMTP_HOST`/`SMTP_PORT`/`FROM_EMAIL`).
- Healthcheck-эндпоинта у сервиса нет; в чарте probes (`liveness`/`readiness`) отключены.
- Воркер использует отдельные классы настроек (pydantic v1 стиль `class Config`), у которых поля БД **обязательны** — при запуске воркера без `FLOWS_DB_*`/`ISSUES_DB_*`/`RFI_DB_*` будет ошибка.

## Минимальный набор для локального запуска

Минимально необходимо задать:

- `SERVICE_PORT` (по умолчанию `8000`), `PROXY_PATH_PREFIX` (пусто локально)
- `JWT_AUTH_ENABLE=False` (чтобы не требовался `JWT_PUBLIC_KEY`) — иначе задайте `JWT_PUBLIC_KEY`
- `PG_HOST`, `PG_PORT`, `PG_LOGIN`, `PG_PASSWORD`, `PG_DB`
- `RABBITMQ_HOST`, `RABBITMQ_PORT`, `RABBITMQ_USERNAME`, `RABBITMQ_PASSWORD`, `RABBITMQ_VHOST` (если `ENABLE_CELERY=1`/`ENABLE_EVENTS=1`)
- хосты внешних сервисов, которые реально используются: `DJANGO_HOST`, `DOCUMENTATION_HOST`, `EAV_HOST`, `CHECKLIST_HOST`, `WORKFLOWS_HOST`, `PLANNING_HOST`
- при `SYNC_RESOURCE_ID=1` — `GATEWAY_URL`, `RESOURCE_URL`
- `TRACING_USE=False` (иначе — `TRACING_HOST`, `TRACING_SERVICE_NAME`)
- для воркера — `FLOWS_DB_*`, `ISSUES_DB_*`, `RFI_DB_*`, `MAILGUN_*` или SMTP

Готовые значения-примеры для всех переменных приведены в `.env.example`.
