113 lines
12 KiB
Markdown
113 lines
12 KiB
Markdown
# Матрица доступа к настройкам Exchanger
|
||
|
||
## Назначение экрана
|
||
|
||
Экран настроек предназначен для владельца автомата, а не для технического специалиста.
|
||
В production он открывается физической кнопкой `SERVICE`; опциональный единый PIN включается
|
||
в самом приложении. В debug-сборке `F10` открывает тот же состав пользовательских настроек.
|
||
|
||
## Доступные владельцу разделы
|
||
|
||
| Раздел UI | Секции `AppSettings` | Применение |
|
||
| --- | --- | --- |
|
||
| Общие | `Branding.ShortText`, `Branding.SupportPhone`, `Security` | сразу после автосохранения |
|
||
| Звук | `Audio` | сразу, включая live-preview |
|
||
| Промо | `Advertisement` | сразу после автосохранения |
|
||
| Тарифы | `Pricing` | сразу, только когда нет операции |
|
||
| Оплата | `Payments`, `Timeouts` | сразу, только когда нет операции |
|
||
| Сервис | `MenuVisibility`, `TokenInventory.Enabled`, отдельный `user://data/token_inventory.json` | сразу после автосохранения; остаток — после ручного добавления или подтверждения пересчёта |
|
||
|
||
## Технические данные, отсутствующие в UI владельца
|
||
|
||
- внешний DLC темы, путь к `.pck`, текущая тема и `ReducedEffects`;
|
||
- сводки применения restart-only изменений и технический итог плейлиста промо-роликов;
|
||
- mock-режим, COM-порт, baud rate, reconnect и остальные параметры контроллера;
|
||
- fullscreen, borderless, debug-window и target FPS;
|
||
- версия приложения, состояние соединения, порт, запас и последние диагностические предупреждения;
|
||
- уровень журналирования, размер и срок хранения журналов;
|
||
- инженерная тестовая выдача одного жетона (владелец вместо неё видит безопасный учёт остатка);
|
||
- AES-ключ, платёжные секреты, сырые кадры, команды и ответы контроллера;
|
||
- framing, handshake, профиль силового канала и привязки `IN8/IN1/IN4/IN24`.
|
||
|
||
Аппаратные значения находятся в отдельном
|
||
`user://config/technical_settings.toml` и изменяются только при техническом обслуживании вне
|
||
приложения. Порт, оба хоппера, привязки входов и параметры связи описаны в
|
||
[TECHNICAL_CONFIGURATION.md](TECHNICAL_CONFIGURATION.md). Они не участвуют в валидации формы
|
||
владельца и не могут заблокировать автосохранение доступных ему параметров.
|
||
|
||
## PIN и безопасность операции
|
||
|
||
После включения или сброса PIN владелец при следующем входе дважды вводит 4–12 цифр. Открытый PIN
|
||
не сохраняется: в JSON попадают только соль, PBKDF2-SHA256-хеш и число итераций. Пять ошибок
|
||
блокируют проверку на 30 секунд.
|
||
|
||
Экран открывается только из `Home`. Пользовательская сессия получает снимок настроек при создании
|
||
`SessionFlow`, поэтому изменения не попадают в середину оплаты или выдачи. Допустимые изменения
|
||
сохраняются атомарно через 0,5 секунды после последнего ввода. Закреплённая снизу кнопка
|
||
«Сохранить и выйти» немедленно завершает ожидающее сохранение и закрывает экран только после
|
||
успеха. Повторный IN8 использует тот же безопасный путь. При ошибках в полях, незавершённом
|
||
пересчёте или тестовой выдаче пользователь остаётся в настройках.
|
||
|
||
Футер находится вне `ScrollContainer`, поэтому остаётся на нижней границе экрана при прокрутке
|
||
одним пальцем или зажатой ЛКМ. Нижний технический зазор в содержимом позволяет поднять последние
|
||
поля выше футера, а жест, начатый на самой кнопке, список не прокручивает.
|
||
|
||
В разделе «Общие» владелец редактирует только «Свой текст» для речевого bubble и телефон
|
||
поддержки. Поле названия автомата и отдельный branding-preview не показываются. Сохранённое
|
||
`Branding.ApplicationName` остаётся совместимым с существующей конфигурацией и продолжает
|
||
использоваться там, где его отображает текущая тема, но через экран владельца не изменяется.
|
||
|
||
## Сервисный учёт жетонов
|
||
|
||
Число в разделе «Сервис» — учётный остаток владельца, а не показание датчика хоппера.
|
||
При первом запуске он равен нулю и хранится отдельно от настроек в
|
||
`user://data/token_inventory.json`. Подтверждённая обычная выдача уменьшает остаток, но не
|
||
уходит ниже нуля.
|
||
|
||
Переключатели «Учитывать остаток жетонов» и «Не продавать больше остатка» включены по умолчанию.
|
||
Первый отвечает за ведение, списание и отображение точного остатка. Второй независимо включает
|
||
лимит полного количества к выдаче с учётом бонуса. При активном лимите недопустимая карточная
|
||
сумма отклоняется до запроса оплаты у терминала, а наличная выдача — до команды хопперу; кнопки
|
||
готовых карточных сумм недоступны, а ручной ввод показывает ошибку.
|
||
|
||
Если учёт включён, а лимит выключен, остатки и сервисные действия остаются видимыми, подтверждённая
|
||
выдача продолжает списываться, но сохранённое число не блокирует оплату. Качественное состояние
|
||
Home для доступности покупки в этом режиме определяется бинарными датчиками. В `DualHopperAuto`
|
||
из hopper 1 планируется его записанный остаток, а вся недостающая часть направляется в hopper 2.
|
||
|
||
При выключенном учёте отдельный переключатель лимита скрывается, сохранённое число не ограничивает
|
||
оплату и не уменьшается при выдаче.
|
||
Точный общий и раздельные остатки, кнопки пересчёта и добавления, а также их статус скрываются;
|
||
на Home скрывается только приблизительное число, но бинарное состояние датчиков продолжает
|
||
показываться. В `DualHopperAuto` выдача без учёта направляется в hopper 1 и сохраняет разбиение
|
||
команд на последовательные пакеты не более 99. Автоматического failover после ошибки нет.
|
||
Файл остатка не удаляется: перед повторным включением учёта после выдач без него необходимо
|
||
пересчитать хопперы, иначе будет использовано устаревшее сохранённое значение.
|
||
|
||
Владелец может:
|
||
|
||
- вручную ввести добавляемое количество и подтвердить его отдельным шагом;
|
||
- запустить автоматический пересчёт: приложение включает активный хоппер, считает фронты
|
||
датчика выдачи и завершает операцию после 10 секунд без нового импульса;
|
||
- исправить полученное число перед окончательной записью, например если оставшиеся в хоппере
|
||
жетоны были извлечены вручную и добавлены к общей куче.
|
||
|
||
Во время пересчёта нельзя начать оплату, обычную выдачу или закрыть настройки. При отмене,
|
||
потере связи либо ошибке старый учётный остаток сохраняется. После штатного завершения старое
|
||
значение обнуляется, а новый остаток записывается только после подтверждения владельцем.
|
||
|
||
## Скрытие элементов главного экрана
|
||
|
||
Панель «Скрытие элементов меню» находится в разделе «Сервис» и управляет тремя независимыми
|
||
флагами `MenuVisibility`: показом учётного остатка жетонов, пользовательского текста вместе с
|
||
theme-owned персонажем справа и целого промо-блока. Все элементы по умолчанию показаны, поэтому миграция старой конфигурации
|
||
не меняет существующий интерфейс. Переключатели применяются сразу после автосохранения.
|
||
|
||
Host изменяет только свойство видимости готовых узлов по binding-id. Он не создаёт, не перемещает
|
||
и не переоформляет содержимое внешней темы. Если скрыта панель остатка или промо, связанные с ней
|
||
поверхности интерактивного питомца также исключаются из графа при следующем входе на Home.
|
||
|
||
Аудит `user://logs/settings-audit.jsonl` содержит дату, внутренний уровень доступа, названия
|
||
изменённых разделов и флаг необходимости перезапуска. Значения, пути, PIN, платёжные данные и
|
||
протокольные кадры в него не записываются.
|