use crate::audit::AuditMetadata;
use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Event {
pub event_id: Uuid,
pub aggregate_type: String,
pub aggregate_id: String,
pub sequence: i64,
pub event_type: String,
pub payload: serde_json::Value,
pub audit: AuditMetadata,
pub timestamp: u64,
}
impl Event {
pub fn new(
aggregate_type: impl Into<String>,
aggregate_id: impl Into<String>,
sequence: i64,
event_type: impl Into<String>,
payload: serde_json::Value,
) -> Self {
Self {
event_id: Uuid::new_v4(),
aggregate_type: aggregate_type.into(),
aggregate_id: aggregate_id.into(),
sequence,
event_type: event_type.into(),
payload,
audit: AuditMetadata::pending(),
timestamp: SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64,
}
}
pub fn with_audit(mut self, audit: AuditMetadata) -> Self {
self.audit = audit;
self
}
pub fn to_json(&self) -> Result<String, serde_json::Error> {
serde_json::to_string(self)
}
pub fn from_json(json_str: &str) -> Result<Self, serde_json::Error> {
serde_json::from_str(json_str)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::audit::AuditMetadata;
use serde_json::json;
#[test]
fn test_event_creation() {
let event = Event::new(
"User",
"user-123",
1,
"UserCreated",
json!({
"name": "Test User",
"email": "test@example.com"
}),
);
assert_eq!(event.aggregate_type, "User");
assert_eq!(event.aggregate_id, "user-123");
assert_eq!(event.sequence, 1);
assert_eq!(event.event_type, "UserCreated");
assert_eq!(event.payload["name"], "Test User");
assert!(event.timestamp > 0);
assert!(event.audit.is_pending());
}
#[test]
fn test_with_audit_overwrites_pending() {
let stamp = AuditMetadata::test_default();
let event =
Event::new("User", "user-1", 1, "UserCreated", json!({})).with_audit(stamp.clone());
assert!(!event.audit.is_pending());
assert_eq!(event.audit, stamp);
}
#[test]
fn test_event_serialization_roundtrips_audit() {
let event = Event::new(
"User",
"user-789",
3,
"ProfileUpdated",
json!({"name": "X"}),
)
.with_audit(AuditMetadata::test_default());
let json_str = event.to_json().unwrap();
let deserialized = Event::from_json(&json_str).unwrap();
assert_eq!(event.event_id, deserialized.event_id);
assert_eq!(event.audit, deserialized.audit);
}
#[test]
fn test_event_ordering() {
let event1 = Event::new("User", "user-1", 1, "UserCreated", json!({}));
let event2 = Event::new("User", "user-1", 2, "ProfileUpdated", json!({}));
assert!(event1.sequence < event2.sequence);
}
#[test]
fn test_event_uniqueness() {
let event1 = Event::new("User", "user-1", 1, "UserCreated", json!({}));
let event2 = Event::new("User", "user-1", 1, "UserCreated", json!({}));
assert_ne!(event1.event_id, event2.event_id);
}
}