ito_domain/audit/
writer.rs1use super::event::AuditEvent;
9
10pub trait AuditWriter: Send + Sync {
15 fn append(&self, event: &AuditEvent) -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
17}
18
19pub struct NoopAuditWriter;
24
25impl AuditWriter for NoopAuditWriter {
26 fn append(&self, _event: &AuditEvent) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
27 Ok(())
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::audit::event::{EventContext, SCHEMA_VERSION};
35
36 fn test_event() -> AuditEvent {
37 AuditEvent {
38 v: SCHEMA_VERSION,
39 ts: "2026-02-08T14:30:00.000Z".to_string(),
40 entity: "task".to_string(),
41 entity_id: "1.1".to_string(),
42 scope: Some("test-change".to_string()),
43 op: "create".to_string(),
44 from: None,
45 to: Some("pending".to_string()),
46 actor: "cli".to_string(),
47 by: "@test".to_string(),
48 meta: None,
49 ctx: EventContext {
50 session_id: "test-sid".to_string(),
51 harness_session_id: None,
52 branch: None,
53 worktree: None,
54 commit: None,
55 },
56 }
57 }
58
59 #[test]
60 fn noop_writer_returns_ok() {
61 let writer = NoopAuditWriter;
62 let event = test_event();
63 assert!(writer.append(&event).is_ok());
64 }
65
66 #[test]
67 fn noop_writer_is_object_safe() {
68 let writer: Box<dyn AuditWriter> = Box::new(NoopAuditWriter);
69 let event = test_event();
70 assert!(writer.append(&event).is_ok());
71 }
72
73 #[test]
74 fn noop_writer_is_send_sync() {
75 fn assert_send_sync<T: Send + Sync>() {}
76 assert_send_sync::<NoopAuditWriter>();
77 }
78
79 #[test]
80 fn trait_is_object_safe_for_dyn_dispatch() {
81 fn takes_writer(_w: &dyn AuditWriter) {}
82 let noop = NoopAuditWriter;
83 takes_writer(&noop);
84 }
85}