1use serde::Serialize;
2
3use crate::db::{ColumnMap, FromRow};
4use crate::error::Result;
5
6#[derive(Debug, Clone, Serialize)]
11pub struct AuditRecord {
12 pub id: String,
14 pub actor: String,
16 pub action: String,
18 pub resource_type: String,
20 pub resource_id: String,
22 pub metadata: serde_json::Value,
24 pub ip: Option<String>,
26 pub user_agent: Option<String>,
28 pub fingerprint: Option<String>,
30 pub tenant_id: Option<String>,
32 pub created_at: String,
34}
35
36impl FromRow for AuditRecord {
37 fn from_row(row: &libsql::Row) -> Result<Self> {
38 let cols = ColumnMap::from_row(row);
39 let metadata_str: String = cols.get(row, "metadata")?;
40 let metadata: serde_json::Value = serde_json::from_str(&metadata_str).map_err(|e| {
41 crate::error::Error::internal(format!("invalid audit metadata JSON: {e}"))
42 })?;
43
44 Ok(Self {
45 id: cols.get(row, "id")?,
46 actor: cols.get(row, "actor")?,
47 action: cols.get(row, "action")?,
48 resource_type: cols.get(row, "resource_type")?,
49 resource_id: cols.get(row, "resource_id")?,
50 metadata,
51 ip: cols.get(row, "ip")?,
52 user_agent: cols.get(row, "user_agent")?,
53 fingerprint: cols.get(row, "fingerprint")?,
54 tenant_id: cols.get(row, "tenant_id")?,
55 created_at: cols.get(row, "created_at")?,
56 })
57 }
58}