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

Модуль restaurant

Статус

Создан каркас Spring Modulith-модуля и публичная граница restaurant::api. Доменная модель, операции и таблицы ещё не реализованы.

Назначение

Модуль restaurant отвечает за представление ресторана на платформе и его жизненный цикл.

Модуль будет владеть:

  • стабильным идентификатором ресторана;
  • публичным названием и slug;
  • адресом и часовым поясом;
  • собственным статусом ресторана;
  • неизменяемой привязкой к организации iiko;
  • операционными блокировками;
  • активацией, временным отключением и окончательным закрытием;
  • read-only контрактом для будущей витрины.

Модуль не отвечает за:

  • франчайзи и юридические реквизиты;
  • подключение и HTTP-взаимодействие с iiko;
  • импорт организаций, меню и стоп-листов;
  • каталог и цены;
  • города, пригороды, микрорайоны и географические зоны;
  • заказы, платежи и чеки.

Географическая модель будет спроектирована отдельно, поскольку ей потребуется собственная логика городов, пригородов, микрорайонов и зон обслуживания.

Границы и зависимости

Разрешённые зависимости:

restaurant ──▶ franchise::api
restaurant ──▶ iiko::api

Через franchise::api модуль сможет проверять эффективную активность юридического лица и ФЧ. Через iiko::api — получать организацию и принадлежащее ей подключение.

Запрещены:

  • прямое чтение таблиц franchise и iiko;
  • зависимость franchise от restaurant;
  • зависимость iiko от restaurant;
  • изменение импортированных данных iiko из модуля ресторана.

Обратная связь выполняется событиями: restaurant реагирует на события других модулей, а модуль источника ничего не знает о потребителе.

Структура пакетов

ru.panampizza.monolith.restaurant
└── api
    └── RestaurantApi

Корневой пакет объявлен через @ApplicationModule. Пакет api объявлен через @NamedInterface("api"). Всё вне api является внутренней реализацией.

RestaurantApi пока является маркером границы. Реальные операции будут добавлены вместе с доменной моделью ресторана.

Целевой жизненный цикл

DRAFT ──▶ ACTIVE ⇄ DISABLED
  │          │          │
  └──────────┴──────────┴──▶ CLOSED
Статус Значение
DRAFT ресторан создан после импорта и ещё не доступен витрине
ACTIVE ресторан активен со стороны собственного жизненного цикла
DISABLED ресторан временно отключён вручную
CLOSED ресторан окончательно закрыт; статус терминальный

Исчезновение организации из iiko не переводит ресторан в CLOSED. Окончательное закрытие — отдельная бизнес-операция сотрудника ГК.

Неизменяемая привязка

Будущий ресторан создаётся для пары:

iiko_connection_id
iiko_organization_id

После создания эту пару нельзя изменить. При смене юридического лица или организации старый ресторан закрывается, а для нового объекта iiko создаётся новый ресторан с другим ID. Связь преемственности между ними не хранится; совпадающий адрес остаётся обычным атрибутом.

Операционная доступность

Собственный статус ресторана не перезаписывается при отключении владельца. Эффективная доступность складывается из собственного статуса и блокировок:

restaurant.status = ACTIVE
operational blocks = [FRANCHISEE_DISABLED]
effective availability = UNAVAILABLE

Планируемые причины блокировки:

  • FRANCHISEE_DISABLED;
  • LEGAL_ENTITY_DISABLED;
  • IIKO_CONNECTION_DISABLED;
  • IIKO_ORGANIZATION_UNAVAILABLE.

После снятия внешней причины собственный статус восстанавливать не требуется: ACTIVE остаётся ACTIVE, вручную DISABLED остаётся DISABLED, а CLOSED никогда не возвращается.

Планируемые события

Модуль будет реагировать на:

  • FranchiseeStatusChanged;
  • LegalEntityStatusChanged;
  • событие появления или изменения доступности организации iiko.

После первого успешного импорта новой организации модуль создаст ресторан DRAFT, если ресторан для пары подключения и организации ещё не существует.

Конкретные обработчики и таблица блокировок будут согласованы отдельными этапами.

Проверка модульности

Общий ModularityTests вызывает ApplicationModules.verify() и проверяет разрешённые зависимости, обращения к named interfaces и отсутствие циклов.

Следующий этап

iiko.connection уже привязан к LegalEntity. На этапе ручного тестирования apiLogin временно хранится открытым текстом внутри модуля iiko; перед production он будет зашифрован отдельным этапом. Следующий этап для этого модуля — создание ресторана из выбранной организации iiko с неизменяемыми владельцами.

Полная модель описана в архитектуре франчайзинга.

Доступ сотрудников ФЧ к созданию и настройке ресторанов описан в модели административного доступа.