Я знаю, что общая концепция источника событий заключается в том, что состояние приложения должно иметь возможность воспроизводиться из потока событий.
Однако иногда нам нужно получить информацию для бизнес-правил из других частей системы. т. е. у учетной записи есть пользователь. Пользователь имеет статус черного списка, который необходим для проверки того, может ли он получить доступ/редактировать учетную запись.
В приведенном ниже примере (исключительно для демонстрационных целей) пользователь пытается вычесть 10 долларов со своего счета. Если пользователь был занесен в черный список, мы не хотим позволять ему снимать какие-либо средства со счета, но мы хотим записать, что он пытался это сделать.
После того, как запрос сделан, мы можем запросить модель пользователя, чтобы узнать, существует ли черный список. Если это правда, мы можем записать это и выдать исключение.
Пользовательская таблица/модель в настоящее время не является источником событий.
Теперь, когда мы пытаемся воспроизвести поток событий, чтобы перестроить проекции с состоянием пользователя, не сохраняемым в событиях, это больше невозможно.
Итак, если мой текущий пример не работает, мои вопросы:
Если бы мы переместили пользователя в систему хранения событий (в другой агрегат, но все события в одном и том же потоке событий), то было бы приемлемо использовать модели чтения в бизнес-правилах?
Можем ли мы каким-либо образом смешать события, основанные на событиях, и CRUD в одной системе, когда они могут зависеть друг от друга для бизнес-правил.
public function subtractMoney(int $amount)
{
if ($this->accountOwnerIsBlacklisted()){
$this->recordThat(new UserActionBlocked());
throw CouldNotSubtractMoney::ownerBlocked();
}
if (!$this->hasSufficientFundsToSubtractAmount($amount)) {
$this->recordThat(new AccountLimitHit());
if ($this->needsMoreMoney()) {
$this->recordThat(new MoreMoneyNeeded());
}
$this->persist();
throw CouldNotSubtractMoney::notEnoughFunds($amount);
}
$this->recordThat(new MoneySubtracted($amount));
}
private function accountOwnerIsBlacklisted(): bool
{
return $this->accountRepositry()->ownerUser()->isBlackListed();
}