1pub use lunaris_core::audit::{
22 AUDIT_TOPIC, AuditEvent, FactIdData, ForgetReceiptData, ForgetTargetData, IndexKindData,
23 PublishError, Publisher, ScopeSpecData, publish_audit_event,
24};
25
26use crate::forget::{ForgetReceipt, ForgetTarget, IndexKind, ScopeSpec};
27
28impl From<&ForgetTarget> for ForgetTargetData {
29 fn from(t: &ForgetTarget) -> Self {
30 match t {
31 ForgetTarget::Id(u) => ForgetTargetData::Id(*u),
32 ForgetTarget::Scope(s) => ForgetTargetData::Scope(s.into()),
33 ForgetTarget::Before(h) => ForgetTargetData::Before(*h),
34 }
35 }
36}
37
38impl From<&ScopeSpec> for ScopeSpecData {
39 fn from(s: &ScopeSpec) -> Self {
40 match s {
41 ScopeSpec::BySource(v) => ScopeSpecData::BySource(v.clone()),
42 ScopeSpec::ByMetadata(k, v) => ScopeSpecData::ByMetadata(k.clone(), v.clone()),
43 ScopeSpec::ByEpisode(u) => ScopeSpecData::ByEpisode(*u),
44 }
45 }
46}
47
48impl From<&IndexKind> for IndexKindData {
49 fn from(i: &IndexKind) -> Self {
50 match i {
51 IndexKind::Kv => IndexKindData::Kv,
52 IndexKind::Vector => IndexKindData::Vector,
53 IndexKind::Graph => IndexKindData::Graph,
54 }
55 }
56}
57
58impl From<&ForgetReceipt> for ForgetReceiptData {
59 fn from(r: &ForgetReceipt) -> Self {
60 Self {
61 target: (&r.target).into(),
62 indices_affected: r.indices_affected.iter().map(Into::into).collect(),
63 rows_written: r.rows_written,
64 rows_deleted: r.rows_deleted,
65 audit_lsn: r.audit_lsn,
66 preview: r.preview,
67 }
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::forget::{ForgetTarget, IndexKind, ScopeSpec};
75 use lunaris_core::storage::types::Lsn;
76 use ulid::Ulid;
77
78 #[test]
79 fn re_exported_audit_topic_matches() {
80 assert_eq!(AUDIT_TOPIC, "__lunaris_audit__");
81 }
82
83 #[test]
84 fn forget_receipt_bridge_round_trips_every_target_variant() {
85 let lsn = Lsn { wall_ms: 1, counter: 2 };
86 let id = Ulid::new();
88 let r1 = ForgetReceipt {
89 target: ForgetTarget::Id(id),
90 indices_affected: vec![IndexKind::Kv, IndexKind::Vector, IndexKind::Graph],
91 matched: 7,
92 rows_written: 3,
93 rows_deleted: 4,
94 audit_lsn: lsn,
95 preview: true,
96 };
97 let d1: ForgetReceiptData = (&r1).into();
98 assert_eq!(d1.target, ForgetTargetData::Id(id));
99 assert_eq!(
100 d1.indices_affected,
101 vec![IndexKindData::Kv, IndexKindData::Vector, IndexKindData::Graph]
102 );
103 assert_eq!(d1.rows_written, 3);
104 assert_eq!(d1.rows_deleted, 4);
105 assert!(d1.preview);
106
107 let r2 = ForgetReceipt {
109 target: ForgetTarget::Scope(ScopeSpec::BySource("src".into())),
110 ..r1.clone()
111 };
112 let d2: ForgetReceiptData = (&r2).into();
113 assert_eq!(d2.target, ForgetTargetData::Scope(ScopeSpecData::BySource("src".into())));
114
115 let r3 = ForgetReceipt {
117 target: ForgetTarget::Scope(ScopeSpec::ByMetadata("k".into(), "v".into())),
118 ..r1.clone()
119 };
120 let d3: ForgetReceiptData = (&r3).into();
121 assert_eq!(
122 d3.target,
123 ForgetTargetData::Scope(ScopeSpecData::ByMetadata("k".into(), "v".into()))
124 );
125
126 let r4 =
128 ForgetReceipt { target: ForgetTarget::Scope(ScopeSpec::ByEpisode(id)), ..r1.clone() };
129 let d4: ForgetReceiptData = (&r4).into();
130 assert_eq!(d4.target, ForgetTargetData::Scope(ScopeSpecData::ByEpisode(id)));
131 }
132}