Задача
Каждая станция приходит со своим договором, и почти всё в продукте от него зависит: какой каталог ей видно, какие категории и страницы доступны, сколько кредитов начисляется сразу и сколько повторяется каждый период, какой уровень членства действует, какие операции требуют согласования iMAR. Без общей платформы эти условия пришлось бы вручную переносить в рабочие системы: отдельно заводить доступ станции и её сотрудников, сверять лимиты, собирать подборки для победителей конкурсов, резервировать кредиты, согласовывать пакеты и передавать данные между CRM, бухгалтерией и системами бронирования.
Решение
Договор как конфигурация. Документ загружается в защищённый раздел и связывается с аккаунтом станции. ИИ-агент извлекает значимые условия и приводит их к параметрам платформы: статус договора и период действия, первоначальное и регулярное начисление кредитов, день и правила пополнения, уровень членства со сроком и преимуществами. Из договора же берутся доступные категории, продукты и CMS-разделы, роли и ограничения аккаунта, условия согласования. Исходный документ хранится рядом с созданной по нему конфигурацией, и сотрудник может проверить, из какого пункта договора взята каждая настройка.
Договорный модуль. Договор бывает в состояниях «ожидает», «активен», «на паузе», «отменён» и «завершён». Плановый процесс активирует договоры, срок которых наступил, и выполняет предусмотренное регулярное пополнение кошелька. Корректировки, паузы, возобновления и начисления попадают в историю, поэтому состояние кредитов восстанавливается по операциям, а не только по текущему остатку. Уровень членства проверяется вместе с договором и правами пользователя при открытии каталога и оформлении пакета.
У каждой станции свой каталог. Права применяются к товарам, категориям и контентным страницам, поэтому две станции с разными договорами видят разную витрину. В карточке пакета фотогалерея и обзор, регион, состав включённых услуг, программа поездки и дополнительные опции. Там же период доступности и крайний срок заявки, цена в кредитах и право конкретной станции на этот пакет, отметка о необходимости ручного подтверждения iMAR. Для нестандартного запроса есть индивидуальный пакет: станция описывает нужный формат, дальше его подхватывает операционная команда.
Самый неочевидный узел: гостевые списки. Победителю конкурса обычно не назначают поездку заранее: ему дают контролируемый выбор. Сотрудник станции собирает список из каталога, указывает данные получателя, задаёт допустимое число пакетов и предел по кредитам и отправляет защищённую ссылку с токеном. В момент отправки платформа резервирует максимально возможный объём кредитов, чтобы гость не выбрал пакет, который станция уже не в состоянии оплатить. Получатель открывает анонимную ссылку, видит только разрешённую подборку и выбирает в заданных границах; система автоматически создаёт заказ, а неиспользованная часть резерва возвращается в кошелёк станции. У списка есть состояния «ожидает», «отправлен», «использован» и «отменён»; приглашение можно отправить повторно или отменить.
Согласование и бронирование. Часть пакетов требует ручного согласования. При оформлении кредиты сначала резервируются, сотрудник iMAR проверяет доступность и может подтвердить заявку полностью, подтвердить допустимую часть или отклонить её; неиспользованный или отклонённый резерв освобождается автоматически. Для подтверждённого пакета создаются запись бронирования, связанный заказ и код активации; получателя можно назначить сразу или позже, после чего ему уходит уведомление. Подтверждённые данные передаются в системы бронирования, история взаимодействий и статусы — в CRM, финансовые документы и проводки — в бухгалтерию.
Кошелёк как журнал операций. Кошелёк станции показывает общую, доступную, использованную и зарезервированную части выделенных кредитов. У каждой операции есть тип и основание: договорное начисление, выделение кредитов подчинённому пользователю, резерв под гостевой список или бронирование, списание после подтверждения, возврат при отмене или частичном согласовании, ручная корректировка с причиной. Такой учёт отличает потраченные кредиты от временно зарезервированных и объясняет любое изменение баланса конкретным договором, пользователем, списком или заказом.
Архитектура. Витрина — PWA на Vue Storefront 1.12.3 и Vue.js 2 с SSR, service worker, установкой на устройство и push-уведомлениями. Она обращается к API на Node.js и Express, который связывает витрину с Magento 2.4.4, Elasticsearch и дополнительными модулями; Magento остаётся ядром торговой логики и административной панелью, а данные каталога синхронизируются в Elasticsearch отдельным процессом. Рядом работают Redis и Kue для очередей и фоновых задач и Varnish для кэширования; периодические операции ведут договорные начисления, смену состояний и синхронизацию данных.
Изоляция и история. Каталог, заказы, кошелёк и документы фильтруются по организации, группе покупателей, роли и индивидуальным разрешениям, а гостевой токен открывает только конкретную подборку и не даёт доступа к аккаунту станции. В истории записаны загрузка и применение договора, изменения статуса и движения кредитов: начисления, резервы, списания, возвраты. Там же отправка списка, выбор получателя, решения iMAR и последующая активация пакета. По этой истории финансовые и операционные исключения разбираются без ручного сведения данных из разных систем.
Результат
Условия бартерного договора больше не держат в голове: договор стал исполняемой конфигурацией продукта. Администратор станции видит в кабинете договор, уровень членства, кошелёк, активность сотрудников и бронирования, распределяет кредиты между подчинёнными пользователями и выгружает месячный отчёт по кредитам вместе с отчётами по продажам, лидерам продаж и брошенным корзинам. Сотрудник станции собирает подборку победителю за несколько минут и не рискует превысить бюджет: за лимитом следит резерв. Получатель выбирает поездку по одной защищённой ссылке, ничего не зная о внутренних лимитах станции. iMAR обрабатывает заявки в единой очереди согласований, где рядом с запросом видны условия договора, зарезервированные кредиты и доступность пакета во внешней системе бронирования.