Skip to main content

tramli_plugins/audit/
mod.rs

1use std::time::Instant;
2use tramli::{FlowState, FlowStore, InMemoryFlowStore, FlowInstance, TransitionRecord};
3
4/// Audited transition record.
5#[derive(Debug, Clone)]
6pub struct AuditedTransitionRecord {
7    pub flow_id: String,
8    pub from: String,
9    pub to: String,
10    pub trigger: String,
11    pub timestamp: Instant,
12}
13
14/// Auditing store decorator — captures transition records.
15pub struct AuditingStore<S: FlowState> {
16    pub delegate: InMemoryFlowStore<S>,
17    audit_log: Vec<AuditedTransitionRecord>,
18}
19
20impl<S: FlowState> AuditingStore<S> {
21    pub fn new(delegate: InMemoryFlowStore<S>) -> Self {
22        Self { delegate, audit_log: Vec::new() }
23    }
24
25    pub fn create(&mut self, flow: FlowInstance<S>) {
26        self.delegate.create(flow);
27    }
28
29    pub fn get(&self, flow_id: &str) -> Option<&FlowInstance<S>> {
30        self.delegate.get(flow_id)
31    }
32
33    pub fn get_mut(&mut self, flow_id: &str) -> Option<&mut FlowInstance<S>> {
34        self.delegate.get_mut(flow_id)
35    }
36
37    pub fn record_transition(&mut self, flow_id: &str, from: &str, to: &str, trigger: &str) {
38        self.delegate.record_transition(flow_id, from, to, trigger);
39        self.audit_log.push(AuditedTransitionRecord {
40            flow_id: flow_id.to_string(),
41            from: from.to_string(),
42            to: to.to_string(),
43            trigger: trigger.to_string(),
44            timestamp: Instant::now(),
45        });
46    }
47
48    pub fn audited_transitions(&self) -> &[AuditedTransitionRecord] {
49        &self.audit_log
50    }
51
52    pub fn transition_log(&self) -> &[tramli::TransitionRecord] {
53        self.delegate.transition_log()
54    }
55
56    pub fn clear(&mut self) {
57        self.delegate.clear();
58        self.audit_log.clear();
59    }
60}
61
62impl<S: FlowState> FlowStore<S> for AuditingStore<S> {
63    fn create(&mut self, flow: FlowInstance<S>) { self.delegate.create(flow); }
64    fn get(&self, flow_id: &str) -> Option<&FlowInstance<S>> { self.delegate.get(flow_id) }
65    fn get_mut(&mut self, flow_id: &str) -> Option<&mut FlowInstance<S>> { self.delegate.get_mut(flow_id) }
66    fn record_transition(&mut self, flow_id: &str, from: &str, to: &str, trigger: &str) {
67        self.record_transition(flow_id, from, to, trigger);
68    }
69    fn transition_log(&self) -> &[TransitionRecord] { self.delegate.transition_log() }
70    fn clear(&mut self) { self.clear(); }
71}