ADR-011: Версионность каталога — нужна ли для управления обновлениями меню
Статус
Accepted — двухуровневое версионирование (товары + каталог).
Принятое решение
Двухуровневое версионирование:
- Товары версионные — каждое изменение (поля, техкарта) создаёт новую версию товара
- Каталог = версионный список ссылок на конкретные версии товаров (draft → published → archived)
- При изменении товара → новая версия товара → draft каталога с обновлённой ссылкой
- Неизменённые товары — ссылки остаются прежними
- Published каталог “заморожен” — изменение товара не ломает published
Контекст
Сейчас каталог мутабельный без версионности (ADR-008, BR 1.7). Франшиза меняет каталог → изменения мгновенно видны всем. Меню франчайзи (BR 1.11) версионируется отдельно.
Проблема
Франшиза добавила 10 новых товаров, изменила описания 5 существующих, убрала 3. Это большое обновление каталога. Что происходит:
Без версионности (текущее решение):
- Каждое изменение применяется мгновенно
- Франчайзи не знает что каталог обновился — нет уведомления “каталог изменился”
- Новые товары недоступны (default deny) — но франчайзи не знает что появились новые товары для его ТТ, пока франшиза не разрешит и франчайзи сам не заглянет в редактор меню
- Удалённые товары скрываются от клиентов мгновенно — франчайзи видит “недоступен” в меню, но не понимает почему
- Нет понятия “версия каталога 2.0” — только непрерывный поток изменений
С версионностью каталога (предлагаемая логика):
- Франшиза работает с черновиком каталога — изменения не видны никому
- Франшиза публикует новую версию каталога → франчайзи получает уведомление “Каталог обновлён до v5”
- Франчайзи сам решает когда обновить своё меню под новый каталог — открывает diff (что добавлено, что убрано, что изменилось), обновляет меню в удобное время
- До обновления меню — клиенты видят прежнее меню (по опубликованному меню + старые товары)
- Это управляемый процесс, а не “каталог поменялся → всё мгновенно поехало”
Ключевой вопрос
Текущий подход (мутабельный каталог) означает что франшиза при любом изменении может сломать меню франчайзи — удалить товар который продаётся, деактивировать категорию. Формула видимости (5 шагов) защищает клиента, но франчайзи не контролирует когда изменения до него дойдут.
Версионность каталога даёт франчайзи контроль: “Я вижу что каталог обновился. Я обновлю своё меню в понедельник, когда смена закончится.”
Рассмотренные варианты
A. Без версионности (текущее решение)
Каталог мутабельный. Изменения мгновенные. Меню франчайзи версионируется отдельно. Защита клиента — через формулу видимости.
| Плюс | Минус |
|---|---|
| Просто | Франшиза может “сломать” меню мгновенно |
| Как в iiko | Франчайзи не контролирует когда обновления доходят |
| Меньше кода | Нет понятия “версия каталога” — сложно отслеживать что изменилось |
B. Версионность каталога (draft → published)
Каталог версионируется как меню: франшиза работает с черновиком, публикует версию. Франчайзи видит уведомление и сам решает когда адаптировать меню.
| Плюс | Минус |
|---|---|
| Франчайзи контролирует когда обновить | Сложнее: нужна версионность всех сущностей каталога (товары, категории, модификаторы) |
| Франшиза может подготовить большое обновление | Два “слоя” версионности (каталог + меню) — сложнее понять |
| Уведомление “каталог обновлён” | Что если франчайзи игнорирует обновление месяц? |
| Diff “что изменилось” | Версионность каталога целиком (снапшот) — тяжёлая модель данных |
C. Каталог мутабельный + уведомления об изменениях (компромисс)
Каталог без версионности (как сейчас). Но при изменениях — уведомление франчайзи: “Франшиза добавила 10 товаров, убрала 3”. Франчайзи не контролирует когда изменения применяются к каталогу, но знает о них и может обновить меню.
| Плюс | Минус |
|---|---|
| Простая реализация (аудит-лог + уведомления) | Франчайзи не контролирует — удалённый товар пропадёт мгновенно |
| Франчайзи информирован | Не решает проблему “сломанного меню” |
| Не нужна версионность |
Влияние на архитектуру
Если Вариант A (без версионности)
- Catalog Service: мутабельные CRUD, без lifecycle
- Меню франчайзи: при каждом открытии редактора видит актуальный каталог
- Удалённые/деактивированные товары мгновенно скрываются от клиентов
- ADR-008 (аудит-лог) даёт историю, но не контроль
Если Вариант B (версионность)
- Catalog Service: draft/published lifecycle для каталога целиком
- Нужна модель “catalog_version”: снапшот или diff-based
- Меню франчайзи: при открытии редактора видит последнюю published версию каталога
- Франшиза может работать с черновиком каталога параллельно
- Notification Service: уведомление франчайзи о новой версии
- Значительно сложнее — затрагивает все сущности (товары, категории, модификаторы, прейскуранты)
Если Вариант C (уведомления)
- Catalog Service: мутабельные CRUD (как сейчас)
- Добавить: Kafka-событие
catalog.updated→ Notification Service → push/email франчайзи - Аудит-лог (ADR-008) используется для формирования “что изменилось”
- Меню франчайзи: при открытии видит актуальный каталог + баннер “Каталог обновлён, проверьте меню”
Дополнительное требование: отчёт по переходу ТТ на новый каталог
Независимо от выбранного варианта — франшизе нужно видеть какие ТТ перешли на актуальный каталог, а какие нет.
Зачем
Франшиза опубликовала обновление каталога (или просто внесла важные изменения). Ей нужно знать:
- ТТ “Центр” — меню обновлено под новый каталог ✅
- ТТ “Вокзал” — меню НЕ обновлено, работает по старому составу ⚠
- ТТ “Фудкорт” — меню НЕ обновлено 3 недели ❌
Без этого отчёта франшиза не контролирует единообразие сети.
Как реализуется в каждом варианте
Вариант A (без версионности): Сложно — нет понятия “версия каталога”. Можно косвенно: сравнить menu.updated_at с catalog_changelog.last_change_at. Если меню давно не обновлялось после изменений каталога → пометка “возможно устарело”.
Вариант B (версионность): Естественно — каждое меню ссылается на catalog_version_id. Отчёт: SELECT stores WHERE menu.catalog_version_id < current_catalog_version. Чётко видно кто на какой версии.
Вариант C (уведомления): Средне — можно отслеживать: уведомление отправлено → меню обновлено после уведомления или нет. Таблица catalog_update_notifications: { franchisee_id, notified_at, menu_updated_after: boolean }.
Этот отчёт — сильный аргумент в пользу Варианта B
Только при версионности каталога можно точно сказать “ТТ работает на каталоге v3, а актуальный — v5”. Варианты A и C дают лишь приближение.
Решение
Ожидает решения.
Вопросы для обсуждения:
- Насколько критична проблема “франшиза сломала меню”? Это реальный сценарий или теоретический?
- Готовы ли к сложности версионности каталога? Это значительно больше чем версионность меню.
- Достаточно ли уведомлений (Вариант C) вместо полной версионности?
- Насколько важен отчёт “какие ТТ перешли на новый каталог”? Это аргумент за Вариант B.