From 3d3c195ba498b1a1bb98e09c638cb2a83e7db49e Mon Sep 17 00:00:00 2001 From: ravimahatonp Date: Thu, 1 Oct 2026 15:02:59 +0545 Subject: [PATCH] fix: add schema version field to Event type for backward-compatible evolution --- contract/src/event.rs | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/contract/src/event.rs b/contract/src/event.rs index e994052d..04b793e3 100644 --- a/contract/src/event.rs +++ b/contract/src/event.rs @@ -11,6 +11,9 @@ pub struct Event { pub aggregate_id: String, /// Type of event (Created, Updated, Deleted, etc.) pub event_type: String, + /// Schema version of this event type (for backward-compatible evolution) + #[serde(default = "default_version")] + pub version: u32, /// Event payload as JSON pub data: serde_json::Value, /// Timestamp when event occurred @@ -23,6 +26,11 @@ pub struct Event { pub metadata: Option, } +/// Default event schema version (v1). +fn default_version() -> u32 { + 1 +} + impl Event { /// Create a new event pub fn new( @@ -35,6 +43,7 @@ impl Event { id: Uuid::new_v4().to_string(), aggregate_id, event_type, + version: 1, data, timestamp: Utc::now(), sequence: 0, @@ -77,6 +86,7 @@ mod tests { assert_eq!(event.aggregate_id, "doc-1"); assert_eq!(event.event_type, "Created"); + assert_eq!(event.version, 1); assert!(!event.id.is_empty()); } @@ -94,5 +104,39 @@ mod tests { assert_eq!(event.id, deserialized.id); assert_eq!(event.aggregate_id, deserialized.aggregate_id); + assert_eq!(deserialized.version, 1); + } + + #[test] + fn test_version_in_serialized_json() { + let event = Event::new( + "doc-2".to_string(), + "Updated".to_string(), + serde_json::json!({"field": "value"}), + "user-2".to_string(), + ); + + let json_str = event.to_json().unwrap(); + let raw: serde_json::Value = serde_json::from_str(&json_str).unwrap(); + assert_eq!(raw["version"], 1); + } + + #[test] + fn test_backward_compat_missing_version_defaults_to_1() { + // Simulate a legacy event stored before version field was added + let legacy_json = serde_json::json!({ + "id": "legacy-001", + "aggregate_id": "doc-old", + "event_type": "Created", + "data": {"title": "Legacy"}, + "timestamp": "2025-01-01T00:00:00Z", + "sequence": 42, + "actor": "system", + "metadata": null + }); + + let event: Event = serde_json::from_value(legacy_json).unwrap(); + assert_eq!(event.version, 1, "Missing version should default to 1"); + assert_eq!(event.aggregate_id, "doc-old"); } }