1use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
7pub struct ReplayAudit {
8 pub audit_v: u32,
10 pub created_unix_ms: u128,
12 pub bundle_dir: String,
14 pub spec_sha256: String,
16 pub input: ReplayAuditInput,
18 pub policy: ReplayAuditPolicy,
20 pub actions: Vec<ReplayAuditAction>,
22}
23
24#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
26pub struct ReplayAuditInput {
27 pub journal_lane: String,
29 pub journal_path: String,
31 pub last_n: u64,
33 pub scanned_records: u64,
35 pub selected_bytes: u64,
37 pub sample_sha256: Vec<String>,
39}
40
41#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
43pub struct ReplayAuditPolicy {
44 pub env: String,
46 pub approval_provided: bool,
48 pub mode: String,
50}
51
52#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
54pub struct ReplayAuditAction {
55 pub action: String,
57 pub role: String,
59 pub input_lane: String,
61 pub output_lane: String,
63 pub stage: String,
65 pub target: String,
67 pub decision: String,
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn replay_audit_json_roundtrips() {
77 let audit = ReplayAudit {
78 audit_v: 1,
79 created_unix_ms: 42,
80 bundle_dir: "/tmp/bundle".to_string(),
81 spec_sha256: "sha256:abc123".to_string(),
82 input: ReplayAuditInput {
83 journal_lane: "journal.main".to_string(),
84 journal_path: "/tmp/journal.mmap".to_string(),
85 last_n: 10,
86 scanned_records: 12,
87 selected_bytes: 512,
88 sample_sha256: vec!["sha256:def456".to_string()],
89 },
90 policy: ReplayAuditPolicy {
91 env: "prod".to_string(),
92 approval_provided: true,
93 mode: "dry_run".to_string(),
94 },
95 actions: vec![ReplayAuditAction {
96 action: "http_post".to_string(),
97 role: "role_stage_notify".to_string(),
98 input_lane: "rx".to_string(),
99 output_lane: "tx".to_string(),
100 stage: "http_post:https://example.test".to_string(),
101 target: "https://example.test".to_string(),
102 decision: "Allow".to_string(),
103 }],
104 };
105
106 let json = serde_json::to_string_pretty(&audit).unwrap();
107 let back: ReplayAudit = serde_json::from_str(&json).unwrap();
108 assert_eq!(back, audit);
109 }
110}