# Конфигурация проекта documentations-api-v2

Документ описывает все переменные окружения и способы конфигурирования сервиса **documentation-api-v2** (`pdm/documentation-api-v2`) — Go-сервис домена «documentations» (v2), отвечающий за диски, документы, бандлы, data source, страницы, публичные ссылки, workflow-обработку и подписи.

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

Сервис настраивается **только через переменные окружения**. Разбор выполняется в `config/config.go` через библиотеку [`github.com/kelseyhightower/envconfig`](https://github.com/kelseyhightower/envconfig) (функция `config.New()` → `envconfig.Process("", cfg)`).

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

- **Префикса нет** — переменные читаются под своими именами (напр. `API_ADDRESS`, `POSTGRES_ADDRESS`), имя задаётся тегом `envconfig:"..."`.
- **Вложенность не используется** — конфиг плоский. Параметры БД вынесены в встроенную структуру `gopg.Config` (`pkg/postgres/gopg/postgres.go`), но остаются на верхнем уровне переменных.
- **Дефолты** заданы тегом `default:"..."` только у части полей (см. таблицы). Поле без дефолта, которое не передали, получает нулевое значение Go (`""`, `0`, `false`) — жёсткой валидации «обязательности» у envconfig в этом коде нет, сервис стартует и с пустыми значениями.
- Переменная БД-сертификата имеет имя с дефисами `YC-PG-CERTIFICATE` (тег `envconfig:"YC-PG-CERTIFICATE"`).

Отдельного конфиг-файла (yaml/toml) у приложения нет. Единственный внешний файл — JSON-описание workflow-задач (`WORKFLOWS_CONFIG_FILEPATH`), разбираемый отдельно в `config/workflows.go` (`NewTasksExecutionConfigFromFilepath`); при ошибке чтения/парсинга сервис **паникует**.

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

| Способ запуска | Откуда берутся переменные |
| --- | --- |
| Локально (бинарник) | Переменные окружения процесса. `.env.template` — только шаблон; приложение **не загружает `.env` автоматически** (в коде нет dotenv) |
| Локально (docker-compose) | `make docker-compose` → `.docker/docker-compose.yml` с `env_file: .docker/.docker.env` |
| Kubernetes (Helm) | `.helm/values.yaml`, чарт-зависимость `universal-chart`: блоки `envs` (обычные значения) и `secretEnvs` (из k8s-секретов) сервиса `api` |
| CI/CD (GitLab) | `.gitlab-ci.yml`: переменные пайплайна (`workflow.rules`) — переключение окружения/namespace, `HELM_SET_ARGS` |

Способы запуска процессов (`cmd/`):

| Бинарник | Точка входа | Назначение |
| --- | --- | --- |
| `api_server` | `cmd/api_server/main.go` | Основной HTTP API (Fiber). Точка входа контейнера (`CMD ["./api_server"]`) |
| `migrate` (`migrations`) | `cmd/migrate/main.go` | Миграции БД (`go-pg-migrations`): `migrate` / `rollback`. Собирается как `./migrations` |
| `filestream_server` | `cmd/filestream_server/main.go` | Отдельный сервер потоковой отдачи файлов (в основном Dockerfile **не собирается**) |

Сборка образа (`.docker/api.Dockerfile`, тег `-tags migrate`) кладёт `api_server`, `migrations` и `.example.tasks_execution_config.json`. Миграции применяются автоматически при старте приложения (см. README), либо вручную через бинарник `migrations`.

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

Дефолт `—` означает, что значение в коде по умолчанию не задано (используется нулевое значение Go, если переменную не передать).

### App / окружение

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `APP_NAME` | string | `documentations-backend` | Имя приложения (Sentry `ServerName`) |
| `APP_VERSION` | string | `v1` | Версия (Sentry `Release`) |
| `ENVIRONMENT` | string | — | Окружение: `stage`/`preprod`/`production` (Sentry `Environment`) |
| `NAMESPACE` | string | — | k8s namespace, используется в логике дисков |

### HTTP-сервер

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `API_ADDRESS` | string | — | Адрес прослушивания Fiber. Читается **обоими** бинарниками (`api_server` и `filestream_server`) |

> `api_server` устанавливает большой `BodyLimit` (5 ТБ) и `ReadBufferSize` 96×4096; `filestream_server` — `BodyLimit` 64 МБ. Оба отдают `GET /ping` для проб k8s; `api_server` дополнительно отдаёт `GET /swagger/*`.

### Database (`gopg.Config`, `pkg/postgres/gopg/postgres.go`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `POSTGRES_ADDRESS` | string | — | Хост PostgreSQL |
| `POSTGRES_PORT` | string | — | Порт PostgreSQL |
| `POSTGRES_USER` | string | — | Пользователь БД |
| `POSTGRES_DB` | string | — | Имя базы данных |
| `POSTGRES_PASSWORD` | string | — | Пароль пользователя БД |
| `POSTGRES_POOL_SIZE` | int | — | Размер пула соединений |
| `ENABLE_SSL` | bool | — | Подключение к БД по TLS (сертификат из `YC-PG-CERTIFICATE`) |
| `ENABLE_SQL_QUERY` | bool | — | Логирование SQL-запросов |
| `YC-PG-CERTIFICATE` | string (PEM) | — | CA-сертификат PostgreSQL. Обязателен при `ENABLE_SSL=1` |

### Аутентификация и публичные ссылки

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `PUBLIC_KEY` | string (PEM) | — | Публичный RSA-ключ (PKIX) для проверки JWT sarex-backend |
| `DOCUMENT_PUBLIC_LINK_JWT_SECRET` | string | — | HMAC-секрет JWT для публичных/временных ссылок на документы |
| `DOCUMENT_PUBLIC_LINK_JWT_EXPIRATION_MINUTES` | uint8 | — | TTL публичной ссылки, минуты |
| `PUBLIC_LINK_HOST` | string | — | Базовый хост генерируемых публичных ссылок |

### Django / IAM (`pkg/django`)

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `DJANGO_HOST` | string | — | Базовый URL Django/монолита (пользователи, компании, сервис-аккаунты) |
| `DJANGO_BASIC_AUTH` | string (base64) | — | Basic-auth `base64(login:password)` для Django и клиента flows |
| `DJANGO_ORIGINATOR` | string | — | Идентификатор источника (`docs_stage`/`docs_preprod`/`docs_prod`) |

### Внешние сервисы (базовые URL клиентов)

Каждый клиент (`pkg/clients/*`) создаётся с `SetBaseURL(<URL>)` и ретраями. Подробнее по путям — см. `api-v2.ENDPOINTS.md`.

| Переменная | Тип | Назначение |
| --- | --- | --- |
| `DOCUMENTATION_URL` | string | Self-URL сервиса, подставляется в workflow-задачи |
| `WORKFLOW_URL` | string | Сервис workflows (запуск обработки) |
| `WORKSPACE_URL` | string | Сервис workspaces |
| `WORKSPACE_V2_EXTERNAL_URL` | string | Внешний URL workspaces v2 |
| `WORKSPACE_BUNDLE_VERSION` | string | Версия бандла для интеграции с workspaces |
| `MARKS_PROCESSING_URL` | string | Сервис PDF-маркировок (marks) |
| `BIM_API_URL` | string | BIM API v1 |
| `BIM_API_V2_URL` | string | BIM API v2 (bim-core) |
| `BIM_API_URL_EXTERNAL` | string | Внешний URL BIM API |
| `SYSTEM_LOG_URL` | string | Сервис журналирования (system-log) |
| `FLOWS_URL` | string | Сервис flows |
| `FILE_URL_EXTERNAL` | string | Внешний URL для отдачи файлов |

### S3 / MinIO (`pkg/s3/minio`)

Клиент инициализируется только при `ENABLE_S3=1` (иначе `api_server` работает без S3).

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `ENABLE_S3` | bool | — | Включить инициализацию S3-клиента |
| `S3_SERVICE_ACCOUNT` | string | — | Путь к JSON сервис-аккаунта Yandex S3 |
| `S3_SERVICE_ACCOUNT_STR` | string | — | Альтернатива: JSON сервис-аккаунта строкой |

### BIM-логика

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `USE_BIMV1_FOR_BIMV2` | bool | — | Использовать BIM v1 API вместо v2 в пайплайне документов |
| `LAST_MASTER_BIM` | int | — | Граничный id для маршрутизации BIM master |
| `LAST_SLAVE_1_BIM` | int | — | Граничный id для маршрутизации BIM slave 1 |

### Кеш и файловый стример

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `READ_WRITE_TIMEOUT_FILE_STREAM` | duration | — | Таймаут чтения/записи файлового стримера (напр. `6h`) |
| `CACHE_DEFAULT_EXPIRATION` | duration | — | TTL кеша (напр. `60s`) |
| `CACHE_CLEANUP_INTERVAL` | duration | — | Интервал очистки кеша |
| `USE_CACHE_IN_FILE_STREAMER` | bool | — | Включить кеш в файловом стримере |

### Workflow-задачи

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `WORKFLOWS_CONFIG_FILEPATH` | string | `.example.tasks_execution_config.json` | Путь к JSON-описанию задач (`config/workflows.go`); при ошибке — паника |
| `WORKFLOWS_IMAGES_VERSION` | string | — | Тег образов задач (`develop`/`master`) |
| `CONTAINER_REGISTRY` | string | `cr.yandex/crp3ccidau046kdj8g9q` | Реестр образов задач |
| `IS_CONVERTED_PDF_UPLOADING_TO_S3` | bool | `true` | Загружать сконвертированный PDF в S3 |

### Наблюдаемость: Sentry и OpenTelemetry

| Переменная | Тип | Значение по умолчанию | Назначение |
| --- | --- | --- | --- |
| `SENTRY_DSN` | string | — | DSN Sentry |
| `SENTRY_DEBUG` | bool | — | Debug-режим Sentry |
| `ENABLE_OBSERVABILITY` | bool | — | Включить slog-хендлер observability и трассировку запросов БД |
| `OBSERVABILITY_COLLECTOR_ENDPOINT` | string | — | Endpoint OTLP-коллектора логов |
| `TRACER_USE` | bool | `false` | Включить OTEL-трейсинг Fiber |
| `TRACER_HOST` | string | `localhost:4317` | Адрес OTLP-коллектора трейсов |
| `TRACER_USE_INSECURE` | bool | `true` | Подключение к коллектору без TLS |
| `SERVICE_NAME` | string | `documentations-api-v2` | Имя сервиса в трейсах |
| `TRACER_LOGGER_NAME` | string | `tracer_logger` | Имя OTEL-логгера |

## Переменные инфраструктуры и сборки

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

| Переменная | Где используется | Назначение |
| --- | --- | --- |
| `API_FILESTREAM_ADDRESS` | `.env.template`, `.docker.env` | Присутствует в шаблонах, но **кодом не читается** (см. Замечания) |
| `POSTGRES_EXTERNAL_PORT` | `.docker/docker-compose.yml` | Внешний порт проброса контейнера Postgres |
| `API_VERSION` | `.docker/docker-compose.yml` | Тег образа `api` (по умолчанию `local`) |
| `GITLAB_CREDENTIALS` | `.docker/api.Dockerfile` (build-arg) | Доступ к приватному GitLab при `go build` |
| `CI_COMMIT_SHORT_SHA` | `.docker/api.Dockerfile` (build-arg), CI | Идентификатор сборки |

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

Чарт — обёртка над зависимостью `universal-chart` (`oci://.../charts`, версия `0.1.7`). Сервис `api`: `deployment` (реплики, ресурсы, пробы `GET /ping:8080`), `service` (ClusterIP `80 → 8080`), `image`, `volumes`.

Смонтированные тома:

- Секрет `documentations-yc-s3` → `/etc/sarex/yc-s3-storage` (на него указывает `S3_SERVICE_ACCOUNT`);
- ConfigMap `tasks-execution-config-documentation-v2` → `/etc/app/tasks_execution_config.json` (на него указывает `WORKFLOWS_CONFIG_FILEPATH` в k8s).

Обычные значения (`envs`) задают те же переменные `APP_NAME`, `API_ADDRESS` (`0.0.0.0:8080`), `ENVIRONMENT`, `NAMESPACE`, URL внешних сервисов, `ENABLE_SSL=1`, `ENABLE_S3=1`, флаги трассировки и т.п. — с разбивкой по окружениям (`_default`/`stage`/`preprod`/`production`).

Значения из секретов (`secretEnvs`, монтируются через `secretKeyRef`):

| Переменная | Секрет (`_default`) | Секрет (`preprod`) | Ключ |
| --- | --- | --- | --- |
| `POSTGRES_USER` | `documentations-postgresql-secret` | `ya-pg-secret` | `username` |
| `POSTGRES_ADDRESS` | `documentations-postgresql-secret` | `ya-pg-secret` | `host` |
| `POSTGRES_PORT` | `documentations-postgresql-secret` | `ya-pg-secret` | `port` |
| `POSTGRES_DB` | `documentations-postgresql-secret` | `ya-pg-secret` | `database` |
| `POSTGRES_PASSWORD` | `documentations-postgresql-secret` | `ya-pg-secret` | `password` |
| `YC-PG-CERTIFICATE` | `documentations-postgresql-secret` (`ca.crt`) | `yc-pg-certificate` (`certificate`) | см. столбцы |
| `DJANGO_BASIC_AUTH` | `django-auth` | — | `key` |
| `DOCUMENT_PUBLIC_LINK_JWT_SECRET` | `yc-jwt-secret` | — | `secret` |
| `PUBLIC_KEY` | `public-key` | — | `key` |

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

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

| Условие | STAND | NAMESPACE | Chart version |
| --- | --- | --- | --- |
| ветка `stage` | `stage` | `documentations` | `0.0.1-stage` |
| ветка `master` | `preprod` | `documentations-preprod` | `0.0.1-preprod` |
| тег (`CI_COMMIT_TAG`) | `prod` | `documentations-prod` | `0.0.1-prod` |
| `merge_request_event` | — | — | сборка образа отключена (`ENABLE_BUILD_IMAGE=false`) |

Ключевые переменные: `SERVICE_NAME=documentations-v2`, `RELEASE_NAME`/`CHART_NAME=documentations-v2`, `DOCKERFILE_PATH=.docker/api.Dockerfile`, `HELM_SET_ARGS` (`--set universal-chart.global.env=…`, `--set universal-chart.services.api.image.name.<env>=${IMAGE_NAME}`), флаги `ENABLE_LINTER`/`ENABLE_BUILD_CHART`/`ENABLE_BUILD_IMAGE`/`ENABLE_DEPLOY`.

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

- **Нет обязательности полей.** `envconfig` в этом коде не помечает поля как required — при отсутствии переменной берётся нулевое значение Go. Пустые критичные значения (адрес БД, `PUBLIC_KEY`) приведут к ошибке уже в рантайме (падение при `db.Ping`, отказ проверки JWT), а не на этапе разбора конфига.
- **`API_FILESTREAM_ADDRESS` не читается.** Оба сервера слушают `API_ADDRESS`; отдельной переменной для порта файлового стримера в коде нет.
- **Опечатка `POSTGRES_POLL_SIZE`.** В `.env.template`/`.docker.env` встречается `POSTGRES_POLL_SIZE`; код читает `POSTGRES_POOL_SIZE` (в helm имя корректное). Значение с опечаткой не подхватывается.
- **`YC-PG-CERTIFICATE`** — имя с дефисами, читается через явный тег `envconfig`. В `.helm` для preprod монтируется из отдельного секрета `yc-pg-certificate` (ключ `certificate`).
- **Файл workflow-задач обязателен по существу.** Если файл по пути `WORKFLOWS_CONFIG_FILEPATH` отсутствует или не парсится — `config.NewTasksExecutionConfigFromFilepath` вызывает `panic`. Локально нужен `.example.tasks_execution_config.json`, в k8s — том ConfigMap.
- **S3 опционален.** При `ENABLE_S3=0` S3-клиент не создаётся; хендлеры, работающие с хранилищем, будут получать `nil`-хранилище.
- **Автомиграции при старте.** Приложение накатывает миграции автоматически (см. README); ручной прогон — бинарником `migrations migrate`/`migrations rollback`.

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

Postgres поднимается через `make docker-compose` (образ `timescale/timescaledb-ha:pg13`, инициализация расширений uuid/ltree из `.docker/install-uuid-ltree.sql`). Приложение — бинарник `./api_server`. Минимально задать:

- `API_ADDRESS` (напр. `localhost:8000`);
- `POSTGRES_ADDRESS`, `POSTGRES_PORT`, `POSTGRES_USER`, `POSTGRES_DB`, `POSTGRES_PASSWORD`, `POSTGRES_POOL_SIZE`, `ENABLE_SSL=0`, `ENABLE_SQL_QUERY`;
- `PUBLIC_KEY` (для проверки JWT sarex-backend), `DOCUMENT_PUBLIC_LINK_JWT_SECRET`;
- `WORKFLOWS_CONFIG_FILEPATH` с существующим JSON (по умолчанию `.example.tasks_execution_config.json`);
- `ENABLE_S3=0`, `TRACER_USE=false`, `ENABLE_OBSERVABILITY=0` — чтобы не поднимать S3/OTEL локально;
- URL внешних сервисов (`DJANGO_HOST`, `WORKFLOW_URL`, `WORKSPACE_URL`, `BIM_API_URL`, `BIM_API_V2_URL`, `MARKS_PROCESSING_URL`, `SYSTEM_LOG_URL`, `FLOWS_URL`) — по мере необходимости для соответствующих сценариев.

Готовые значения-примеры приведены в `api-v2.env.example` (с учётом замечаний выше).
