Итог тестирования 2026-05-12
Стенд: admin.nirbi.ru (PROD). Учётка тестера:
admin@erp.local / <password — см. private/creds.md>. Источники: сессияtest-base/sessions/2026-05-12-admin-prod-walkthrough.md, скриншотыtest-base/screenshots/2026-05-12-admin-prod-walkthrough/.
TL;DR
За день закрыто 9 разделов admin-панели + работа на POS/KDS. 27 пользовательских находок (F76-F102), плюс по 7 пунктам backlog обновлены статусы.
Состояние на конец дня:
- POS зарегистрирован на ТТ Smoke 001, Online. KDS зарегистрирован.
- Через UI нельзя задать PIN сотруднику или привязку к ТТ (F102). Делали через прямой PATCH с тем же endpoint что UI.
- admin@erp.local: PIN =
9999, привязан к ТТ Smoke 001 (роль Администратор). - Оплата картой отложена — PayKeeper-adapter недоступен.
- Стенд наполнен: 12 категорий, 13 ингредиентов, 5 модификаторов, 67 товаров с тематическими картинками, 82 цены в Базовом прейскуранте, 3 временных тарифа, 1 расписание меню (Завтраки 07-11), 2 в стоп-листе.
- POS/KDS happy-path запланирован на завтра.
🚫 BLOCKER — мешает работать прямо сейчас
F102 — Невозможно отредактировать сотрудника (PIN, привязка к ТТ)
Что видит пользователь: в карточке сотрудника жмёшь «Редактировать» → меняешь PIN или магазины роли → «Сохранить» → UI бесконечно висит на «Сохранение…» без сообщений. Перезагружаешь страницу — изменения частично применились (PIN записан как has_pin: true), но валидное состояние не достигнуто и UI не сообщил об ошибке.
Эффект на работу: на ТТ Smoke 001 не можем задать PIN сотрудникам → KDS логин по PIN не работает → POS/KDS happy-path заблокирован.
Где смотреть: PATCH /api/v1/admin/employees/<id> → возвращает 500 INTERNAL_ERROR на любое поле ({pin}, {pin_code}, {roles: [{role_id, store_ids}]}). Pod user-service-5dcbcb747d-l7gsl в namespace erp сам по себе здоров (Ready=1, Restarts=0), значит регрессия в свежем билде. UI кроме того не обрабатывает 500 и ERR_CONNECTION_CLOSED — нужен toast/баннер + сброс loading-state.
F78 — На странице ТТ во вкладке «Интеграции» показывается «Не удалось загрузить данные PayKeeper»
Что видит пользователь: открываешь карточку ТТ → вкладка «Интеграции» → сообщение «Не удалось загрузить данные PayKeeper». Подключить PayKeeper нельзя.
Где смотреть: GET /api/v1/admin/paykeeper/accounts/by-store/<store_id> → 500 «fetch failed». Сервис erp-paykeeper-adapter сейчас недоступен (на проде Kafka не поднята — Сано отметил). Дополнительно: даже после починки PK эндпоинт должен возвращать 200 + null если PK к ТТ не привязан, а не 500.
F100 — Импорт сотрудников из PayKeeper не открывается
Что видит пользователь: Сотрудники → «Выгрузить из PK» → «Нет активных интеграций PayKeeper. Сначала подключите PayKeeper в карточке юридического лица.» Подключить нельзя — см. F78.
Где смотреть: GET /api/v1/admin/paykeeper/accounts?status=active → 502 {"code":"PAYKEEPER_ADAPTER_UNAVAILABLE"}. UI же отдаёт пользователю общее «Нет интеграций», скрывая что сервис недоступен. Когда PK поднимется — F100 уйдёт сам.
🔴 CRITICAL — серьёзные пользовательские проблемы
F81 — В «Чаевые (Нетмонет)» на проде показаны фейковые цифры
Что видит пользователь: Финансы → Чаевые → таблица: ТТ «Кофейня Тверская» и «Кофейня Арбат», 4 официанта (Анна Белова, Борис Котов, Елена Сидорова, Максим Петров), 45 «транзакций» = 13 950 ₽, средний чек 310 ₽, журнал на 30+ строк. Этих ТТ и сотрудников в системе нет вообще — на нашей франшизе одна ТТ Smoke 001 и два сотрудника.
Эффект на работу: менеджер может принять решение на основе этих цифр.
Где смотреть: admin-spa маршрут /admin/tips. При открытии страницы — ни одного запроса к backend (только /auth/me). Данные захардкожены в коде SPA. Нужно: убрать mock, заменить на реальный API. Если API ещё не готов — показывать «Раздел в разработке» или скрывать пункт из sidebar до готовности.
F91 — Длинное название ТТ при сохранении ломает форму
Что видит пользователь: в edit-форме ТТ ввёл длинное название (~500+ символов) → «Сохранить» → ничего не происходит, UI остаётся на форме без сообщения. Изменение не сохранилось.
Где смотреть: PATCH /api/v1/admin/stores/<id> с длинной строкой → 500. Backend не валидирует длину (нужен 400 «Имя слишком длинное, макс N»), UI беззвучен на 500 (нужен toast). Также добавить maxLength на input.
F93 — Не сохраняется отредактированный шаблон смены
Что видит пользователь: Сотрудники → Шаблоны смен → выбираешь ТТ → «Изменить» на шаблоне → «Сохранить» → UI отображает успех, но изменения не применились.
Где смотреть: PUT /api/v1/admin/shift-templates/<id> → 500 даже без изменений. Подтверждает backlog BUG-018/019. Также UI после 500 не сообщает об ошибке.
F94 — Не сохраняется формула зарплаты «По роли»
Что видит пользователь: Сотрудники → Формулы зарплаты → «Изменить» на формуле → «Сохранить» → ошибки в UI нет, но изменение не применилось.
Где смотреть: PUT /api/v1/admin/salary-formulas/<id> → 500. Подтверждает backlog BUG-023. UI беззвучен.
F95 — Кнопка «Экспорт CSV» в Ведомостях не скачивает файл
Что видит пользователь: Сотрудники → Ведомости → «Экспорт CSV» → ничего не происходит, файл не скачивается.
Где смотреть: Клиент шлёт GET /api/v1/admin/payroll/?store_id=&period=2026-05/export → 422. URL составлен криво: пустой store_id + period с прилипшим /export. Скорее всего ошибка в template-литерале клиента. Подтверждает backlog BUG-024.
F98 — Кнопка «Дублировать» в карточке товара не работает
Что видит пользователь: Каталог → Товары → карточка → «Дублировать» → ничего не происходит, новой копии не создаётся.
Где смотреть: POST /api/v1/admin/catalog/products/<id>/duplicate → 500. UI без сообщения. Возможно конфликт имён (если backend не суффиксит «копия») или сам endpoint сломан.
F99 — Кнопка «+ Дочерняя» создаёт категорию на корневом уровне
Что видит пользователь: Категории → у существующей категории «Кофе» жмёшь «+ Дочерняя» → форма создания открывается без указания, что это подкатегория → создаётся на корневом уровне рядом с «Кофе». Иерархия не работает.
Где смотреть: форма создания при триггере с «+ Дочерняя» должна передавать parent_id. Сейчас, скорее всего, контекст родителя теряется в state SPA.
🟡 MAJOR — заметные баги, есть обход
F77 — При создании франчайзи можно ввести мусор в ИНН/ОГРН/Email
Что видит пользователь: Юр.лица → «+ Создать» → франчайзи → ИНН=5 цифр, ОГРН=7 цифр, Email без @ — нажимаешь «Создать» → клиент пропускает (только «Дата договора» подсвечена как обязательная).
Где смотреть: клиентская валидация на форме /admin/legal-entities/new. Нужно: pattern на ИНН (10 или 12 цифр), ОГРН (13 или 15), HTML5 type=email или regex. Серверная — отдельно (не submit’или, чтобы не плодить мусор).
F80 — Через 15 минут работы в админке всё перестаёт показывать данные
Что видит пользователь: через ~15 минут открываешь любой раздел → экраны рендерятся пустыми, «Не удалось загрузить», некоторые поля без значений. Логин-форма не появляется. Перезагрузка → редирект на /login, но иногда сразу обратно на dashboard и снова пусто. Где смотреть: SPA не обрабатывает 401 после истечения JWT — нет refresh-token flow, нет 401-interceptor → logout+redirect. JWT TTL ~15 мин.
F84 — Кнопка «Сохранить» в форме товара иногда «молчит»
Что видит пользователь: заполнил форму товара → жмёшь «Сохранить» → ничего не происходит. Если ввёл что-то невалидное в поле вне видимой области (например, отрицательное время приготовления внизу страницы) — браузерный popup появляется там, и его не видно.
Где смотреть: форма /admin/catalog/products/new использует только нативную HTML5-валидацию. Нужны кастомные сообщения под каждым полем (как на форме ЮЛ), плюс автоскролл к первому invalid-полю.
F90 — Если два менеджера одновременно правят одну ТТ, второе сохранение тихо затирает первое
Что видит пользователь: менеджер А открыл ТТ → менеджер Б открыл ту же ТТ → оба меняют название → оба нажали «Сохранить» → правка Б осталась, правка А потерялась без предупреждения.
Где смотреть: нет optimistic-lock. Минимум: при сохранении сравнивать updated_at от загрузки с текущим в БД → если изменился, показать «данные были изменены другим пользователем, обновите страницу».
F92 — Email-валидация работает в одной форме и не работает в другой
Что видит пользователь: в форме ТТ ввод неправильного email подсвечивается; в форме ЮЛ — пропускается без претензий.
Где смотреть: на форме ТТ поле email с type="email", на форме ЮЛ — обычный type="text". Унифицировать.
F96 — После сохранения некоторых форм появляется английская ошибка
Что видит пользователь: Сотрудники → Роли → создание роли с уже существующим именем → внизу формы появляется текст «Role with this name already exists». Русскоязычный пользователь не понимает. Где смотреть: UI выводит сырое сообщение от backend при 409 (и других кодах). Нужно мапить error code → русский текст в SPA.
🟢 MINOR — мелочи UI/UX
F76 — В карточке ЮЛ ссылка «1 ТТ» уносит обратно в список ЮЛ
Где смотреть: в карточке /admin/legal-entities/<id> блок «Основные данные» → поле «Торговые точки» → ссылка 1 ТТ имеет href="/admin/legal-entities". Должна вести на /admin/stores (с фильтром по этому ЮЛ).
F79 — Названия везде показываются с кавычками: "Кассир", "Латте 0.3", "Кофе"
Что видит пользователь: в списках сотрудников, ролей, товаров, категорий, модификаторов, прейскурантов отображаются названия в кавычках, как будто это литералы. И в фильтрах те же кавычки.
Где смотреть: какие-то поля имени сохранили в БД с обрамлением "...". Не убираются ни trim’ом, ни автоматически. Часть полей при создании trim’ит пробелы (категория, видел) — выборочная sanitization. Нужно: при сохранении убирать leading/trailing кавычки и пробелы единообразно.
F82 — В карточке товара можно ввести отрицательный вес и КБЖУ
Где смотреть: поля «Вес брутто/нетто (кг)», «Калории», «Белки», «Жиры», «Углеводы» — без атрибута min="0". У соседних number-полей («Порядок сортировки», «Время приготовления») min=0 настроен — inconsistency.
F83 — Поле «Цвет (HEX для POS)» принимает любой текст
Где смотреть: добавить pattern ^#[0-9A-Fa-f]{6}$ или color-picker.
F87 — В карточке товара поле «Категория» не отображается
Что видит пользователь: на странице товара виден тип, единица, статус, КБЖУ — но нет упоминания категории, к которой товар привязан. В списке товаров колонка «Категория» есть.
Где смотреть: компонент детальной карточки /admin/catalog/products/<id> не выводит поле category.
F88 — В подтверждении удаления названия с кавычками отображаются с двойными кавычками
Что видит пользователь: диалог «Удалить категорию ""Кофе""?» (двойные кавычки вокруг названия, у которого они уже внутри).
Где смотреть: UI оборачивает имя в кавычки → если имя уже с кавычками (см. F79), получается двойное обрамление. После фикса F79 проблема уйдёт.
F89 — В edit-форме ТТ селект «Прейскурант» содержит две опции «(дефолтный)»
Что видит пользователь: «По умолчанию (дефолтный)» и "Базовый" (дефолтный) — обе подписаны как дефолтный. Пользователь не понимает в чём разница.
Где смотреть: одна опция — null-placeholder, другая — реальный default-прейскурант. Убрать пометку у placeholder.
F97 — На форме создания роли «Отмена» уносит не в список ролей, а на предыдущую страницу
Что видит пользователь: из /admin/roles/new нажал «Отмена» → попал обратно туда, откуда зашёл (например, в /admin/employees/new).
Где смотреть: «Отмена» использует history.back(), нужен явный редирект на /admin/roles.
F101 — Кнопка «Улучшить с помощью AI» в edit-товаре не реагирует
Что видит пользователь: жмёшь кнопку — ничего. Ни модалки, ни запроса, ни ошибки. Где смотреть: скрыть кнопку до реализации фичи или показать «Скоро».
Backlog: статусы по итогам дня
| ID | Старое | Новое |
|---|---|---|
| BUG-002 (потеря фокуса) | open | verify-needed (на admin не воспроизводится — проверить под другой ролью) |
| BUG-005 (вкладки ЮЛ-карточки) | open | retracted (UI переделан: Реквизиты/ТТ/PayKeeper) |
| BUG-006 (404 на Save франшизы) | open | verify-needed (на admin не воспроизводится) |
| BUG-007 (поиск ФИО не работает) | open | verify-needed (на admin работает) |
| BUG-018, BUG-019 (Save шаблона смены 500) | open | reproduced = F93 |
| BUG-023 (Save формулы зарплаты 500) | open | reproduced = F94 |
| BUG-024 (Экспорт CSV 422) | open | reproduced = F95 |
| BUG-051 (default-прейскурант не привязан) | open | reproduced (Назначено ТТ=0, но используется в карточке ТТ) |
| BUG-060 (catalog/menu 500) | open | fixed |
Положительные подтверждения — что работает
- Пагинация, сортировка A-Я, поиск по части слова (case-insensitive) — всё работает.
- Inline toggle статуса товара в списке.
- Backend защищает от каскадного удаления: категория с товарами → понятное русское сообщение «в категории есть товары».
- Confirm-диалоги с «Это действие необратимо» на деструктивных действиях.
- Trim пробелов в категории при создании.
- PIN-валидация (4 цифры): блокирует буквы и >4 цифр.
- Восстановление товаров и ролей из «Удалённые».
- ЮЛ нельзя изменить у существующей ТТ (поле disabled с подписью).
- Скачивание XLSX-шаблона для импорта ЮЛ.
Что НЕ покрыто сегодня и почему
- RBAC под Manager/Franchisee/Кассир — нет credentials к существующим тестовым аккаунтам (по запросу пользователь решил пропустить).
- Реальный импорт ЮЛ.xlsx — нет файла с данными.
- Загрузка фото товара — не было тестового файла.
- Удаление терминала ТТ + эффект на ТТ.
- Деактивация ЮЛ (Активный → Приостановлен) + эффект на привязанные ТТ.
- Концепт «Приостановлена» для ТТ — есть в фильтре, но UI-переход не нашёл (не показано в карточке).
- POS/KDS happy-path (заказ → кухня → оплата → Z-отчёт) — заблокирован F102: нельзя задать PIN сотрудникам, KDS логин по PIN не пройдёт.
- PayKeeper-flow (оплата картой, фискализация через PK) — adapter недоступен, deferred до подъёма Kafka.
Артефакты [TEST]-объектов на стенде
- Товар
[TEST] Капучино 0.4(idd1224622-a76d-4bce-bee8-64bf2cc3411e) — в Удалённых. Hard-delete endpoint вернул 404, оставлен админу на очистку. - Остальные [TEST]-объекты вычищены.
Что в первую очередь отдать на фикс
- F102 — без него заблокирован POS/KDS happy-path.
- F81 — фейк-данные на продакшен-странице (риск принятия решений на основе мусора).
- F91 — backend падает 500 при длинном имени ТТ (риск рандомного 500 на любом пользовательском вводе длинной строки).
- F78/F100 — PayKeeper после поднятия Kafka. Заодно — добавить обработку 200+null для F78 (когда PK не привязан к ТТ).