Event sourcing - замість поточного стану зберігається послідовність подій, що до нього призвели. Стан обчислюється «програванням» подій.
Звичайно: accounts: id=7, balance=150
Event sourcing: AccountOpened(id=7)
MoneyDeposited(7, 200)
MoneyWithdrawn(7, 80)
MoneyDeposited(7, 30)
→ balance = 150
Події лише додаються - ніколи не змінюються й не видаляються. Виправлення - нова подія (DepositCorrected), а не редагування старої.
Переваги:
- повна історія й аудит «з коробки»: не лише що зараз, а як і чому так сталося. Природно для фінансів, бухгалтерії, медицини, юридичних процесів;
- стан на будь-який момент у минулому - програти події до потрібної дати;
- нові подання даних заднім числом: придумали новий звіт - будуєте проєкцію з усієї історії подій, ніби він існував завжди;
- налагодження: відтворити точну послідовність, що призвела до помилки;
- природна інтеграція через події з іншими частинами системи.
Ціна - і вона значна:
- складність: проєкції для читання (CQRS практично обов'язковий), знімки (snapshots) для агрегатів з тисячами подій, обробка кінцевої узгодженості;
- еволюція подій: подія, записана три роки тому, має читатися й сьогодні. Зміна структури потребує версіонування й «апкастингу» старих подій;
- видалення даних: незмінний журнал конфліктує з правом на видалення персональних даних (GDPR). Рішення - шифрування персональних даних у подіях окремим ключем і знищення ключа (crypto-shredding);
- запити до поточного стану - лише через проєкції; «просто зробити SQL-запит» уже не вийде;
- команда має розуміти підхід - інакше помилки в проєкціях і подіях дорогі.
Коли варто: домен, де історія змін - сама цінність (рахунки, облік, бронювання, системи з аудитом), або де потрібні складні часові запити.
Коли не варто: CRUD, контентні сайти, більшість типових вебзастосунків. Журнал аудиту (spatie/laravel-activitylog) чи таблиця історії змін дають частину переваг без перебудови архітектури.
У Laravel-екосистемі є готові пакети (наприклад, spatie/laravel-event-sourcing), але вони не знімають концептуальної складності.