> ## Documentation Index
> Fetch the complete documentation index at: https://omniflow-vpn.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Настройки установки

> Что хранит экран настроек, что из этого влияет на поведение сегодня и откуда на самом деле берётся каждое работающее значение

`/admin/settings` — вход в конфигурацию консоли оператора, и он держит три разных
рода вещей. Коммерческая политика — пополнение кошелька и одновременность подписок —
хранится в базе данных. Десять декларативных **разделов установки** хранятся,
версионируются и попадают в аудит, а их учётные данные запечатаны. Две карточки
доступны только для чтения: предпросмотр телеметрии и история резервных копий и
восстановлений.

Это указатель, а не страница с формами. Раньше всё рисовалось одной колонкой —
коммерция с платёжными провайдерами, все десять разделов, предпросмотр телеметрии,
история резервных копий, диагностический пакет и каждый провайдер входа клиентов, —
так что добраться до уведомления об обслуживании значило прокрутить мимо платёжных
провайдеров, а открытие экрана запрашивало всё это разом, смотрели вы на что-то из
этого или нет.

| Раздел | Что держит |
| - | - |
| `/admin/settings/commerce` | Валюта, лимиты пополнения, политика подписок, платёжные провайдеры |
| `/admin/settings/integrations` | Remnawave, бот Telegram, операторская группа, обязательные каналы |
| `/admin/settings/operations` | Обслуживание, уведомления, резервные копии, телеметрия — плюс предпросмотр телеметрии и история копий |
| `/admin/settings/brand` | Брендинг, [оформление](https://omniflow-vpn.mintlify.site/ru/operations/branding.md) и раздел безопасности |
| `/admin/settings/connect` | [Инструкции по подключению](https://omniflow-vpn.mintlify.site/ru/operations/connection-catalogue.md): платформы и приложения, которые предлагается установить клиентам |
| `/admin/settings/notices` | [Тексты сообщений](https://omniflow-vpn.mintlify.site/ru/operations/message-wording.md): транзакционные уведомления, которые установка отправляет сама |
| `/admin/settings/analytics` | [Измерение рекламы](https://omniflow-vpn.mintlify.site/ru/operations/advertising-measurement.md): счётчики, подтверждение сайта и идентификатор клика, переносимый в заказ |
| `/admin/settings/sign-in` | Провайдеры входа для клиентов |
| `/admin/settings/ai` | Провайдеры моделей, включение по функциям, бюджеты, подключения MCP |

Диагностический пакет переехал на [`/admin/system`](https://omniflow-vpn.mintlify.site/ru/operations/admin-operations).
Его маршрут всегда был за `system.read`, а не за `settings.read` — пакет описывает
работающую установку, а не настраивает её, — и раньше он рисовался на странице,
которую оператор с одним лишь `system.read` открыть не мог.

Различие, которое здесь имеет значение, на экране не видно, поэтому оно изложено
первым.

> [!WARNING]
>
> Сохранение раздела установки записывает версионированный документ, запечатывает
> введённые вами секреты и добавляет запись в журнал аудита. Оно **не** меняет
> поведение процессов `api`, `bot` и `worker`. Эти процессы читают свою конфигурацию
> из переменных окружения один раз при старте и никогда не перечитывают её. Чтобы
> изменить поведение, измените переменную и перезапустите процесс.
>
> Считайте сохранённый раздел записью о намерении — полезной, проверяемой и пока
> что не рычагом управления.

Каждый раздел настроек требует `settings.read`; каждое сохранение требует
`settings.write`. Диагностическому пакету нужно `system.read`, и живёт он на экране
системы. О том, как выдаются эти права доступа, см.
[Панель администратора](https://omniflow-vpn.mintlify.site/ru/operations/admin-panel.md).

## Откуда на самом деле читается каждое значение

| Карточка настроек | Хранится в | Читается во время работы | Чем изменить поведение |
| - | - | - | - |
| Пополнение кошелька | `commerce_settings` | Нет — лимиты, пресеты и скользящее окно берутся из окружения | `APP_WALLET_TOPUP_*` |
| Подписки | `commerce_settings` | Частично — веб-панель клиента читает `multi_subscription_enabled`, чтобы решить, показывать ли переключатель подписок | `APP_MULTI_SUBSCRIPTION_ENABLED`, `APP_MAX_SUBSCRIPTIONS_PER_CUSTOMER` |
| Брендирование | `installation_settings` | Нет | `APP_PUBLIC_URL`, `APP_TERMS_URL`, `APP_SUPPORT_URL`, `APP_DEFAULT_CURRENCY` |
| Оформление | `installation_settings`, `branding_assets` | **Да** — обе панели читают его при каждой отрисовке, за минутным кэшем | Сохранить и перезагрузить; переменной окружения нет |
| Remnawave | `installation_settings` | Нет | `APP_REMNAWAVE_URL`, `APP_REMNAWAVE_TOKEN` |
| Telegram | `installation_settings` | Нет | `APP_TELEGRAM_TOKEN`, `APP_TELEGRAM_WEBHOOK_URL`, `APP_TELEGRAM_WEBHOOK_SECRET` |
| Группа операторов | `installation_settings` | Нет | `APP_OPERATOR_CHAT_ID`, `APP_OPERATOR_NOTIFICATION_CAP`, `APP_OPERATOR_NOTIFICATION_WINDOW_MINUTES` |
| Обязательные каналы | `installation_settings` | Нет | *(эквивалента нет; см. [Обязательные каналы](https://omniflow-vpn.mintlify.site/ru/operations/required-channels.md))* |
| Обслуживание | `installation_settings` | Нет | `APP_MAINTENANCE_AUTO_DETECT`, `APP_MAINTENANCE_FAILURE_STREAK`, `APP_MAINTENANCE_RECOVERY_STREAK` |
| Уведомления | `installation_settings` | Нет | *(эквивалента нет; пороги скомпилированы в приложение)* |
| Телеметрия | `installation_settings` | Только предпросмотр — см. ниже | `APP_TELEMETRY_ENABLED`, `APP_TELEMETRY_ENDPOINT` |
| Резервные копии | `installation_settings` | Нет | `APP_BACKUP_ENABLED`, `APP_BACKUP_ENCRYPTION_KEY`, `APP_BACKUP_DIR`, `APP_BACKUP_INTERVAL_HOURS`, `APP_BACKUP_RETENTION_DAYS` |
| Безопасность | `installation_settings` | Нет | *(эквивалента нет; времена жизни сессий скомпилированы в приложение)* |
| Платёжные провайдеры | `payment_provider_settings` | Нет — адаптеры, которые на самом деле вызывают API и воркер, собираются из окружения при старте | `APP_TELEGRAM_TOKEN`, `APP_CRYPTOBOT_TOKEN`, `APP_CRYPTOBOT_TESTNET`, `APP_YOOKASSA_SHOP_ID`, `APP_YOOKASSA_SECRET` |
| Вход клиентов (OIDC) | `customer_oidc_providers` | Да | Сама панель |

Клиентский OIDC — исключение, которое стоит запомнить: эти провайдеры читаются из
базы данных при каждом входе, поэтому добавление, правка или отключение
провайдера вступает в силу немедленно, — а отключение завершает установленные им
сессии. Всё остальное на этой странице либо управляется окружением, либо хранится
и ждёт.

У трёх разделов вообще нет эквивалента в окружении, и их поля инертны в обе
стороны:

* **Уведомления** — `failedPaymentThreshold`, `driftThreshold`, `outboxBacklogThreshold`,
  `quietHoursStart`, `quietHoursEnd`. Их ничто не читает. Оповещение о выдаче доступа
  срабатывает после трёх неудачных попыток, и это скомпилированная константа.
* **Безопасность** — `sessionIdleMinutes`, `sessionAbsoluteHours`, `requireTotp`,
  `allowedOrigins`. Сессии операторов всегда используют скомпилированную политику:
  30 минут таймаута бездействия, 12 часов абсолютного времени жизни, ротация токена
  каждые 15 минут. Нигде нет механизма, который требовал бы двухфакторную
  аутентификацию для аккаунта оператора; TOTP настраивается на уровне аккаунта и
  добровольно.
* **Обязательные каналы** — `recheckIntervalMinutes`, `graceHours`, `warnBeforeSuspend`.
  Повторная проверка членства выполняется в боте фиксированным десятиминутным циклом.

Полный список переменных, которые действительно вступают в силу, приведён в разделе
[Конфигурация](https://omniflow-vpn.mintlify.site/ru/getting-started/configuration.md).

## Как сохраняется раздел

Каждый раздел — это одна карточка со своей кнопкой **Save**. В подвале карточки
показаны версия, из которой она отрисована, и время последней записи.

**1. Откройте раздел**

Перейдите на `/admin/settings` и выберите раздел. Отрисовывается каждая секция,
которая может быть у раздела, а не только те, которые кто-то уже записал, поэтому
свежая установка показывает пустые карточки, а не ни одной.

**2. Отредактируйте поля документа**

Текстовые, URL-, числовые, логические поля и текстовые области — всё это часть
*документа* раздела. Документ никогда не содержит учётных данных, и это
обеспечивается тем, что запрос не выбирает столбец с секретом, а не фильтром,
о применении которого кто-то должен помнить.

**3. Вводите секрет, только если вы его меняете**

Поле секрета всегда пустое, потому что API никогда не возвращает сохранённое
значение. Если оставить его пустым, сохранится то, что уже записано. Панель
вырезает пустые секреты из полезной нагрузки перед отправкой, поэтому повторное
сохранение карточки не может случайно стереть учётные данные.

**4. Сохраните**

Запрос — это `PUT /v1/panel/settings/{section}` с телом
`{"document": {...}, "version": <n>, "secrets": {...}}`. При успехе карточка
перерисовывается с новой версией и обновлённой отметкой времени.

### Что может отклонить сохранение

| Ответ | Что означает |
| - | - |
| `409 conflict` | Отправленная вами версия не является текущей. Кто-то другой сохранил этот раздел, пока ваш экран был открыт; карточка показывает предупреждение о конфликте и просит перезагрузить страницу. Повторное сохранение поверх отбросило бы чужое изменение, каким бы оно ни было, — поэтому запрос отклоняется, а не объединяется. |
| `422` | Неизвестное имя раздела или документ, не являющийся корректным JSON. |
| `403` | У ваших ролей нет `settings.write`. |

### Что записывает журнал аудита

Каждое сохранение добавляет `settings.section.saved` в категории `configuration` с
объектом `installation_setting:<section>`. Его метаданные несут получившуюся версию
и *имена* секретов, которые были заменены, — никогда их значения. «Кто-то поменял
токен Remnawave во вторник» — вот проверяемый факт, и именно он нужен при разборе
инцидента.

Секреты запечатываются ключом `APP_DATA_ENCRYPTION_KEY` под меткой, своей для
каждого раздела, поэтому шифротекст, перенесённый из строки одного раздела в
другой, не открывается, а не расшифровывается там, где ему не место.

> [!NOTE]
>
> Тело ответа на сохранение сообщает `secretConfigured` исходя из того, нёс ли
> секрет *именно этот вызов*, поэтому сохранение, изменившее только поля документа,
> отвечает `false`, даже когда учётные данные сохранены. Панель сразу после этого
> перечитывает список разделов, поэтому бейдж, который вы видите на экране, верен;
> интеграции, читающей ответ на сохранение напрямую, следует перечитывать
> `GET /v1/panel/settings`, а не доверять этому полю.

## Каталог разделов

| Раздел | Поля документа | Секреты |
| - | - | - |
| `branding` | `serviceName`, `supportContact`, `publicUrl`, `termsUrl`, `defaultLocale`, `timezone` | — |
| `remnawave` | `baseUrl`, `reconcileIntervalMinutes`, `compatibilityChecked` | `token` |
| `telegram` | `botUsername`, `webhookUrl`, `webhookEnabled` | `botToken`, `webhookSecret` |
| `operator_group` | `chatId`, `createTopics`, `notificationCap`, `windowMinutes` | — |
| `required_channels` | `recheckIntervalMinutes`, `graceHours`, `warnBeforeSuspend` | — |
| `maintenance` | `autoEnable`, `failureThreshold`, `noticeEn`, `noticeRu` | — |
| `notifications` | `failedPaymentThreshold`, `driftThreshold`, `outboxBacklogThreshold`, `quietHoursStart`, `quietHoursEnd` | — |
| `telemetry` | `enabled`, `endpoint` | — |
| `backup` | `enabled`, `intervalHours`, `retentionDays`, `directory` | `encryptionKey` |
| `security` | `sessionIdleMinutes`, `sessionAbsoluteHours`, `requireTotp`, `allowedOrigins` | — |
| `theme` | Палитра, масштабы скруглений и отступов, доступные режимы, режим по умолчанию — см. [White-label оформление](https://omniflow-vpn.mintlify.site/ru/operations/branding.md) | — |
| `analytics` | `enabled`, идентификаторы счётчиков по провайдерам, теги подтверждения для вебмастеров — см. [Измерение рекламы](https://omniflow-vpn.mintlify.site/ru/operations/advertising-measurement.md) | — |

Четыре из них не являются полями универсального рендерера. У `ai` и `mcp` свой экран по
адресу `/admin/settings/ai` — см. [Управление ИИ](https://omniflow-vpn.mintlify.site/ru/operations/ai-governance.md) и
[MCP](https://omniflow-vpn.mintlify.site/ru/operations/mcp.md); у `theme` свой редактор под полями брендинга на
`/admin/settings/brand`, потому что цвет — не текстовое поле, а логотип — не документ
настроек; а у `analytics` свой на `/admin/settings/analytics`, потому что у идентификатора
счётчика своя форма для каждого провайдера, а тег подтверждения берётся из списка
разрешённых. Все четыре остаются обычными разделами через
`GET`/`PUT /v1/panel/settings/{section}`, с тем же контролем версии и той же записью в
журнале.

Тексты уведомлений на `/admin/settings/notices` — исключение, которое вообще не является
разделом. Это таблица переопределений, а не один документ: строка — это исключение, а её
отсутствие — стандартный текст, и именно поэтому возврат является удалением, а более
позднее обновление может улучшить текст, которого никто не касался.

## Коммерческие настройки

Две карточки в верхней части экрана опираются на строку `commerce_settings`, а не
на документ раздела, и это единственная часть экрана с настоящей валидацией.

Строка заполняется из окружения при первом старте API с пустой таблицей, поэтому
оператор, выполняющий обновление, находит уже настроенные им лимиты, а не значения
по умолчанию из схемы. Сбой заполнения логируется и никогда не блокирует запуск.

**Карточка пополнения.** Переключатель включения, бейдж валюты только для чтения,
минимум, максимум, скользящее окно в часах, лимит на окно и список пресетов через
запятую — все суммы в минорных единицах. Валюта не редактируется, потому что
кошелёк ведётся по валютам: несколько валют пополнения позволили бы клиенту
пополнить баланс, который он не сможет потратить на нужный ему тариф. Свободный
ввод остаётся доступен при любом наборе пресетов, поэтому пустой список пресетов
означает «только свободный ввод», а не «пополнение недоступно».

Отказы, все `422`: минимум или максимум меньше нуля или равный нулю, минимум выше
максимума, окно меньше нуля или равное нулю и — тот, на который натыкаются чаще
всего, — **пресет вне лимитов**, потому что пресет, который магазин отклонит, —
это кнопка, которая всегда падает.

**Карточка подписок.** Переключатель множественных подписок и максимум на клиента,
который должен быть не меньше 1. Отключение одновременности ничего не закрывает:
клиенты, у которых уже несколько подписок, их сохраняют, а потолок применяется
только к новым покупкам. Тариф может сузить потолок собственным лимитом; расширить
друг друга они не могут. См. [Подписки](https://omniflow-vpn.mintlify.site/ru/commerce/subscriptions.md).

Обе записи добавляют `panel.settings.topup.updated` / `panel.settings.subscriptions.updated`
с объектом `settings:commerce`.

## Предпросмотр телеметрии

Карточка предпросмотра показывает анонимный идентификатор установки, признак того,
отправлялось ли что-нибудь хоть раз, общее число событий, отрисованную полезную
нагрузку JSON и плоский список имён её полей.

> [!WARNING]
>
> Состояние вкл/выкл и эндпоинт на карточке берутся из **документа раздела**
> `telemetry`, который в свежей установке пуст, — поэтому карточка показывает
> `enabled: false`. Отправитель же читает `APP_TELEMETRY_ENABLED`, который **по
> умолчанию равен `true`**. В установке с настройками по умолчанию карточка
> говорит «выключено», пока API раз в день отправляет heartbeat.
>
> Карточка к тому же отрисовывает не тот набор полей, что уходит в событии на
> проводе. Считайте авторитетом того, что покидает установку,
> [Анонимную телеметрию](https://omniflow-vpn.mintlify.site/ru/operations/telemetry.md), а способом это остановить —
> `APP_TELEMETRY_ENABLED=false`.

Что карточка передаёт верно — так это форму обещания: ни в предпросмотре, ни в
событии на проводе нет ни количества клиентов, ни цифры выручки, ни домена, потому
что число, достаточно малое, чтобы опознать установку, само является
идентификатором.

## Резервные копии и восстановления

Таблица недавних резервных копий только для чтения — когда, какого рода, статус,
размер, проверена — а прямо под ней история восстановлений. Резервная копия,
которую никто никогда не восстанавливал, — это резервная копия, о работоспособности
которой никто не знает, поэтому обе вещи стоят на одной карточке, а не на разных
экранах.

Панель не может ни снять, ни восстановить резервную копию. Маршрута на запись для
этого нет ни на `/v1/panel`, ни на `/v1/admin`; единственные два способа заставить
это произойти — расписание воркера и поверхность `/ops` у бота. См.
[Резервные копии и восстановление](https://omniflow-vpn.mintlify.site/ru/operations/backup-restore.md).

## Диагностический пакет

Нажмите **Generate**, и карточка запросит `GET /v1/panel/settings/diagnostics`,
которому нужно `system.read`, а не `settings.read`: он описывает работающую
установку, а не её настройки, и нужен он тем, кто и так смотрит на состояние
системы.

Пакет несёт:

* версию сборки, версию Go и `GOOS/GOARCH`
* статус миграций: число применённых, последнюю версию и признак того, помечена ли
  миграция как грязная, — читается из собственной таблицы ревизий Atlas
* по каждому разделу: настроен ли он, держит ли секрет и какая у него версия
* статус резервных копий: всего, когда снята последняя, её размер, когда последний
  раз проверялась, последнее восстановление, число восстановлений
* здоровье платёжных провайдеров и текущее состояние режима обслуживания
* количество строк по клиентам, подпискам, заказам, открытым обращениям, операторам
  и ожидающим событиям outbox

Он собирается по списку разрешённых полей, а не выгрузкой состояния с последующей
фильтрацией. Фильтр приходится обновлять каждый раз, когда добавляется поле; список
разрешённого при забывчивости отказывает в безопасную сторону. Поэтому пакет не
содержит ни учётных данных, ни документов разделов — документ брендирования
безобиден, а документ группы операторов называет чат, и проведение этой границы по
каждому разделу отдельно — ровно та ошибка, которой список разрешённого позволяет
избежать.

Два числа в пакете требуют интерпретации:

* **Версия всегда `dev`.** Ни одна сборка не проставляет версию в бинарники, включая
  выпущенные образы, поэтому и пакет, и `/livez`, и heartbeat телеметрии сообщают
  `dev`. Определяйте развёртывание по тегу образа.
* **Число ожидающих событий outbox только растёт.** События пишутся в
  `outbox_events` при `order.paid`, `wallet.credited` и `addon.purchased`, и ничто
  не помечает их опубликованными, поэтому счётчик растёт всё время жизни установки,
  а чистка по сроку хранения ничего из них не удаляет. Это не сигнал о накоплении
  очереди и не признак того, что что-то застряло. См.
  [Задания и очереди](https://omniflow-vpn.mintlify.site/ru/operations/jobs-and-queues.md).

Статус миграций, читающийся нулями, означает, что таблицы ревизий Atlas не
существует, и это верный ответ для установки, у которой мигратор не запускался.

## Связанные страницы

> **[Конфигурация](https://omniflow-vpn.mintlify.site/ru/getting-started/configuration.md)**
>
> Каждая переменная окружения, которая меняет поведение, сгруппированная по темам.

> **[Панель администратора](https://omniflow-vpn.mintlify.site/ru/operations/admin-panel.md)**
>
> Роли, права доступа, сессии и журнал аудита за этим экраном.

> **[Анонимная телеметрия](https://omniflow-vpn.mintlify.site/ru/operations/telemetry.md)**
>
> Точное событие на проводе и как его отключить.

> **[Резервные копии и восстановление](https://omniflow-vpn.mintlify.site/ru/operations/backup-restore.md)**
>
> Снятие, проверка, хранение и проигрывание зашифрованного дампа.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.