# API пользовательских настроек Этот раздел описывает `user_settings` - отдельное хранилище пользовательских настроек, не связанное с `users_params` и не связанное с legacy DM-таблицами. ## 1. Назначение `user_settings` хранит технические пользовательские настройки, которые должны синхронизироваться между максимум двумя access/sync-серверами пользователя. Основной текущий кейс: - `setting_type = 1` - курсор прочитанности канала; - `setting_key = ownerBlockchainName/channelName`; - `value_num = number of messages already seen in channel`; - `value_text = ''`. Если настройки нет, канал считается полностью прочитанным, то есть unread = `0`. После первого открытия канала UI отправляет текущий курсор, чтобы зафиксировать baseline и дальше считать только новые сообщения. ## 2. Структура записи - `login` - логин владельца настройки; - `setting_type` - числовой код типа настройки; - `setting_key` - строковый ключ настройки; - `time_ms` - время установки значения в миллисекундах; - `value_text` - строковое значение; - `value_num` - числовое значение; - `client_key` - публичный Ed25519 ключ клиента в Base64; - `signature` - Ed25519 подпись preimage в Base64; - `synced` - была ли настройка успешно доставлена на второй сервер. Уникальность: `(login, setting_type, setting_key)`. Обновление: только если `time_ms` новее текущего значения. ## 3. Формат подписи Подписывается строка: `SHiNe/UserSettings:|login|setting_type|setting_key|time_ms|value_text|value_num` Где внутри полей используется экранирование `\` и `|`. Подпись создаётся клиентским `client_key`. ## 4. Операции ### `UpsertUserSetting` Записывает или обновляет настройку пользователя. Если запрос пришёл от клиента, сервер: - сохраняет запись локально; - пытается сразу отправить её на доступный sync-сервер; - если отправка успешна, помечает запись как `synced=true`; - если нет, оставляет `synced=false`. Если запрос пришёл по синхронизации между серверами, используется `sync_delivery=true`, и повторной пересылки дальше не делается. ### `GetUserSetting` Чтение одной настройки по `(login, setting_type, setting_key)`. ### `ListUserSettings` Список всех настроек пользователя. ### `UserSettingsSyncBatch` Внутренний межсерверный batch-эндпоинт. - отдаёт настройки, новые относительно курсора; - используется для bootstrap и догрузки после восстановления; - применяется только для пользователей, чей сервер есть в `access_servers`. ### `MarkAllUserSettingsUnsynced` Внутренний служебный запрос. - помечает все настройки пользователя или все настройки сразу как `synced=false`; - одновременно сбрасывает DM-outbox того же пользователя (или всех пользователей), чтобы операция замены/добавления access-сервера не оставила историю DM несинхронизированной; - ответ дополнительно содержит `dmUpdated` — количество сброшенных DM-событий; - нужен после добавления нового sync-сервера или при потере локальной БД. ## 5. Синхронизация Настройки и DM имеют раздельные таблицы и правила ACK, но периодический процесс использует один логический последовательный сеанс поверх постоянного WSS-пула: сначала синхронизирует настройки, затем забирает `DmSyncBatch`. Завершение логического сеанса не закрывает физический сокет. - локальная запись создаётся с `synced=false`, если её ещё не подтвердил второй сервер; - если запись пришла с другого сервера, она сохраняется сразу как `synced=true`; - периодический sync раз в 6 часов проверяет несинхронизированные настройки, догружает их по курсору и затем забирает несинхронизированные DM; - если появляется новый sync-сервер или локальная БД была потеряна, нужно пометить все настройки несинхронизированными и заново догрузить batch с нуля. ## 6. Текущий UI-кейс UI при открытии канала отправляет `UpsertUserSetting` с: - `setting_type = 1`; - `setting_key = ownerBlockchainName/channelName`; - `value_num = количество уже просмотренных сообщений в канале`. Это значение используется сервером для расчёта unread в списке каналов и в канале.