Задача
Ресторанная сеть постоянно обновляет печатные материалы: меню, таблички, вывески, листовки, сезонные плакаты, канцелярию, стартовые наборы для новых локаций. Без единой платформы каждый такой запрос идёт письмом — с пересылкой файлов, уточнением тиража и адреса и ручной проверкой того, актуален ли макет.
Из этого вырастает набор системных рисков. Ресторан может напечатать прошлогоднюю версию меню или уже закрытой кампании. Локальная правка макета «на месте» ломает брендовые правила. Один и тот же запрос вводится заново в нескольких системах. Маркетинг тратит время дизайнера на замену адреса и даты. Превышение допустимого тиража обнаруживается только при ручной обработке. Складские остатки и допечатка рассматриваются раздельно, хотя это один и тот же заказ. Ресторан не видит статуса и уточняет его у людей. И самое неприятное: производственный файл, ушедший в типографию, может отличаться от версии, которую согласовали.
Решение
DAMS как источник истины по контенту. Отдельная система на Symfony хранит рабочие исходники, print-ready версии, превью, утверждённые шаблоны, сезонные кампании и региональные варианты. Карточка продукта отделена от файла: к одной позиции привязываются исходник, превью, печатный PDF, локализованные варианты и дополнительные изображения. Один asset может лежать в нескольких логических коллекциях — в кампании, в категории signage и в подборке региона — без физического дублирования.
Публикация без двойного ввода. Из DAMS карточки публикуются в каталог Magento вместе с идентификатором, категориями, вариантами, производственным файлом и правилами видимости. Обмен версионный и идемпотентный: повтор события не создаёт вторую карточку, замена файла обновляет только свою версию, снятый с публикации материал исчезает из новых заказов, но остаётся в истории, а уже оформленный заказ продолжает ссылаться на конкретную утверждённую версию. Ошибка синхронизации уходит в очередь с безопасным повтором.
Генератор брендовых шаблонов. Вместо запроса к дизайнеру ресторан открывает утверждённый шаблон и заполняет только разрешённые поля — адрес, даты кампании, часы работы, локальное предложение. Логотип, типографика, цвета, отступы, обязательные подписи и технические зоны заблокированы. Известные данные подставляются из профиля локации, правила проверяют обязательные значения, длину текста и допустимость конфигурации, при необходимости макет уходит на согласование, и только после подтверждения генерируется зафиксированная print-ready версия — именно она попадает в заказ и в типографию. Шаблон и созданный экземпляр хранятся раздельно: обновление шаблона не меняет уже утверждённый заказ, но новые запросы берут актуальную версию.
Лимиты и пересчёт согласований. Превышение лимита не блокирует заявку, а переводит её на согласование. Матрица учитывает ресторан, регион и роль автора, категорию и материал, количество и внутреннюю стоимость, кампанию и период, стандартную или нестандартную конфигурацию, наличие остатка, срочность и способ доставки. Согласующий видит причину срабатывания правила, действующий лимит, выбранный макет и предполагаемый способ исполнения — и может утвердить, уменьшить количество, вернуть на изменение или отклонить с комментарием. Важная деталь: после правки количества, макета или адреса правила пересчитываются заново, и решение по предыдущей версии на изменённую заявку не переносится.
Выбор источника исполнения. Заказ может закрываться готовым остатком, новой печатью или их сочетанием. Оркестратор сравнивает наличие, расположение ресторана и склада, срок и стоимость перевозки, возможность и срок допечатки, загрузку вендора, обязательную дату кампании и стоимость разделённого исполнения. Наличие на удалённом складе не означает, что этим остатком выгодно пользоваться: если локальная допечатка быстрее перевозки, задание уходит типографии. Часть тиража при этом может приехать со склада, остаток — из печати, а ресторан видит один заказ с несколькими линиями исполнения и отдельным tracking на каждую посылку. Дешёвый вариант, не успевающий к запуску кампании, допустимым не считается.
Нестандартные заказы. Если нужной конфигурации нет в каталоге, пользователь заполняет структурированный бриф вместо свободного письма: тип материала, назначение и кампания, тираж и срок, размеры, материал, референсы, адрес. Запрос проходит свой workflow — проверка полноты, ответственный, уточнение, расчёт стоимости, согласование, макет, — а затем переводится в обычный производственный заказ и попадает в общий fulfillment и tracking, поэтому не выпадает из истории ресторана.
Идемпотентность и объяснимость. Повторный webhook не должен создавать второй заказ, резерв, print job или отправление: каждая внешняя операция хранит correlation id, исходное событие, результат и число попыток. При частичном сбое выполненная физическая операция не отменяется вслепую — оркестратор запускает компенсирующее действие. Правила, лимиты и approval-матрицы имеют период действия и версию, поэтому старый заказ можно объяснить настройками, которые действовали в момент его создания.
Архитектурно продукт повторяет схему Yokohama Print, адаптированную под ресторанную операционную модель.
Результат
Tender Greens получила единый контур управления печатными материалами сети. Маркетинг и дизайнеры владеют источниками и версиями в DAMS, рестораны заказывают только разрешённые позиции, а типовые локальные правки выполняются через безопасные брендовые шаблоны, не проходя через дизайнера.
Согласования, склад, print-on-demand, доставка и tracking перестали быть разрозненными ручными процессами. Каждая заявка сохраняет связь между рестораном, утверждённой версией макета, решением согласующего, источником исполнения и конкретным отправлением, а корпоративный вход и серверная авторизация не дают обойти лимит прямой ссылкой или чужим идентификатором локации.
Операционная аналитика показывает спрос по ресторанам и кампаниям, время согласований, долю смешанного исполнения и загрузку типографий — по ней видно, какие повторяющиеся нестандартные заказы пора превратить в обычную карточку каталога.