Skip to main content

ferro_audit/
entity.rs

1//! SeaORM `Entity` / `Model` / `ActiveModel` / `Column` / `Relation` for the
2//! `audit_log` table (D-19).
3//!
4//! Schema authority is `migration.rs` (`CreateAuditLogTable`). This module's
5//! `Model` shape must match the migration's column declarations exactly:
6//! adding a column requires editing both files.
7
8use sea_orm::entity::prelude::*;
9use serde_json::Value as JsonValue;
10
11/// One row of the `audit_log` table. Persisted by `AuditEntry::write` and
12/// read by the query helpers (`history_for_target`, `recent_by_actor`,
13/// `recent`).
14#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
15#[sea_orm(table_name = "audit_log")]
16pub struct Model {
17    /// Client-generated UUIDv4 — set at `write()` time so the caller can
18    /// reference the entry before it hits the DB (D-21).
19    #[sea_orm(primary_key, auto_increment = false)]
20    pub id: Uuid,
21
22    /// Multi-tenant scoping; stringly-typed because ferro has no first-class
23    /// tenant primitive (D-13).
24    pub tenant_id: Option<String>,
25
26    /// Snake_case actor kind — see `AuditActor::kind()` in `actor.rs`.
27    pub actor_kind: String,
28
29    /// Stringly-typed actor id; `NULL` for `System` and `Anonymous` (D-05).
30    pub actor_id: Option<String>,
31
32    /// Required dotted-namespace action verb (e.g. `"inventory.stock.adjust"`).
33    pub action: String,
34
35    /// Target kind — `NULL` allowed because pure events have no target (D-10).
36    pub target_kind: Option<String>,
37
38    /// Target id (consumer-stringified primary key).
39    pub target_id: Option<String>,
40
41    /// JSON snapshot of the target's state BEFORE the action. `None` for
42    /// creations and pure events.
43    pub before: Option<JsonValue>,
44
45    /// JSON snapshot of the target's state AFTER the action. `None` for
46    /// deletions and pure events.
47    pub after: Option<JsonValue>,
48
49    /// Free-text reason / cause (e.g. `"order_committed"`,
50    /// `"stripe_webhook_payment_failed"`).
51    pub reason: Option<String>,
52
53    /// Caller-supplied correlation id; future framework plumbing may
54    /// populate this automatically (D-12 — deferred to a later phase).
55    pub correlation_id: Option<Uuid>,
56
57    /// DB-stamped timestamp (D-22); set by `DEFAULT CURRENT_TIMESTAMP` and
58    /// re-fetched after INSERT per RESEARCH Pitfall 1 / F-12.
59    pub created_at: DateTime,
60}
61
62/// No foreign keys in v0 (D-19, D-25).
63#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
64pub enum Relation {}
65
66impl ActiveModelBehavior for ActiveModel {}