Wow
Put the domain model at the heart of the system.
class CartSpec : AggregateSpec<Cart, CartState>(
{
on {
val ownerId = generateGlobalId()
val addCartItem = AddCartItem(
productId = "productId",
quantity = 1,
)
givenOwnerId(ownerId)
whenCommand(addCartItem) {
expectNoError()
expectEventType(CartItemAdded::class)
expectState {
items.assert().hasSize(1)
}
// …- Problem
- Complex business rules need traceable state changes and coordination across aggregates.
- Decision
- Model every write as command → domain decision → event → projection, and verify behavior with Given → When → Expect specifications.
- Trade-off
- Worth it where history and rules justify Event Sourcing; plain CRUD may not need the cost.