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
66
67
68
69
70
71
72
73
74
75
//! # ferro-audit
//!
//! Append-only structured before/after audit log for the Ferro framework.
//!
//! Audit entries record *what happened* — for forensic investigation,
//! regulatory evidence, and state replay. They are the historical twin
//! of [`ferro-events`]: events are "something happened, react now";
//! audit entries are "something happened, here is the evidence forever".
//!
//! ## Example
//!
//! ```rust,ignore
//! use ferro_audit::{AuditEntry, AuditActor, AuditTarget};
//! use serde_json::json;
//!
//! AuditEntry::record("inventory.stock.adjust")
//! .actor(AuditActor::User(user_id.to_string()))
//! .target(AuditTarget::new("inventory.unit", unit_id.to_string()))
//! .before(json!({ "quantity": old }))
//! .after(json!({ "quantity": new }))
//! .reason("order_committed")
//! .write(&conn)
//! .await?;
//! ```
//!
//! ## Replay
//!
//! `AuditEntry::history_for_target(&target, &conn).await?` returns the
//! sequence of entries ordered ascending by `created_at`. Passing that
//! sequence to [`reconstruct_state`] folds each entry's `after` JSON into
//! a running object — the *replay* primitive.
//!
//! The fold is a **shallow object merge**: newer keys overwrite older
//! keys at the top level only. Nested objects and arrays are replaced
//! wholesale, not deep-merged. A consumer needing deep-merge runs its
//! own fold over the `Vec<AuditEntry>`.
//!
//! ## Schema and Migration
//!
//! ferro-audit ships a SeaORM migration as [`CreateAuditLogTable`].
//! Register it in your consumer-side `Migrator`:
//!
//! ```rust,ignore
//! impl MigratorTrait for Migrator {
//! fn migrations() -> Vec<Box<dyn MigrationTrait>> {
//! vec![
//! Box::new(ferro_audit::CreateAuditLogTable),
//! // ... your app migrations
//! ]
//! }
//! }
//! ```
pub use AuditActor;
pub use AuditEntry;
pub use AuditError;
pub use Migration as CreateAuditLogTable;
pub use prune_older_than;
pub use ;
pub use reconstruct_state;
pub use AuditTarget;
// Entity re-export for SeaORM-native consumer queries (D-25 — consumers
// needing pagination / custom filters drop down to sea-orm directly).
pub use Entity as AuditLogEntity;