Как реализована обработка заказов и валидация переходов статусов?
Что проверяют
Вопрос про ваш реальный проект: умеете ли вы моделировать жизненный цикл сущности так, чтобы недопустимое состояние нельзя было получить в принципе. Следом почти всегда спрашивают, что будет, если два запроса одновременно меняют статус одного заказа.
Как отвечать
Опишите свою систему по каркасу и подставьте свои цифры: сколько статусов, сколько заказов в день, какие были инциденты.
- модель: статус меняется только методами агрегата (
order.Pay(),order.Ship()), свойствоStatusсprivate set. Правила переходов собраны в одном месте: таблица допустимых пар или библиотекаStateless, а неswitch, размазанный по сервисам; - ошибка перехода: недопустимый переход возвращает доменную ошибку или
Result, API отвечает409 Conflictс понятным кодом; - конкурентность: оптимистическая блокировка в EF Core через
rowversion([Timestamp]) или токен конкурентности; приDbUpdateConcurrencyExceptionзаказ перечитывается, и переход проверяется заново. Альтернатива: условныйUPDATE ... WHERE Status = @expected; - идемпотентность: платёжный шлюз повторяет вебхуки, поэтому повторный
Paidдля уже оплаченного заказа должен быть безопасным, в этом помогает ключ идемпотентности; - побочные эффекты: событие о смене статуса пишется в таблицу outbox в той же транзакции, а публикует его отдельный процесс. MassTransit умеет это из коробки;
- история: каждая смена статуса попадает в журнал с автором и временем.
Отдельно покажите тесты: [Theory] в xUnit перебирает все пары статусов и проверяет, что разрешены ровно нужные.
Если такой системы у вас не было, скажите прямо и опишите, как спроектировали бы её, опираясь на похожую задачу из своего опыта.
Где спотыкаются
Проверяют переходы только в контроллере или на фронтенде, а у сущности публичный сеттер. Любой новый код или фоновая задача обходит правила.
Не думают о гонках: оператор отменяет заказ, пока приходит подтверждение оплаты, и заказ оказывается отменённым и оплаченным одновременно.
Отправляют письмо или сообщение в брокер до коммита транзакции. При откате клиент получает уведомление о статусе, которого в базе нет.