Laravel Event Sourcing (Spatie) - Использование прогнозов в рамках бизнес-правил - PullRequest
0 голосов
/ 18 октября 2019

Я знаю, что общая концепция источников событий заключается в том, что состояние приложения должно воспроизводиться из потока событий.

Иногда, однако, нам нужно получать информацию для бизнес-правил от другихчасти системы. т. е. учетная запись имеет пользователя. У пользователя есть статус черного списка, который требуется, чтобы проверить, могут ли они получить доступ к учетной записи или изменить ее.

В приведенном ниже примере (исключительно в демонстрационных целях) пользователь пытается вычесть из своей учетной записи 10 долларов США. Если пользователь занесен в черный список, мы не хотим разрешать ему снимать средства со счета, но мы хотим записать, что они пытались это сделать.

После того, как запрос сделан, мы можем запроситьМодель пользователя, чтобы увидеть, существует ли черный список. Если true, то мы можем записать его и выдать исключение.

Таблица / модель пользователя в настоящее время не получены из событий.

Теперь, когда мы пытаемся воспроизвести поток событий, чтобы перестроитьпрогнозы с состоянием пользователя не сохраняются в событиях, это больше невозможно.

Итак, если мой текущий пример не работает, мои вопросы:

  1. Если бы мы переместили пользователя в систему хранения событий (в другом агрегате, но во всех событиях в одном потоке событий), было бы приемлемым использовать модели чтения в рамках бизнес-правил?

  2. Можно ли каким-либо образом смешивать источники событий и 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();
}
...