Работа без Telegram
Core можно запустить как браузерный магазин с регистрацией по email. Telegram остаётся дополнительным каналом входа и уведомлений. Числовой user_id — внутренний ключ базы, telegram_id — отдельная подтверждённая привязка. Публичный minishop_id имеет вид ms_ и 32 шестнадцатеричных символа UUID; для новых основных записей Remnawave он используется как username.
Новая установка
Заголовок раздела «Новая установка»В .env задайте как минимум:
Заполните доступы к своему Remnawave и платёжным провайдерам отдельно. EMAIL_AUTH_SECRET и WEBAPP_SESSION_SECRET должны быть устойчивыми между перезапусками и одинаковыми на репликах. Генерируйте каждый независимо, например openssl rand -hex 32, и храните вне Git. PUBLIC_APP_URL — адрес браузерного кабинета и ссылка в письмах; WEBHOOK_BASE_URL — адрес входящих вебхуков API. SMTP может работать и при EMAIL_LOGIN_ENABLED=False, если письма нужны для уведомлений.
Первый владелец
Заголовок раздела «Первый владелец»Мастер установки предлагает два необязательных поля: Telegram User ID и email первого владельца. В .env им соответствуют BOOTSTRAP_OWNER_TELEGRAM_ID и BOOTSTRAP_OWNER_EMAIL. Можно заполнить одно поле, оба для одного человека или пропустить оба. Telegram и SMTP настраиваются отдельно; SMTP в мастере тоже можно пропустить. До регистрации должен быть настроен хотя бы один доступный способ входа: Telegram, SMTP/email или внешний OAuth-провайдер.
Первый вошедший аккаунт с указанной подтверждённой привязкой Telegram или подтверждённым email получает роль owner и доступ в админку. Email сравнивается без учёта регистра; учитываются также дополнительные подтверждённые адреса аккаунта. Просто указать чужой email без подтверждения недостаточно. Telegram ID сравнивается с привязкой Telegram, а не с внутренним числовым ID Minishop. Заблокированный аккаунт не получает роль.
Назначение одноразовое и защищено от одновременного входа двух аккаунтов. Если Telegram и email оказались у разных аккаунтов, владельцем станет только первый совпавший; аккаунты автоматически не объединяются. Привяжите второй способ входа в профиле владельца через обычное подтверждение. Наличие владельца, включая сохранённое отозванное назначение, останавливает автоматическую выдачу: оставшиеся значения .env не создают новых администраторов и не восстанавливают отозванные права. После успешного назначения оба значения можно очистить и пересоздать backend/worker. Роли сохраняются в базе, а выдача записывается в аудит.
Если оба поля пропущены, после запуска backend, worker и frontend зарегистрируйте аккаунт доступным способом входа. Его ID вида ms_… виден в профиле. Из доверенной оболочки сервера, в каталоге установки, назначьте первого владельца:
Команда по Minishop ID работает и без привязанных Telegram/email. Вместо ID можно передать --telegram-id 123456789 для зарегистрированной привязки Telegram или --email owner@example.com для подтверждённого адреса. Выберите ровно один аргумент. На отдельном backend node выполняйте команду в каталоге backend. Команда отказывает, если активный владелец уже существует, аккаунт не найден или заблокирован; она не заменяет существующего владельца. После выполнения обновите кабинет.
Первому случайному зарегистрированному пользователю права не выдаются. ADMIN_IDS остаётся только однократным импортом администраторов существующей установки и не заменяет настройки первого владельца. Владелец управляет ролями owner и admin в разделе «Настройки → Общие → Администраторы» админки. Последнюю роль владельца отозвать нельзя. Ошибочный идентификатор до первого назначения исправьте в .env и пересоздайте backend/worker; если владельца ещё нет, всегда доступна ручная команда.
Обновление существующей установки
Заголовок раздела «Обновление существующей установки»- Сохраните резервную копию PostgreSQL и текущей конфигурации. Зафиксируйте ожидающие оплаты, recurring-подписки и ссылки на пользователей в панели.
- Разверните обновлённый backend и worker и примените обычные миграции. Миграции
0090,0091и0092добавляют UUID,minishop_id, роли, фактическое имя пользователя и отпечаток панели, а также последовательность для новых внутренних ключей. Они не перенумеровывают старые аккаунты и не переписывают их платежи. - Пока панель отвечает на сохранённые native ID, запустите
python backend/scripts/capture_panel_usernames.py, затемpython backend/scripts/capture_panel_usernames.py --applyиз доверенной оболочки. Команда считывает фактические username только по ссылкам с подтверждённой Telegram identity, проверенным email или точным сохранённым username и не меняет панель; ненайденные связи остаются в отчёте для ручной сверки. Запускайте её против той же панели, с которой были созданы связи: совпавший числовой native ID другой панели не доказывает принадлежность аккаунта. Сделайте это до обновления панели 2.8 → 3.x: после смены поколения старый UUID может стать нечитаемым через API. Проверьте уникальностьaccount_idиminishop_idи сохранностьpanel_user_uuid. Миграция БД не угадываетpanel_usernameпо email или Telegram ID. СтарыеADMIN_IDSимпортируются в роли только через явно записанныйtelegram_id; неразрешённые ID видны в журнале миграции и требуют ручного решения. - Подтвердите email владельца и назначьте роль командой выше, если она ещё не импортирована. Только после проверки админского входа отключайте Telegram через
TELEGRAM_ENABLED=False. - Сверьте суммы и статусы платежей, балансы, подарки, recurring-состояния, подписки и связи с панелью с резервной копией. Повторные вебхуки должны оставаться идемпотентными.
Новые username панели используют minishop_id. Исторические tg_* и em_* остаются фактическими именами до отдельного подтверждённого переименования в версии Remnawave, где оно поддерживается. Код ищет старую запись по сохранённому panel_username и native ID; он не объявляет переименование завершённым. Если у аккаунта уже есть ссылка на запись панели, но её невозможно подтвердить, Core сохраняет эту ссылку для ручной сверки и не создаёт новую запись автоматически. Обновление Minishop само по себе не меняет username, подписочную ссылку или ключи подключения в панели.
Telegram identity можно свободно привязать к существующему аккаунту без изменения
user_id, account_id, minishop_id, подписки или роли. Если она уже принадлежит другому
аккаунту (в том числе созданному командой /start), обычная привязка предлагает явное объединение.
Тот же сценарий работает для существующих Google, Yandex ID, Discord и email-аккаунтов и
не содержит отдельных правил для каждой пары провайдеров.
После свежей авторизации второго аккаунта backend сохраняет подписанное доказательство владения
на 10 минут. GET /api/account/merge/status показывает способы повторного входа в текущий,
сохраняемый аккаунт. OAuth с purpose=merge подтверждает именно его уже привязанную identity;
passkey использует /api/account/merge/passkey/options и /api/account/merge/passkey/verify.
При доступном email-входе можно вместо этого запросить код через
POST /api/account/merge/request. Включённый SMTP и подтверждённый email не обязательны,
если аккаунт подтверждается провайдером или passkey.
POST /api/account/merge/confirm завершает объединение после явного согласия пользователя:
передаётся email_code либо пустое тело после повторного входа. POST /api/account/merge/cancel
отменяет сохранённое подтверждение. Доказательства привязаны к участникам и конкретной попытке;
сервер повторно проверяет владельца identity под блокировкой обоих аккаунтов.
Сохраняется текущий аккаунт, его Minishop ID, права и основные настройки; способы входа и
связанные данные второго переносятся штатным механизмом. Разные identity одного провайдера,
несовместимые права и другие конфликты отклоняются без частичного переноса.
Аккаунт с историей административных ролей требует отдельного ручного разбора. Удалённый
числовой ID записывается как исторический alias для старых обязательств, но не даёт доступа
старой сессии. Если сверка двух записей панели не завершилась, ответ помечает
panel_reconciliation_pending; оператор проверяет связи и доступ перед закрытием инцидента.
Прежние /api/account/telegram/merge/request и /confirm остаются совместимыми со сценарием
email-кода и свежих подписанных Telegram-данных.
Отдельно синхронизация автоматически объединяет записи панели с одинаковым Telegram ID, когда основная запись уже привязана к аккаунту Minishop. Например, при добавлении Telegram ID к единственной ранее созданной вручную записи сохраняются именно её UUID, username и нативная ссылка подключения. Подписка Minishop сохраняет свой ID, тариф, оплаченные лимиты, историю и согласие на продление; активные сроки объединяются, а существующая публичная ссылка Minishop перепривязывается к сохраняемой записи без замены токена. Созданный магазином дубль удаляется только после успешного обновления сохраняемой записи. Повтор после сбоя не начисляет дни второй раз и учитывает последующие покупки, смену лимитов или отмену подписки. Несколько внешних записей или неизвестное происхождение требуют ручного разбора. Если дубль связан с другим локальным аккаунтом Minishop, используется описанная выше процедура подтверждения обеих учётных записей.
После создания аккаунтов, чей внутренний ID отличается от Telegram ID, старый образ приложения небезопасен: он снова считает числовой ключ Telegram-адресом. Используйте совместимый релиз, понимающий новые идентификаторы и роли, либо восстанавливайте базу и внешние операции на согласованную контрольную точку. Возврат одного образа не откатывает платежи или состояние Remnawave. Перед восстановлением остановите обработку новых вебхуков и сохраните их очередь для повторного воспроизведения.
Рекламные источники
Заголовок раздела «Рекламные источники»Кампании, ссылки, предложения и проверка источника покупки описаны в разделе рекламы.