Перейти к содержанию

Панам — новая платформа. Проектная документация

Новая система продажи товаров: монолит на Kotlin + Spring Boot, админка на React + Ant Design, источник номенклатуры и приёмник заказов — iiko Transport (api-ru.iiko.services).

Заменяет связку legacy-сервисов: PHP/Laravel site (сайт, админка Orchid, заказы, импорт iiko), Go menu (второй импорт iiko + API меню), Go payment, Go user, Node notification.

Состав документации

Документ Содержание
01-architecture.md Границы системы, модульный монолит, стек, нефункциональные требования
02-catalog-domain.md Доменная модель каталога и полная схема БД (DDL)
03-iiko-sync.md Синхронизация с iiko: организации, меню, стоп-листы, ревизии, отказоустойчивость
04-admin-catalog.md ТЗ на админку каталога: экраны, сценарии, поведение
05-catalog-api.md Контракты API: публичная витрина + админский API
06-decisions.md Принятые решения (ADR), открытые вопросы, план работ
07-media.md Изображения: инвентаризация размеров, пресеты, загрузка, нарезка, отдача
08-frontend-logic.md Разбор логики legacy-витрины и legacy-бэкендов: что переезжает на бэкенд (доставка, зоны, режим работы, слоты, гейт оформления)
09-order-flow.md Жизненный цикл заказа в legacy: статусы, отправка в iiko, оплата, отмена, уведомления — и постановка для модуля order
10-notifications.md Уведомления: клиентский контур (TG/MAX/SMS), служебный контур (MAX-чаты), почта и ошибки — и постановка для модуля notifications

Границы первого этапа

В скоупе: каталог — импорт номенклатуры из iiko, доменная модель товара, админка каталога, публичное API витрины, медиа-хранилище, стоп-листы (чтение), справочники организаций и терминалов.

Вне скоупа первого этапа (проектируется позже): корзина и заказы, отправка заказов в iiko и статусы, оплата, клиенты и авторизация покупателей, скидки/промокоды/акции, доставка и зоны, уведомления, статистика.

Уточнение по итогам разбора витрины (08-frontend-logic.md): справочник организаций с расписанием и статусом точки и перенос SEO-контента категорий входят в первый этап — без них новая витрина не покажет режим работы и потеряет SEO. Зоны доставки, слоты «ко времени» и гейт оформления остаются на этапе заказа.

Каталог спроектирован так, чтобы заказ мог сослаться на catalog.product_variantiiko.item без переделки модели.

Ключевые решения (кратко)

  1. Два жёстко разделённых слоя данных. Схема iiko — зеркало источника, пишется только импортом, для человека read-only. Схема catalog — витрина, владелец — админка. Связь только через явные ссылки. Ни одно поле не «редактируется поверх» импорта.
  2. iiko — источник истины по ценам, составу и наличию. Админка владеет мерчандайзингом: структура каталога, картинки, сортировка, SEO, бейджи, видимость, тексты-переопределения.
  3. Витринное дерево категорий — собственное. itemCategories и productCategories из iiko используются только как сырьё для импорта и подсказок, а не как структура сайта.
  4. Товар — это карточка с вариантами. «Панам 25/30/35/40 см» — 4 отдельных блюда в iiko (itemSizes у всех длины 1, sizeId: null) и один товар на витрине. Сборка карточки — ручная, с автоподсказкой кандидатов при импорте.
  5. Один generic-товар вместо типизации таблицами. В legacy было dish_pizza, dish_snacks, dish_drinks, dish_non_food — каждый новый тип товара требовал миграции, модели, экрана. В новой модели тип товара — это данные (категория + ось вариативности + набор атрибутов), а не таблица.
  6. Модификаторы нормализованы, но состав и цена — на уровне блюда. Проверено на выгрузке: 243 блюда порождают 21 231 ссылку на 237 уникальных модификаторов (отсюда 19 МБ ответа), при этом состав группы отличается между блюдами, а цена одного модификатора зависит от блюда.
  7. Модульный монолит на Spring Modulith. Границы модулей проверяются тестом, а транзакционный outbox (Event Publication Registry) идёт из коробки — событие «меню импортировано» не теряется.
  8. Каталог собирается с нуля. Данные legacy не мигрируются: там товары разбиты по таблицам dish_pizza / dish_snacks / dish_drinks / dish_non_food, и перенос потянул бы за собой эту структуру. Мигрируются только пользователи, и это следующий этап.
  9. Привязка к iiko хранит снимок. Блюда в iiko случайно удаляют и пересоздают с новым itemId. Вариант товара помнит, чем была позиция, замена подбирается по SKU, перепривязка — одно действие; карточка, фото и SEO не теряются.

Данные, на которых основано проектирование

Разбор response.json — реальный ответ POST /api/2/menu (внешнее меню, 1 организация):

формат                 formatVersion=2, revision — сквозной счётчик изменений
itemCategories         15 категорий внешнего меню (витринная группировка iiko)
productCategories      34 учётные группы (бухгалтерская классификация iiko)
блюд                   243
itemSizes              243 (ровно по одному на блюдо, sizeId=null у всех)
типы                   type=DISH, orderItemType=Product, measureUnit ∈ {порц, шт}
групп модификаторов    704 вхождения / 24 уникальных имени / 11 вхождений без itemGroupId
ссылок на модификаторы 21 231 при 237 уникальных modifier itemId
организаций в ценах    1 (в проде — все организации внешнего меню, батчами по 10)