Smoke Test — Production Deploy
Когда использовать
Сразу после того, как админ выкатил все сервисы в k8s (или на VPS) и говорит «вроде поднялось». Цель — за 30–40 минут глазами тестировщика убедиться, что каждый микросервис собрался, отвечает и работает в связке с остальными.
Тест не проверяет бизнес-логику в глубину — для этого есть E2E тест-кезс — ИП от аккаунта до закрытия смены и E2E Test Scenarios. Здесь только «живой / мёртвый».
Как читать этот документ
Каждый шаг устроен одинаково:
👉 Что нажать в интерфейсе
✅ Что должно произойти
🟢 Какой сервис подтверждён живым
Если на шаге что-то пошло не так — остановись и зови админа, не имеет смысла идти дальше: следующие шаги опираются на текущий.
Подготовка
- URL админки:
https://erp-test.nirbi.ru(или прод-URL, который дал админ) - Тестовый аккаунт владельца франшизы:
demo@nirbi.ru / admin123(демо-тенант) либо созданный админом свежий - Браузер: Chrome / Firefox в обычном режиме (НЕ инкогнито — нужны localStorage и cookies)
- Открыть DevTools (F12) → вкладка Network и Console — пусть будут открыты всю сессию, чтобы видеть 500-е и красные ошибки
- POS Desktop: установлен на тестовой машине (или планшет с Android-сборкой POS, если есть)
Блок 0. Базовые health-check’и (1 минута)
Перед тем как лезть в UI — быстро прокликать, что фронт вообще открывается.
| Шаг | Что нажать | Ожидание | Проверяет |
|---|---|---|---|
| 0.1 | Открыть https://erp-test.nirbi.ru | Открывается страница логина (логотип, поля Email / Пароль, кнопка «Войти») | 🟢 Nginx + Admin BFF + Admin Web |
| 0.2 | F12 → Console | Нет красных ошибок типа «failed to fetch», «502», «net::ERR_…» | 🟢 SSL + сеть |
Если на 0.1 страница не открывается или висит «502 Bad Gateway» — дальше не идём, проблема в инфре (nginx, BFF упал, контейнер не стартовал).
Блок 1. Авторизация → Auth Service
1.1 Логин
👉 Ввести email + пароль владельца, нажать «Войти»
✅ - Редирект на /dashboard
- Сверху справа имя пользователя
- В меню слева видно разделы: Дашборд, Торговые точки, Каталог,
Склад, Сотрудники, Роли, Заказы, Клиенты, Интеграции
🟢 Auth Service (выдал JWT) + User Service (нашёл пользователя по email)
+ Admin BFF (прокинул запрос)
Если type=individual (ИП)
Раздел «Юридические лица» не виден — это нормально, так задумано в BR 1.4.4.
1.2 /auth/me работает
👉 F12 → вкладка Network → перезагрузить страницу
✅ Найти запрос GET /api/v1/admin/auth/me — статус 200, в ответе:
{ user, franchise, scope, permissions: [...] }
🟢 Auth Service (агрегация permissions) + Redis (кэш scope) + User Service
Если permissions пустой — у пользователя нет прав, дальнейшие шаги работать не будут. Зови админа.
Блок 2. Юридические лица → User Service (только для type=corporate)
Для ИП (individual) этот блок пропускается — у них одно главное ЮЛ создаётся при bootstrap.
2.1 Открыть список ЮЛ
👉 Меню «Юридические лица»
✅ Открывается список (минимум одна запись — главное ЮЛ франшизы),
нет ошибки 403/500
🟢 User Service (List endpoint)
2.2 Создать ЮЛ Франчайзи
👉 «Добавить» → выбрать тип «Франчайзи» → заполнить:
- Название: «ООО Тест Франчайзи»
- ИНН: 7700000000
- Email владельца: franchisee.smoke@example.com
- Пароль: TempPass123!
- Режим прав: «Полный доступ» (системная роль «Администратор»)
👉 Сохранить
✅ - ЮЛ появилось в списке
- В таблице «Сотрудники» появился новый сотрудник с email franchisee.smoke@…
🟢 User Service (атомарная транзакция ЮЛ + владелец)
Блок 3. Торговые точки → Store Service
3.1 Создать ТТ
👉 Меню «Торговые точки» → «Добавить»
- Название: «ТТ Smoke 001»
- Адрес: Москва, ул. Тестовая, 1
- Телефон: +7 (495) 000-00-00
- ЮЛ: главное ЮЛ
- Расписание: Пн-Вс 09:00-23:00
👉 Сохранить
✅ ТТ появилась в списке со статусом «Черновик»
🟢 Store Service (CRUD)
3.2 Опубликовать ТТ
👉 Открыть «ТТ Smoke 001» → кнопка «Опубликовать»
✅ Статус меняется на «Опубликована» (зелёный бейдж)
🟢 Store Service (state-машина)
3.3 Привязать POS-терминал
👉 Карточка ТТ → вкладка «POS-терминалы» → «Добавить»
- Заводской номер ФН: 9999000099990001
- РН ККТ: 0001234567000001
👉 Сохранить
✅ Терминал появился в списке, статус active
🟢 Store Service (POSTerminalController)
Блок 4. Каталог → Catalog Service ⭐ (главный по объёму)
4.1 Создать категорию
👉 Меню «Каталог» → вкладка «Категории» → «Добавить»
- Название: «Кофе»
👉 Сохранить
✅ Категория «Кофе» появилась в дереве слева
🟢 Catalog Service (categories CRUD) + Kafka (событие catalog.category.upserted)
4.2 Создать товар
👉 Вкладка «Товары» → «Добавить»
- Название: «Латте 0.3»
- Категория: Кофе
- Цена: 250
- КБЖУ: 120 ккал, 5/4/15
👉 Сохранить
✅ Товар появился в списке внутри категории «Кофе»
🟢 Catalog Service (products CRUD) + Kafka (catalog.product.upserted)
Это и есть «создал товар → каталог-сервис работает чётко». Если получилось — самый объёмный сервис жив.
4.3 Создать группу модификаторов
👉 Вкладка «Модификаторы» → «Добавить группу»
- Название: «Молоко»
- Тип выбора: один из
- Опции: Обычное (0₽), Безлактозное (+30₽), Овсяное (+50₽)
👉 Сохранить
✅ Группа «Молоко» появилась в списке с тремя опциями
🟢 Catalog Service (modifier_group_upserted в Kafka)
4.4 Привязать модификатор к товару
👉 Открыть товар «Латте 0.3» → вкладка «Модификаторы» → добавить группу «Молоко»
👉 Сохранить
✅ В карточке товара видно «Молоко (3 опции)»
4.5 Создать прейскурант
👉 Вкладка «Прейскуранты» → «Добавить»
- Название: «Базовый»
- Привязать к ТТ «ТТ Smoke 001»
- Цены: Латте 0.3 → 280₽
👉 Сохранить и применить
✅ Прейскурант создан и применён
🟢 Catalog Service (price-list module)
4.6 Стоп-лист
👉 Меню «Стоп-листы» → выбрать ТТ «ТТ Smoke 001» →
найти «Латте 0.3» → переключатель «В стоп»
✅ Появляется иконка «🚫 в стопе» рядом с товаром
🟢 Catalog Service (stoplist per-store)
После этого вернуть переключатель обратно — иначе позже на POS товара не будет.
Блок 5. Склад → Warehouse Service
5.1 Создать ингредиент
👉 Меню «Склад» → «Ингредиенты» → «Добавить»
- Название: «Молоко 3.2%»
- Единица: л
👉 Сохранить
✅ Ингредиент в списке
🟢 Warehouse Service (ingredients CRUD)
5.2 Создать техкарту для товара
👉 Открыть товар «Латте 0.3» → вкладка «Техкарта» →
«Создать» → добавить ингредиент «Молоко 3.2%», 0.2 л
👉 Сохранить
✅ Техкарта сохранилась, видна себестоимость
🟢 Warehouse Service (recipes)
5.3 Акт приёмки
👉 Меню «Склад» → вкладка «Приёмка» → «Создать акт»
- Склад: ТТ Smoke 001
- Добавить позицию: Молоко 3.2%, 10 л, 80₽/л
👉 Сохранить как черновик → затем «Провести»
✅ Акт получает статус «Проведён»
На вкладке «Остатки» видно: Молоко 3.2% — 10 л
🟢 Warehouse Service (acts + остатки + FIFO)
Блок 6. Сотрудники + Роли → User Service
6.1 Создать роль «Кассир»
👉 Меню «Роли» → «Добавить роль»
- Название: «Кассир Smoke»
- Permissions: pos.access ✅, orders.create ✅, payments.process ✅
- Зарплата: 350 ₽/час
👉 Сохранить
✅ Роль в списке, 0 сотрудников
🟢 User Service (roles + permissions)
6.2 Создать сотрудника-кассира
👉 Меню «Сотрудники» → «Добавить»
- ФИО: Тестов Тест Тестович
- Email: cashier.smoke@example.com
- Телефон: +7 (900) 000-00-00
- Роль: «Кассир Smoke» на ТТ «ТТ Smoke 001»
- PIN: 1234
👉 Сохранить
✅ Сотрудник в списке. PIN установлен (видно «PIN: ✅»)
🟢 User Service (employees + employee_role_stores) + Auth Service (pin_hash)
Блок 7. Клиенты → Customer Service
7.1 Создать клиента
👉 Меню «Клиенты» → «Добавить клиента»
- Имя: Иван Smoke
- Телефон: +7 (911) 111-11-11
- Email: ivan.smoke@example.com
👉 Сохранить
✅ Клиент в списке
🟢 Customer Service (customers CRUD)
7.2 Создать группу клиентов
👉 Меню «Клиенты» → вкладка «Группы» → «Добавить»
- Название: «VIP Smoke»
- Тип: статическая
👉 Сохранить → открыть → добавить туда Ивана Smoke
✅ В карточке Ивана видна метка «VIP Smoke»
🟢 Customer Service (customer_groups + scheduler)
Блок 8. POS-касса → POS BFF + Auth + Order Service
8.1 PIN-логин на POS
👉 Открыть POS Desktop → выбрать «ТТ Smoke 001» → ввести PIN: 1234
✅ - Открывается экран смены
- Сверху имя кассира «Тестов Т.Т.»
🟢 POS BFF + Auth Service (pin-login + pos.access check) + User Service (PIN lookup)
8.2 Открыть смену
👉 Кнопка «Открыть смену» → подтвердить
✅ Появляется главный экран кассы с меню (категории слева)
🟢 Order Service (shift open) + Catalog Service (отдача меню)
8.3 Создать заказ
👉 Тапнуть «Кофе» → «Латте 0.3» → выбрать модификатор «Овсяное»
→ «Добавить в заказ»
✅ Позиция в чеке справа: «Латте 0.3, овсяное — 330₽»
(280 базовая + 50 за овсяное молоко)
🟢 Catalog Service (меню с прейскурантом + модификаторы)
+ Order Service (создание заказа в статусе new)
8.4 Прикрепить клиента
👉 Кнопка «Клиент» → ввести «+7 911» → выбрать Ивана Smoke
✅ Имя клиента появилось в шапке чека
🟢 Customer Service (поиск по phone) + Order Service (привязка)
8.5 Оплата наличными
👉 «К оплате» → способ «Наличные» → ввести сумму → «Подтвердить»
✅ - Заказ закрыт (статус «Оплачен»)
- На экране «Чек выдан»
🟢 Order Service (фиксация оплаты + переход new → ready → closed)
8.6 Закрыть смену
👉 Меню кассы → «Закрыть смену» → «Z-отчёт»
✅ Открывается отчёт:
- Выручка: 330₽
- Заказов: 1
- По способам оплаты: Наличные 330₽
🟢 Order Service (/internal/orders/shift-report)
+ User Service (агрегатор отчёта смены)
Блок 9. Заказы в админке → Order Service (read-side)
9.1 Список заказов
👉 В админке: Меню «Заказы»
✅ Видно созданный заказ — № заказа, ТТ Smoke 001, 330₽, Оплачен,
клиент «Иван Smoke»
🟢 Order Service (list endpoint) + Customer Service (denorm имя клиента)
9.2 Детали заказа
👉 Открыть заказ
✅ Видны: позиции, модификатор «овсяное», способ оплаты, время,
привязанный клиент
🟢 Order Service (детали)
Блок 10. Интеграции → Aggregator Service + Paykeeper Adapter
Эти разделы нужны если соответствующие сервисы заявлены в скоупе деплоя. Если не заявлены — пропускаем.
10.1 PayKeeper — подключить аккаунт
👉 Меню «Интеграции» → «PayKeeper» → «Добавить аккаунт»
- ЮЛ: главное ЮЛ
- Host: koala-test.paykeeper.ru
- Логин/пароль: из секретов админа
- Informer seed: тестовый
👉 Сохранить → «Проверить соединение»
✅ Зелёная плашка «Соединение установлено»
🟢 Paykeeper Adapter (HTTP client + AES-GCM шифрование секретов)
10.2 Caталог-синк в PK (BR 3.4)
👉 На карточке аккаунта PK → «Запустить синхронизацию каталога»
✅ Прогресс-бар → отчёт «Синхронизировано N товаров, 0 ошибок»
🟢 Paykeeper Adapter (catalog sync) + Catalog Service (full snapshot endpoint)
+ Kafka (consumer группа)
10.3 Aggregator — подключить ТТ к Яндекс.Еде (если в скоупе)
👉 Меню «Интеграции» → «Агрегаторы доставки» → выбрать ТТ →
«Подключить Яндекс.Еду» → ввести OAuth credentials → Сохранить
✅ Статус подключения — «Активно»
🟢 Aggregator Service (binding CRUD + OAuth client)
Блок 11. Возврат через PayKeeper (если PK подключён)
Полный сценарий — в PayKeeper — возвраты. Здесь — короткий smoke.
11.1 Создать PK-заказ и оплатить
👉 На POS — выбрать ТТ с подключённым PK-терминалом → создать заказ →
способ оплаты «PayKeeper» → получить QR/ссылку → оплатить из ЛК PK
✅ Заказ переходит в paid, есть pk_payment_id
🟢 Paykeeper Adapter (invoice + informer webhook) + Order Service
11.2 Полный возврат
👉 В админке: открыть заказ → «Запросить возврат» → полная сумма
✅ - В Kafka событие order.refund_requested
- Платёж в ЛК PK уходит в refunding → refunded
- В админке статус заказа «Возвращён» (через webhook или через 3-5 мин через poll)
🟢 Paykeeper Adapter (reverse_payment + RefundCheckScheduler)
+ Order Service (refund_records)
Финальная сводка
После прохождения всех блоков — заполнить таблицу:
| Сервис | Блоки | Статус |
|---|---|---|
| Nginx + Admin Web + Admin BFF | 0, 1.1 | ⬜ |
| Auth Service | 1, 6.2 (PIN), 8.1 | ⬜ |
| User Service | 1.1, 2, 3 (через scope), 6 | ⬜ |
| Store Service | 3 | ⬜ |
| Catalog Service | 4, 8.2 (меню) | ⬜ |
| Warehouse Service | 5 | ⬜ |
| Customer Service | 7, 8.4, 9.1 | ⬜ |
| Order Service | 8.3, 8.5, 8.6, 9 | ⬜ |
| POS BFF + POS Desktop | 8 | ⬜ |
| Paykeeper Adapter | 10.1, 10.2, 11 | ⬜ |
| Aggregator Service | 10.3 | ⬜ |
| Kafka (косвенно) | 4.1, 4.2, 10.2, 11.2 | ⬜ |
| Redis (косвенно) | 1.2 (кэш scope) | ⬜ |
| PostgreSQL (косвенно) | везде, где «Сохранить» | ⬜ |
Если все строки зелёные — деплой принят.
Если хотя бы одна красная — собрать в одном сообщении админу:
- Какой блок упал (например, «4.2 — товар не сохраняется»)
- Что увидел тестировщик на экране (текст ошибки)
- Что в DevTools → Network: статус-код запроса, request URL, тело ответа
- Время по МСК — чтобы админ нашёл нужные строки в логах
Ссылки
- Deployment Runbook — как админ это всё деплоил
- E2E Test Scenarios — глубокие e2e сценарии (PayKeeper, refunds)
- E2E ИП — от аккаунта до закрытия смены — расширенный сценарий для ИП-тенанта
- Environments — что где живёт в k8s / VPS