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