1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! [`AggregateRoot`] — the transactional consistency boundary.
//!
//! Layers DDD identity + invariants over
//! [`atomr_persistence::Eventsourced`]. Every aggregate is event-sourced;
//! `AggregateRoot` adds:
//!
//! * a typed [`AggregateRoot::Id`] (the identity DDD requires),
//! * a default [`AggregateRoot::check_invariants`] hook for global
//! post-apply checks the framework runs at strategic points
//! (recommended: after every command's events are applied).
//!
//! The associated `Command` is required to implement
//! [`crate::Command`] with a matching `AggregateId`, so the framework
//! can route commands without dynamic dispatch.
use Hash;
use Eventsourced;
/// DDD aggregate root. One per consistency boundary; every command and
/// every event passes through one of these.
///
/// **Note on bounds.** The matching constraints
/// `<Self as Eventsourced>::Command: Command<AggregateId = Self::Id>`
/// and `<Self as Eventsourced>::Event: DomainEvent` are *not* expressed
/// as a supertrait `where`-clause here, because Rust's MSRV-stable
/// trait machinery propagates such clauses awkwardly through every
/// usage site. The patterns that actually consume these bounds (e.g.
/// [`crate::cqrs::CqrsPattern`]) re-state them at their own builder /
/// impl sites. Do implement [`crate::Command`] for your `Command`
/// type and [`crate::DomainEvent`] for your `Event` type.