backbone-catalog 0.7.0

Canonical product/service identity: Item, Item Group, UOM (Indonesia-first)
Documentation
//! Event Envelope
//!
//! Generated by metaphor-schema. Do not edit manually.
//!
//! Wraps domain events with metadata for persistence.

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

// ============================================================================
// EVENT ENVELOPE
// ============================================================================

/// Wraps a domain event with metadata for persistence
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventEnvelope<T> {
    /// Unique event ID
    pub event_id: Uuid,
    /// Aggregate ID this event belongs to
    pub aggregate_id: Uuid,
    /// Type of aggregate
    pub aggregate_type: String,
    /// Sequence number within the aggregate stream
    pub sequence: i64,
    /// Event type name (for deserialization)
    pub event_type: String,
    /// Event version (for schema evolution)
    pub event_version: i32,
    /// The actual event payload
    pub payload: T,
    /// Event metadata (correlation ID, causation ID, etc.)
    pub metadata: EventMetadata,
    /// When the event occurred
    pub occurred_at: DateTime<Utc>,
    /// When the event was stored
    pub stored_at: Option<DateTime<Utc>>,
}

impl<T> EventEnvelope<T> {
    /// Create a new event envelope
    pub fn new(
        aggregate_id: Uuid,
        aggregate_type: impl Into<String>,
        sequence: i64,
        event_type: impl Into<String>,
        payload: T,
    ) -> Self {
        Self {
            event_id: Uuid::new_v4(),
            aggregate_id,
            aggregate_type: aggregate_type.into(),
            sequence,
            event_type: event_type.into(),
            event_version: 1,
            payload,
            metadata: EventMetadata::default(),
            occurred_at: Utc::now(),
            stored_at: None,
        }
    }

    /// Add correlation ID for tracing
    pub fn with_correlation_id(mut self, id: Uuid) -> Self {
        self.metadata.correlation_id = Some(id);
        self
    }

    /// Add causation ID for event chaining
    pub fn with_causation_id(mut self, id: Uuid) -> Self {
        self.metadata.causation_id = Some(id);
        self
    }

    /// Add user ID who triggered the event
    pub fn with_user_id(mut self, id: Uuid) -> Self {
        self.metadata.user_id = Some(id);
        self
    }
}

/// Metadata attached to events
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct EventMetadata {
    /// Correlation ID for distributed tracing
    pub correlation_id: Option<Uuid>,
    /// ID of the event that caused this event
    pub causation_id: Option<Uuid>,
    /// User who triggered the action
    pub user_id: Option<Uuid>,
    /// Custom metadata as JSON
    #[serde(default)]
    pub custom: std::collections::HashMap<String, serde_json::Value>,
}

/// Event as stored in the database
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
pub struct StoredEvent {
    pub event_id: Uuid,
    pub aggregate_id: Uuid,
    pub aggregate_type: String,
    pub sequence: i64,
    pub event_type: String,
    pub event_version: i32,
    pub payload: serde_json::Value,
    pub metadata: serde_json::Value,
    pub occurred_at: DateTime<Utc>,
    pub stored_at: DateTime<Utc>,
}

// <<< CUSTOM ENVELOPE START >>>
// Add custom event envelope extensions here
// <<< CUSTOM ENVELOPE END >>>