# Конфигурация проекта cde-orchestration-demo (Оркестратор)

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

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

Сервис настраивается **только через переменные окружения**. Разбор выполняется библиотекой [`github.com/sethvargo/go-envconfig`](https://github.com/sethvargo/go-envconfig): в каждом бинарнике вызывается `envconfig.Process(ctx, config)` со своей структурой `Config` (см. `internal/app/http/config.go` и `internal/app/worker/*/config.go`).

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

- **Глобального префикса нет** — в отличие от других сервисов Sarex, переменные не имеют общего префикса (напр. просто `LOG_LEVEL`, `DATABASE_URL`).
- Вложенные секции задаются тегом `env:", prefix=XXX_"` на поле-структуре. Например поле `Database DatabaseConfig` с `prefix=DATABASE_` и полем `Url` с тегом `env:"URL"` даёт переменную `DATABASE_URL`.
- Структура `Auth` **не имеет** тега `prefix`, поэтому её поля читаются без префикса: `AUTH_HOST`, `USERNAME`, `PASSWORD`.
- Значения по умолчанию задаются в теге через `default=...`. Отсутствие поля без дефолта не приводит к ошибке `envconfig` (пустое значение), но может привести к падению при инициализации зависимого клиента (напр. пустой `PUBLIC_KEY` вызовет панику при старте http).

Файл `.env` подгружается через [`github.com/lpernett/godotenv`](https://github.com/lpernett/godotenv): в `main` вызывается `godotenv.Load(*envFileFlag)`, путь задаётся флагом `-env-file` (по умолчанию `.env`). Если файла нет — загрузка пропускается, переменные берутся из окружения процесса.

Отдельного конфиг-файла (yaml/toml) у приложения нет.

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

| Способ запуска | Откуда берутся переменные |
| --- | --- |
| Локально (бинарник) | Флаг `-env-file` → `.env` (godotenv) и/или переменные окружения процесса |
| Локально (docker-compose) | `docker-compose.yml`: у каждого сервиса `env_file: .env` |
| Kubernetes (Helm) | `.helm/values.yaml`: блок `envs` (обычные значения) и `secretEnvs` (значения из k8s-секрета `cde-secret`) чарта `universal-chart` |
| Kubernetes (kustomize, этот репозиторий) | Vault Agent инжектит секрет `secrets/data/vault/apps/cde` в файл `/vault/secrets/cde-env`, который экспортируется в окружение перед запуском бинарника (`source /vault/secrets/cde-env`) |

## Бинарники (точки входа)

| Бинарник | Точка входа | Config | Назначение |
| --- | --- | --- | --- |
| `http` | `cmd/http/main.go` | `internal/app/http` | HTTP API оркестрации (процессы, подпись, загрузка BPMN) |
| `copy` | `cmd/worker/copy/main.go` | `.../worker/copy` | Воркер копирования документов (`copyDocuments`) |
| `copyv2` | `cmd/worker/copyv2/main.go` | `.../worker/copyv2` | Копирование документов v2 (`copyDocumentsv2`) |
| `create_versions` | `cmd/worker/create_versions/main.go` | `.../worker/create_versions` | Создание версий (`createVersions`) |
| `create_versionsv2` | `cmd/worker/create_versionsv2/main.go` | `.../worker/create_versionsv2` | Создание версий v2 (`createVersionsv2`) |
| `flows_callback` | `cmd/worker/flows_callback/main.go` | `.../worker/flows_callback` | Обратный вызов в сервис flows (`flowsCallback`) |
| `markings` | `cmd/worker/markings/main.go` | `.../worker/markings` | Маркировка документов (`markDocuments`) |
| `markingsv2` | `cmd/worker/markingsv2/main.go` | `.../worker/markingsv2` | Маркировка v2 (`markDocumentsv2`) |
| `sign` | `cmd/worker/sign/main.go` | `.../worker/sign` | Подпись документов (`signDocuments`) |
| `signv2` | `cmd/worker/signv2/main.go` | `.../worker/signv2` | Подпись v2 (`signDocumentsv2`) |
| `split_pdf` | `cmd/worker/split_pdf/main.go` | `.../worker/split_pdf` | Разбиение/обработка PDF (`splitPDF`) |
| `update_bundles` | `cmd/worker/update_bundles/main.go` | `.../worker/update_bundles` | Обновление бандлов (`updateBundles`) |

Воркеры — это Zeebe job-workers: они подключаются к Zeebe-gateway и обрабатывают Service Task соответствующего типа (`ZEEBE_WORKER_JOB_TYPE`). HTTP-сервер, помимо приёма запросов, обращается к Camunda Operate/Zeebe (см. `ENDPOINTS.md`).

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

Дефолт `—` означает, что значения по умолчанию нет.

### Общие (для всех бинарников)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ENVIRONMENT` | string | `production` (у воркеров) | Окружение развёртывания. У `http` не читается |
| `LOG_LEVEL` | string | `info` (http) / `debug` (воркеры) | Уровень логирования |
| `IS_CONTOUR` | bool | `false` | Режим изолированного контура (влияет на инициализацию S3) |

### HTTP-сервер (`cmd/http`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ADDRESS` | string | `:8080` | Адрес прослушивания Fiber |
| `PROCESS_CACHE_TTL` | int (сек) | `60` | TTL кеша процессов |
| `PROCESS_CACHE_CLEAR_INTERVAL` | int (сек) | `60` | Интервал очистки кеша процессов |
| `PUBLIC_KEY` | string (PEM) | — | RSA public key для проверки JWT. Обязателен: при пустом/некорректном значении сервис падает при старте |
| `OPERATE_URL` | string | — | Базовый URL Camunda Operate/REST |
| `SAREX_BACKEND_BASE_URL` | string | — | Базовый URL sarex-backend (проверка MRPA при подписи) |

### Camunda (`CAMUNDA_*`)

| Переменная | Тип | Значение по умолчанию | Назначение | Где используется |
| --- | --- | --- | --- | --- |
| `CAMUNDA_KEYCLOAK_URL` | string | — | URL Keycloak для OAuth (Zeebe/Operate) | http + воркеры |
| `CAMUNDA_CLIENT_ID` | string | `operate` | Client ID для Operate | только http |
| `CAMUNDA_CLIENT_SECRET` | string | `identity-secret-for-components` | Client secret для Operate | только http |
| `CAMUNDA_PROCESS_DEFINITION_ID` | string | `actionsOnApproval` | ID определения процесса | только http |

### Zeebe (`ZEEBE_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ZEEBE_GATEWAY` | string | — | Адрес Zeebe gateway |
| `ZEEBE_CLIENT_ID` | string | `zeebe` | Client ID |
| `ZEEBE_CLIENT_SECRET` | string | `identity-secret-for-components` | Client secret |
| `ZEEBE_WORKER_JOB_TYPE` | string | зависит от воркера | Тип Service Task, который слушает воркер |

Значения `ZEEBE_WORKER_JOB_TYPE` по умолчанию: `markDocuments` (http/markings), `markDocumentsv2` (markingsv2), `copyDocuments` (copy), `copyDocumentsv2` (copyv2), `createVersions` (create_versions), `createVersionsv2` (create_versionsv2), `flowsCallback` (flows_callback), `signDocuments` (sign), `signDocumentsv2` (signv2), `splitPDF` (split_pdf), `updateBundles` (update_bundles).

### Database (`DATABASE_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `DATABASE_URL` | string | — | DSN подключения к PostgreSQL (pgx) |
| `DATABASE_POOL_SIZE` | int32 | `10` | Размер пула соединений |

### S3 (`S3_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `S3_ENDPOINT_URL` | string | `https://storage.yandexcloud.net` | Эндпоинт S3 |
| `S3_ACCESS_KEY_ID` | string | — | Access key |
| `S3_SECRET_ACCESS_KEY` | string | — | Secret key |
| `S3_PARTITION_ID` | string | `yc` | Partition ID (aws-sdk-go-v2) |
| `S3_SIGNING_REGION` | string | `ru-central1` | Регион для подписи запросов |

### Auth (без префикса)

Поле-структура `Auth` не имеет префикса, поэтому переменные читаются напрямую.

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `AUTH_HOST` | string | — | Хост сервиса аутентификации (получение токенов пользователя/админа) |
| `USERNAME` | string | — | Логин админ-учётки |
| `PASSWORD` | string | — | Пароль админ-учётки |

### Flows (`FLOWS_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `FLOWS_URL` | string | — | Базовый URL сервиса flows |
| `FLOWS_INTERNAL_URL` | string | — | Внутренний URL flows (обновление документов review). Есть только в конфигах `copy`/`copyv2` |

### Workspaces (`WORKSPACES_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `WORKSPACES_URL` | string | — | URL сервиса рабочих областей (используется воркерами copy/copyv2) |

### Workflows (`WORKFLOWS_*`)

Используется воркером `split_pdf`.

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `WORKFLOWS_HOST` | string | — | Хост сервиса workflows |
| `WORKFLOWS_IMAGE_TAG` | string | `latest` | Тег docker-образа задач обработки PDF |

> Container registry (`cr.yandex/crp3ccidau046kdj8g9q`) и флаг `UploadResultsToS3=true` заданы в коде воркера `split_pdf` (`worker.go`), а не через окружение.

### System log (`SYSTEM_LOG_*`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `SYSTEM_LOG_URL` | string | — | URL сервиса системных логов (copy, copyv2, create_versions, create_versionsv2) |

### Telegram (`TELEGRAM_*`)

Клиент алертинга для воркеров.

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `TELEGRAM_TOKEN` | string | — | Токен бота |
| `TELEGRAM_ALERT_GROUP_ID` | int64 | — | ID группы для алертов |
| `TELEGRAM_DEBUG` | bool | `false` | Debug-режим бота |

### AMQP / RabbitMQ (`AMQP_*`)

Используется воркерами `markingsv2` и `copyv2` (маркировка бандлов через RabbitMQ).

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `AMQP_HOST` | string | — | Хост RabbitMQ |
| `AMQP_PORT` | string | — | Порт RabbitMQ |
| `AMQP_USER` | string | — | Пользователь |
| `AMQP_PASSWORD` | string | — | Пароль |
| `AMQP_PATH_API` | string | — | Vhost / путь API в URL подключения |

## Матрица «переменная → бинарник»

| Секция | http | copy | copyv2 | create_versions | create_versionsv2 | flows_callback | markings | markingsv2 | sign | signv2 | split_pdf | update_bundles |
| --- | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| Общие | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `ADDRESS`/`PROCESS_CACHE_*` | ✓ | | | | | | | | | | | |
| `PUBLIC_KEY`,`OPERATE_URL`,`SAREX_BACKEND_BASE_URL`,`CAMUNDA_CLIENT_*`,`CAMUNDA_PROCESS_DEFINITION_ID` | ✓ | | | | | | | | | | | |
| `CAMUNDA_KEYCLOAK_URL`,`ZEEBE_*` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `DATABASE_*` | ✓ | ✓ | ✓ | ✓ | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ | |
| `S3_*` | ✓ | ✓ | ✓ | ✓ | ✓ | | | ✓ | ✓ | ✓ | | |
| `AUTH_*`/`USERNAME`/`PASSWORD` | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `FLOWS_URL` | | ✓ | ✓ | | | ✓ | ✓ | ✓ | ✓ | ✓ | | ✓ |
| `FLOWS_INTERNAL_URL` | | ✓ | ✓ | | | | | | | | | |
| `WORKSPACES_URL` | | ✓ | ✓ | | | | | | | | | |
| `WORKFLOWS_*` | | | | | | | | | | | ✓ | |
| `SYSTEM_LOG_URL` | | ✓ | ✓ | ✓ | ✓ | | | | | | | |
| `AMQP_*` | | | ✓ | | | | | ✓ | | | | |
| `TELEGRAM_*` | | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |

> Матрица построена по структурам `Config` соответствующих бинарников. Наличие поля в структуре не всегда означает, что клиент инициализируется — см. замечания ниже.

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

Обычные значения (блок `envs`):

| Переменная | Значения по окружениям |
| --- | --- |
| `SAREX_BACKEND_BASE_URL` | stage: `https://stage.sarex.io`, preprod: `https://preprod.sarex.io`, production: `https://lk.sarex.io` |

Значения из секрета (блок `secretEnvs`, общий для всех сервисов через якорь `*cde_secret_envs`), берутся из k8s-секрета `cde-secret` одноимёнными ключами: `ENVIRONMENT`, `LOG_LEVEL`, `ZEEBE_GATEWAY`, `DATABASE_URL`, `S3_ENDPOINT_URL`, `S3_ACCESS_KEY_ID`, `S3_SECRET_ACCESS_KEY`, `PUBLIC_KEY`, `PDM_URL`, `FLOWS_URL`, `FLOWS_INTERNAL_URL`, `USERNAME`, `PASSWORD`, `CAMUNDA_PROCESS_DEFINITION_ID`, `OPERATE_URL`, `CAMUNDA_KEYCLOAK_URL`, `CAMUNDA_CLIENT_ID`, `CAMUNDA_CLIENT_SECRET`, `WORKFLOWS_HOST`, `WORKSPACES_URL`, `AUTH_HOST`, `TELEGRAM_ALERT_GROUP_ID`, `TELEGRAM_TOKEN`, `IS_CONTOUR`, `AMQP_HOST`, `AMQP_PORT`, `AMQP_USER`, `AMQP_PASSWORD`, `AMQP_PATH_API`, `SYSTEM_LOG_URL`.

## Развёртывание через kustomize (этот репозиторий)

В `iac/apps/cde` секреты доставляются не через `secretEnvs` чарта, а через **Vault Agent Injector**: аннотации подов монтируют секрет `secrets/data/vault/apps/cde` в файл `/vault/secrets/cde-env`, который экспортируется перед запуском (`source /vault/secrets/cde-env`, затем `exec /http` или `/worker`). Дополнительно контейнерам задаётся `S3_IS_CONTOUR=true` (примечание: в коде используется переменная `IS_CONTOUR`).

Оверлеи: `base` (общие манифесты), `brusnika-stage`, `brusnika-prod`, `yc-k8s-test`.

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

- **Нет глобального префикса.** Имена переменных короткие (`USERNAME`, `PASSWORD`, `AUTH_HOST`) — легко пересечься с системными; следите за окружением процесса.
- **`PUBLIC_KEY` обязателен для `http`** — при пустом/некорректном PEM сервис паникует на старте (`server.go`).
- **`PDM_URL`** присутствует в `secretEnvs` Helm, но соответствующий клиент (`internal/adapters/http/pdm`) в текущей сборке нигде не инициализируется — переменная фактически не используется кодом.
- **`S3_IS_CONTOUR`** задаётся в kustomize-манифестах, тогда как код читает `IS_CONTOUR` (без префикса `S3_`). Проверьте, что для влияния на поведение выставлен именно `IS_CONTOUR`.
- **`FLOWS_INTERNAL_URL`** объявлен только в конфигах `copy`/`copyv2`; в остальных воркерах поля нет, хотя ключ есть в общем секрете.
- **Значения по умолчанию для секретов Camunda/Zeebe** (`identity-secret-for-components`) подходят для локального стенда, но должны переопределяться в prod.
- Приложение читает `.env` только если файл существует; иначе используются переменные окружения. `make`-целей для генерации `.env` в репозитории нет — используйте этот `.env.example` как шаблон.
