Сессия 2026-05-05 — E2E цепочка Admin → POS → KDS

Первый сквозной прогон тест-плана chain-admin-pos-kds. Гибридный режим: Claude через admin-bff API, Александр на POS desktop, координация через чат.

Цель

Подтвердить корректность цепочки Admin → POS → KDS на 60-кейсовом плане. Найти расхождения с документацией и баги.

Сетап

  • Стенд https://erp-test.nirbi.ru (см. stand.md)
  • Учётки: admin@erp.local + petr@ + ivan@ (Anna admin-login отказан by-design)
  • POS desktop у Александр с PIN 1234 / 4321
  • KDS desktop у Александр на тех же PIN

Что сделали — по этапам

Этап 0: Reverse-engineering стенда

  • Логин под admin → JWT
  • Snapshot 11 разделов API: stores, products, categories, kitchen-stations, modifier-groups, kds/devices, pos/devices, kds/settings, orders, refunds, kitchen-queue, menu-availabilities, price-lists
  • Скачали admin SPA bundle (980 КБ) + POS bundle (380 КБ) для реверса URL/headers
  • Обнаружили: pos-bff (/api/v1/pos/*) снаружи стенда недоступен — все запросы падают в catch-all admin-bff
  • KDS-web нет — только Tauri-десктоп

Этап 1: Admin → POS пропагация (через admin-bff)

Прогнали 6 / 24 кейсов:

  • TC-CHAIN-001 (создание товара) ✅
  • TC-CHAIN-002 (rename) ✅
  • TC-CHAIN-003 (PATCH base_price) ⚠ → нашли F6a (тихо игнорируется)
  • TC-CHAIN-004 (DELETE) ❌ → F9 (500 для товара в состоянии F8)
  • TC-CHAIN-006 (toggle available_in_all_stores) ❌ → F8 (потеря store_ids)
  • TC-CHAIN-011 (cascade) ⚠ → не подтвердить из-за F10 (GET categories/{id} 404)

Стопы (TC-020..023) — endpoint не нашли с первого подхода, отложили в стадию 2.

Этап 2: Стадия 1 — API-only расширения

  • Модификаторы: создали 7 групп с разными неправильными вариантами → найдены F30, F31, F32, F33, F34
  • Флаги товара: 5 кейсов → найден F35 (open_price + by_weight mutex)
  • Нумерация заказов: пропуски #22 и #25F24 (по гипотезе Александр = симптом F25/F37)
  • RBAC регрессия Курьера (расширенная) → F13 расширен до 7 эндпоинтов, F15 расширен до 4 эндпоинтов, F4 расширен до 6 routes

Этап 3: Стадия 2 — координация POS desktop

Александр на POS, Claude через admin/orders + admin/kitchen-queue:

  • TC-CHAIN-051 (KDS «Готово») — заказ #026 PASS, latency 32 сек
  • TC-CHAIN-070 (денорм имени) — Кола→ОРИГИНАЛ → заказ #033 → revert → PASS
  • TC-CHAIN-071 (денорм цены) — unit_price=80 frozen → PASS
  • TC-CHAIN-018 (изменение цены через price-list) — заказ #035 unit_price=100 → PASS (нашли правильный endpoint /price-lists/{id}/items)
  • TC-CHAIN-052 (оплата → closed) — заказ #026 закрыт, fiscal_data + paykeeper полные → PASS, но F25 (заказ исчез из POS UI), F26 (RRN/card_last4 null)
  • F27 confirmed: на POS нет UI кнопки cancel ни на одном статусе (API работает — отменили #028 через POST /orders/{id}/cancel)
  • F37 NEW: на POS нет журнала закрытых заказов (только агрегаты)
  • TC-CHAIN-031: только не-кухонные → не на KDS — PASS
  • TC-CHAIN-033: микс кухня+некухня → KDS показывает кухонную + строкой «(поз. на других станциях)» — PASS
  • TC-CHAIN-058/059 (per-position): заказ #030 (Кола+Шаурма), Кола auto-ready, Шаурма pending — PASS
  • TC-CHAIN-032 (микс кухня+бар) — BLOCKED F2 (Бар пустой) + F3 (KDS без станции) + F40 (категория Кофе скрыта)

Этап 4: Стопы + временные меню

  • TC-CHAIN-020 (стоп товара): Кола в стоп → исчезла с POS — PASS
  • TC-CHAIN-021 (снятие со стопа): Кола вернулась — PASS
  • TC-CHAIN-022 (стоп категории): Десерты в стоп — backend OK, UI нельзя проверить (F40)
  • TC-CHAIN-024 (часть): правило menu-availability Десертов 14-22 → деактивация → Десерты появились на POS → подтверждение F40: правила работают наоборот / всегда скрывают
  • F39 NEW: stop с reason: null принимается без валидации

Этап 5: Стадия 3 — модификаторы привязка

  • Создали тест-товар + тест-группу min=1 max=2, 3 опции
  • PATCH product с modifier_group_ids → ничего не привязалось (F41)
  • POST /products/{id}/modifiers → привязалось (правильный endpoint)
  • На POS: max=2 enforce работает (3-ю не выбрать), но без подсказки → F42 UX
  • Заказ #036 показал unit_price+0+0=50 → подозрение на F43 (display)
  • Реверс: price опции не возвращается в API — лежит в price-lists/{id}/items.modifier_items отдельно
  • POST modifier-groups с options[].price → не записал → F44 (silent ignore)
  • PATCH /price-lists/{id}/modifier-items с правильным body → updated_count=1
  • Заказ #037 → unit_price=50 + B=10 = total 60 → F43 RETRACTED (backend и UI работают, проблема была в F44)

Этап 6: Контракт цен — финал

Раскрыто:

  • Цены товаров: PATCH /price-lists/{id}/items body {items: [{product_id, price}]}
  • Цены опций: PATCH /price-lists/{id}/modifier-items body {items: [{modifier_option_id, price}]}
  • Привязка модификаторов: POST /products/{id}/modifiers body {modifier_group_id, binding_type}
  • Default-прейскурант применяется неявно к ТТ без price_list_id (F1 уточнение)
  • F6 split: F6a Critical (PATCH product тихо ignores base_price) + F6b Minor (GET без цены)

Findings этой сессии

См. полный список с деталями в findings.md. Кратко:

🔴 Critical (8): F3, F6a, F8, F9, F13, F14, F15, F25, F27, F37 🟡 Major (12): F1, F4, F6b, F10, F16, F21, F24, F26, F30, F31, F32, F40, F41, F44 🟢 Minor (10): F2, F5, F7, F33, F34, F35, F39, F42, F45 ⚪ Retracted/by-design: F11, F12, F19, F20, F22, F28, F29, F38, F43

Ретракции:

  • F38 (POS фильтрует товары без активных KDS на станции) → оказалось F40
  • F43 (POS не считает цену опций при показе total) → оказалось F44

Прогон сценария

См. галочки в chain-admin-pos-kds.md.

Артефакты

  • Snapshot стенда: D:\Project\ERP\.work\snapshot\ (16 файлов JSON)
  • Bundle файлы: D:\Project\ERP\.work\admin-bundle.js, pos-bundle.js
  • Тестовые тела + ответы: D:\Project\ERP\.work\run\
  • Полная версия отчёта (для разработчика): archive/BUGS-FOR-DEV.md + BUGS-FOR-DEV-stage2.md + BUGS-FOR-DEV-stage3.md

Что в todo.md записать

См. todo.md:

  • Завтра — регресс по фиксам коллеги-разработчика
  • E2E с нулевой франшизой
  • 39 непрогнанных кейсов сценария chain-admin-pos-kds
  • Доменные exploratory: Aggregator, External menus, PayKeeper