use chrono::{DateTime, NaiveDate, Utc};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use stateset_primitives::{
CartId, CurrencyCode, CustomerId, GiftCardId, InvoiceId, LoyaltyProgramId, OrderId,
OrderItemId, PaymentId, ProductId, ReturnId, ShipmentId, StoreCreditId, SubscriptionId,
};
use uuid::Uuid;
use crate::models::{
CartStatus, CustomerStatus, FulfillmentStatus, InvoiceStatus, OrderStatus, PaymentStatus,
ReturnReason, ReturnStatus, SubscriptionStatus, TrustLevel, X402Asset, X402Network,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum CommerceEvent {
OrderCreated {
order_id: OrderId,
customer_id: CustomerId,
total_amount: Decimal,
item_count: usize,
timestamp: DateTime<Utc>,
},
OrderStatusChanged {
order_id: OrderId,
from_status: OrderStatus,
to_status: OrderStatus,
timestamp: DateTime<Utc>,
},
OrderPaymentStatusChanged {
order_id: OrderId,
from_status: PaymentStatus,
to_status: PaymentStatus,
timestamp: DateTime<Utc>,
},
OrderFulfillmentStatusChanged {
order_id: OrderId,
from_status: FulfillmentStatus,
to_status: FulfillmentStatus,
timestamp: DateTime<Utc>,
},
OrderCancelled {
order_id: OrderId,
reason: Option<String>,
timestamp: DateTime<Utc>,
},
OrderItemAdded {
order_id: OrderId,
item_id: OrderItemId,
sku: String,
quantity: i32,
timestamp: DateTime<Utc>,
},
OrderItemRemoved {
order_id: OrderId,
item_id: OrderItemId,
timestamp: DateTime<Utc>,
},
InventoryItemCreated {
item_id: i64,
sku: String,
name: String,
timestamp: DateTime<Utc>,
},
InventoryAdjusted {
item_id: i64,
sku: String,
location_id: i32,
quantity_change: Decimal,
new_quantity: Decimal,
reason: String,
timestamp: DateTime<Utc>,
},
InventoryReserved {
reservation_id: Uuid,
sku: String,
quantity: Decimal,
reference_type: String,
reference_id: String,
timestamp: DateTime<Utc>,
},
InventoryReservationReleased {
reservation_id: Uuid,
sku: String,
quantity: Decimal,
timestamp: DateTime<Utc>,
},
InventoryReservationConfirmed {
reservation_id: Uuid,
sku: String,
quantity: Decimal,
timestamp: DateTime<Utc>,
},
LowStockAlert {
sku: String,
location_id: i32,
current_quantity: Decimal,
reorder_point: Decimal,
timestamp: DateTime<Utc>,
},
CustomerCreated {
customer_id: CustomerId,
email: String,
timestamp: DateTime<Utc>,
},
CustomerUpdated {
customer_id: CustomerId,
fields_changed: Vec<String>,
timestamp: DateTime<Utc>,
},
CustomerStatusChanged {
customer_id: CustomerId,
from_status: CustomerStatus,
to_status: CustomerStatus,
timestamp: DateTime<Utc>,
},
CustomerAddressAdded {
customer_id: CustomerId,
address_id: Uuid,
timestamp: DateTime<Utc>,
},
ProductCreated {
product_id: ProductId,
name: String,
slug: String,
timestamp: DateTime<Utc>,
},
ProductUpdated {
product_id: ProductId,
fields_changed: Vec<String>,
timestamp: DateTime<Utc>,
},
ProductStatusChanged {
product_id: ProductId,
from_status: String,
to_status: String,
timestamp: DateTime<Utc>,
},
ProductVariantAdded {
product_id: ProductId,
variant_id: Uuid,
sku: String,
timestamp: DateTime<Utc>,
},
ProductVariantUpdated {
variant_id: Uuid,
sku: String,
timestamp: DateTime<Utc>,
},
CustomObjectTypeCreated {
type_id: Uuid,
handle: String,
timestamp: DateTime<Utc>,
},
CustomObjectTypeUpdated {
type_id: Uuid,
handle: String,
fields_changed: Vec<String>,
timestamp: DateTime<Utc>,
},
CustomObjectTypeDeleted {
type_id: Uuid,
handle: String,
timestamp: DateTime<Utc>,
},
CustomObjectCreated {
object_id: Uuid,
type_handle: String,
owner_type: Option<String>,
owner_id: Option<String>,
timestamp: DateTime<Utc>,
},
CustomObjectUpdated {
object_id: Uuid,
type_handle: String,
fields_changed: Vec<String>,
timestamp: DateTime<Utc>,
},
CustomObjectDeleted {
object_id: Uuid,
type_handle: String,
timestamp: DateTime<Utc>,
},
ReturnRequested {
return_id: ReturnId,
order_id: OrderId,
customer_id: CustomerId,
reason: ReturnReason,
item_count: usize,
timestamp: DateTime<Utc>,
},
ReturnStatusChanged {
return_id: ReturnId,
from_status: ReturnStatus,
to_status: ReturnStatus,
timestamp: DateTime<Utc>,
},
ReturnApproved {
return_id: ReturnId,
order_id: OrderId,
timestamp: DateTime<Utc>,
},
ReturnRejected {
return_id: ReturnId,
order_id: OrderId,
reason: String,
timestamp: DateTime<Utc>,
},
ReturnCompleted {
return_id: ReturnId,
order_id: OrderId,
refund_amount: Decimal,
timestamp: DateTime<Utc>,
},
RefundIssued {
return_id: ReturnId,
order_id: OrderId,
amount: Decimal,
method: String,
timestamp: DateTime<Utc>,
},
CartCreated {
cart_id: CartId,
customer_id: Option<CustomerId>,
timestamp: DateTime<Utc>,
},
CartItemAdded {
cart_id: CartId,
product_id: ProductId,
sku: String,
quantity: i32,
timestamp: DateTime<Utc>,
},
CartStatusChanged {
cart_id: CartId,
from_status: CartStatus,
to_status: CartStatus,
timestamp: DateTime<Utc>,
},
CartCheckoutCompleted {
cart_id: CartId,
order_id: OrderId,
total_amount: Decimal,
timestamp: DateTime<Utc>,
},
PaymentCreated {
payment_id: PaymentId,
order_id: OrderId,
amount: Decimal,
currency: CurrencyCode,
timestamp: DateTime<Utc>,
},
PaymentStatusChanged {
payment_id: PaymentId,
from_status: PaymentStatus,
to_status: PaymentStatus,
timestamp: DateTime<Utc>,
},
PaymentCompleted {
payment_id: PaymentId,
order_id: OrderId,
amount: Decimal,
timestamp: DateTime<Utc>,
},
ShipmentCreated {
shipment_id: ShipmentId,
order_id: OrderId,
carrier: String,
tracking_number: Option<String>,
timestamp: DateTime<Utc>,
},
ShipmentDelivered {
shipment_id: ShipmentId,
order_id: OrderId,
timestamp: DateTime<Utc>,
},
InvoiceCreated {
invoice_id: InvoiceId,
customer_id: CustomerId,
total_amount: Decimal,
currency: CurrencyCode,
timestamp: DateTime<Utc>,
},
InvoiceStatusChanged {
invoice_id: InvoiceId,
from_status: InvoiceStatus,
to_status: InvoiceStatus,
timestamp: DateTime<Utc>,
},
SubscriptionCreated {
subscription_id: SubscriptionId,
customer_id: CustomerId,
plan_name: String,
price: Decimal,
timestamp: DateTime<Utc>,
},
SubscriptionStatusChanged {
subscription_id: SubscriptionId,
from_status: SubscriptionStatus,
to_status: SubscriptionStatus,
timestamp: DateTime<Utc>,
},
SubscriptionRenewed {
subscription_id: SubscriptionId,
billing_amount: Decimal,
timestamp: DateTime<Utc>,
},
SubscriptionCancelled {
subscription_id: SubscriptionId,
reason: Option<String>,
timestamp: DateTime<Utc>,
},
GiftCardCreated {
gift_card_id: GiftCardId,
initial_balance: Decimal,
currency: CurrencyCode,
timestamp: DateTime<Utc>,
},
GiftCardRedeemed {
gift_card_id: GiftCardId,
amount: Decimal,
order_id: Option<OrderId>,
timestamp: DateTime<Utc>,
},
StoreCreditIssued {
store_credit_id: StoreCreditId,
customer_id: CustomerId,
amount: Decimal,
reason: String,
timestamp: DateTime<Utc>,
},
StoreCreditApplied {
store_credit_id: StoreCreditId,
order_id: OrderId,
amount: Decimal,
timestamp: DateTime<Utc>,
},
LoyaltyPointsEarned {
program_id: LoyaltyProgramId,
customer_id: CustomerId,
points: i64,
source: String,
timestamp: DateTime<Utc>,
},
LoyaltyPointsRedeemed {
program_id: LoyaltyProgramId,
customer_id: CustomerId,
points: i64,
timestamp: DateTime<Utc>,
},
X402IntentCreated {
intent_id: Uuid,
cart_id: Option<CartId>,
payer_address: String,
payee_address: String,
amount: u64,
asset: X402Asset,
network: X402Network,
timestamp: DateTime<Utc>,
},
X402IntentSigned {
intent_id: Uuid,
signing_hash: String,
payer_public_key: String,
timestamp: DateTime<Utc>,
},
X402IntentSequenced {
intent_id: Uuid,
sequence_number: u64,
batch_id: Uuid,
timestamp: DateTime<Utc>,
},
X402IntentSettled {
intent_id: Uuid,
tx_hash: String,
block_number: u64,
timestamp: DateTime<Utc>,
},
X402IntentFailed {
intent_id: Uuid,
reason: String,
timestamp: DateTime<Utc>,
},
X402IntentExpired {
intent_id: Uuid,
timestamp: DateTime<Utc>,
},
AgentCardCreated {
agent_id: Uuid,
name: String,
wallet_address: String,
trust_level: TrustLevel,
timestamp: DateTime<Utc>,
},
AgentCardVerified {
agent_id: Uuid,
trust_level: TrustLevel,
verification_method: String,
timestamp: DateTime<Utc>,
},
AgentCardSuspended {
agent_id: Uuid,
reason: String,
timestamp: DateTime<Utc>,
},
AgentCardReactivated {
agent_id: Uuid,
timestamp: DateTime<Utc>,
},
A2AQuoteRequested {
quote_id: Uuid,
buyer_agent_id: Uuid,
seller_agent_id: Uuid,
total: Decimal,
item_count: usize,
timestamp: DateTime<Utc>,
},
A2AQuoteAccepted {
quote_id: Uuid,
buyer_agent_id: Uuid,
seller_agent_id: Uuid,
timestamp: DateTime<Utc>,
},
A2AQuoteRejected {
quote_id: Uuid,
buyer_agent_id: Uuid,
reason: Option<String>,
timestamp: DateTime<Utc>,
},
A2APurchaseInitiated {
purchase_id: Uuid,
quote_id: Option<Uuid>,
buyer_agent_id: Uuid,
seller_agent_id: Uuid,
payment_intent_id: Uuid,
total: Decimal,
timestamp: DateTime<Utc>,
},
A2APurchasePaid {
purchase_id: Uuid,
payment_intent_id: Uuid,
tx_hash: String,
timestamp: DateTime<Utc>,
},
A2ADeliveryConfirmed {
purchase_id: Uuid,
order_id: Option<OrderId>,
buyer_agent_id: Uuid,
seller_agent_id: Uuid,
rating: Option<u8>,
timestamp: DateTime<Utc>,
},
FixedAssetPlacedInService {
asset_id: Uuid,
asset_number: String,
in_service_date: NaiveDate,
acquisition_cost: Decimal,
timestamp: DateTime<Utc>,
},
FixedAssetDisposed {
asset_id: Uuid,
asset_number: String,
disposal_date: NaiveDate,
proceeds: Decimal,
gain_loss: Decimal,
timestamp: DateTime<Utc>,
},
FixedAssetWrittenOff {
asset_id: Uuid,
asset_number: String,
write_off_date: NaiveDate,
loss: Decimal,
timestamp: DateTime<Utc>,
},
DepreciationPosted {
asset_id: Uuid,
asset_number: String,
periods: u32,
amount: Decimal,
accumulated_depreciation: Decimal,
timestamp: DateTime<Utc>,
},
RevenueRecognized {
obligation_id: Uuid,
amount: Decimal,
total_recognized: Decimal,
timestamp: DateTime<Utc>,
},
RevenueContractCompleted {
contract_id: Uuid,
contract_number: String,
transaction_price: Decimal,
currency: CurrencyCode,
timestamp: DateTime<Utc>,
},
CycleCountCompleted {
cycle_count_id: Uuid,
warehouse_id: i32,
line_count: usize,
variance_line_count: usize,
total_variance: Decimal,
timestamp: DateTime<Utc>,
},
ThreeWayMatchVarianceDetected {
bill_id: Uuid,
purchase_order_id: Uuid,
variance_line_count: usize,
tolerance_percent: Decimal,
timestamp: DateTime<Utc>,
},
FxRevaluationPosted {
as_of_date: NaiveDate,
base_currency: CurrencyCode,
total_unrealized_gain_loss: Decimal,
journal_entry_id: Option<Uuid>,
timestamp: DateTime<Utc>,
},
MonthEndCloseCompleted {
period_id: Uuid,
period_name: String,
depreciation_total: Decimal,
revenue_recognized_total: Decimal,
fx_unrealized_gain_loss: Decimal,
closing_entry_id: Option<Uuid>,
timestamp: DateTime<Utc>,
},
}
impl CommerceEvent {
#[must_use]
pub const fn event_type(&self) -> &'static str {
match self {
Self::OrderCreated { .. } => "order_created",
Self::OrderStatusChanged { .. } => "order_status_changed",
Self::OrderPaymentStatusChanged { .. } => "order_payment_status_changed",
Self::OrderFulfillmentStatusChanged { .. } => "order_fulfillment_status_changed",
Self::OrderCancelled { .. } => "order_cancelled",
Self::OrderItemAdded { .. } => "order_item_added",
Self::OrderItemRemoved { .. } => "order_item_removed",
Self::InventoryItemCreated { .. } => "inventory_item_created",
Self::InventoryAdjusted { .. } => "inventory_adjusted",
Self::InventoryReserved { .. } => "inventory_reserved",
Self::InventoryReservationReleased { .. } => "inventory_reservation_released",
Self::InventoryReservationConfirmed { .. } => "inventory_reservation_confirmed",
Self::LowStockAlert { .. } => "low_stock_alert",
Self::CustomerCreated { .. } => "customer_created",
Self::CustomerUpdated { .. } => "customer_updated",
Self::CustomerStatusChanged { .. } => "customer_status_changed",
Self::CustomerAddressAdded { .. } => "customer_address_added",
Self::ProductCreated { .. } => "product_created",
Self::ProductUpdated { .. } => "product_updated",
Self::ProductStatusChanged { .. } => "product_status_changed",
Self::ProductVariantAdded { .. } => "product_variant_added",
Self::ProductVariantUpdated { .. } => "product_variant_updated",
Self::CustomObjectTypeCreated { .. } => "custom_object_type_created",
Self::CustomObjectTypeUpdated { .. } => "custom_object_type_updated",
Self::CustomObjectTypeDeleted { .. } => "custom_object_type_deleted",
Self::CustomObjectCreated { .. } => "custom_object_created",
Self::CustomObjectUpdated { .. } => "custom_object_updated",
Self::CustomObjectDeleted { .. } => "custom_object_deleted",
Self::ReturnRequested { .. } => "return_requested",
Self::ReturnStatusChanged { .. } => "return_status_changed",
Self::ReturnApproved { .. } => "return_approved",
Self::ReturnRejected { .. } => "return_rejected",
Self::ReturnCompleted { .. } => "return_completed",
Self::RefundIssued { .. } => "refund_issued",
Self::CartCreated { .. } => "cart_created",
Self::CartItemAdded { .. } => "cart_item_added",
Self::CartStatusChanged { .. } => "cart_status_changed",
Self::CartCheckoutCompleted { .. } => "cart_checkout_completed",
Self::PaymentCreated { .. } => "payment_created",
Self::PaymentStatusChanged { .. } => "payment_status_changed",
Self::PaymentCompleted { .. } => "payment_completed",
Self::ShipmentCreated { .. } => "shipment_created",
Self::ShipmentDelivered { .. } => "shipment_delivered",
Self::InvoiceCreated { .. } => "invoice_created",
Self::InvoiceStatusChanged { .. } => "invoice_status_changed",
Self::SubscriptionCreated { .. } => "subscription_created",
Self::SubscriptionStatusChanged { .. } => "subscription_status_changed",
Self::SubscriptionRenewed { .. } => "subscription_renewed",
Self::SubscriptionCancelled { .. } => "subscription_cancelled",
Self::GiftCardCreated { .. } => "gift_card_created",
Self::GiftCardRedeemed { .. } => "gift_card_redeemed",
Self::StoreCreditIssued { .. } => "store_credit_issued",
Self::StoreCreditApplied { .. } => "store_credit_applied",
Self::LoyaltyPointsEarned { .. } => "loyalty_points_earned",
Self::LoyaltyPointsRedeemed { .. } => "loyalty_points_redeemed",
Self::X402IntentCreated { .. } => "x402_intent_created",
Self::X402IntentSigned { .. } => "x402_intent_signed",
Self::X402IntentSequenced { .. } => "x402_intent_sequenced",
Self::X402IntentSettled { .. } => "x402_intent_settled",
Self::X402IntentFailed { .. } => "x402_intent_failed",
Self::X402IntentExpired { .. } => "x402_intent_expired",
Self::AgentCardCreated { .. } => "agent_card_created",
Self::AgentCardVerified { .. } => "agent_card_verified",
Self::AgentCardSuspended { .. } => "agent_card_suspended",
Self::AgentCardReactivated { .. } => "agent_card_reactivated",
Self::A2AQuoteRequested { .. } => "a2a_quote_requested",
Self::A2AQuoteAccepted { .. } => "a2a_quote_accepted",
Self::A2AQuoteRejected { .. } => "a2a_quote_rejected",
Self::A2APurchaseInitiated { .. } => "a2a_purchase_initiated",
Self::A2APurchasePaid { .. } => "a2a_purchase_paid",
Self::A2ADeliveryConfirmed { .. } => "a2a_delivery_confirmed",
Self::FixedAssetPlacedInService { .. } => "fixed_asset_placed_in_service",
Self::FixedAssetDisposed { .. } => "fixed_asset_disposed",
Self::FixedAssetWrittenOff { .. } => "fixed_asset_written_off",
Self::DepreciationPosted { .. } => "depreciation_posted",
Self::RevenueRecognized { .. } => "revenue_recognized",
Self::RevenueContractCompleted { .. } => "revenue_contract_completed",
Self::CycleCountCompleted { .. } => "cycle_count_completed",
Self::ThreeWayMatchVarianceDetected { .. } => "three_way_match_variance_detected",
Self::FxRevaluationPosted { .. } => "fx_revaluation_posted",
Self::MonthEndCloseCompleted { .. } => "month_end_close_completed",
}
}
#[must_use]
pub const fn timestamp(&self) -> DateTime<Utc> {
match self {
Self::OrderCreated { timestamp, .. }
| Self::OrderStatusChanged { timestamp, .. }
| Self::OrderPaymentStatusChanged { timestamp, .. }
| Self::OrderFulfillmentStatusChanged { timestamp, .. }
| Self::OrderCancelled { timestamp, .. }
| Self::OrderItemAdded { timestamp, .. }
| Self::OrderItemRemoved { timestamp, .. }
| Self::InventoryItemCreated { timestamp, .. }
| Self::InventoryAdjusted { timestamp, .. }
| Self::InventoryReserved { timestamp, .. }
| Self::InventoryReservationReleased { timestamp, .. }
| Self::InventoryReservationConfirmed { timestamp, .. }
| Self::LowStockAlert { timestamp, .. }
| Self::CustomerCreated { timestamp, .. }
| Self::CustomerUpdated { timestamp, .. }
| Self::CustomerStatusChanged { timestamp, .. }
| Self::CustomerAddressAdded { timestamp, .. }
| Self::ProductCreated { timestamp, .. }
| Self::ProductUpdated { timestamp, .. }
| Self::ProductStatusChanged { timestamp, .. }
| Self::ProductVariantAdded { timestamp, .. }
| Self::ProductVariantUpdated { timestamp, .. }
| Self::CustomObjectTypeCreated { timestamp, .. }
| Self::CustomObjectTypeUpdated { timestamp, .. }
| Self::CustomObjectTypeDeleted { timestamp, .. }
| Self::CustomObjectCreated { timestamp, .. }
| Self::CustomObjectUpdated { timestamp, .. }
| Self::CustomObjectDeleted { timestamp, .. }
| Self::ReturnRequested { timestamp, .. }
| Self::ReturnStatusChanged { timestamp, .. }
| Self::ReturnApproved { timestamp, .. }
| Self::ReturnRejected { timestamp, .. }
| Self::ReturnCompleted { timestamp, .. }
| Self::RefundIssued { timestamp, .. }
| Self::CartCreated { timestamp, .. }
| Self::CartItemAdded { timestamp, .. }
| Self::CartStatusChanged { timestamp, .. }
| Self::CartCheckoutCompleted { timestamp, .. }
| Self::PaymentCreated { timestamp, .. }
| Self::PaymentStatusChanged { timestamp, .. }
| Self::PaymentCompleted { timestamp, .. }
| Self::ShipmentCreated { timestamp, .. }
| Self::ShipmentDelivered { timestamp, .. }
| Self::InvoiceCreated { timestamp, .. }
| Self::InvoiceStatusChanged { timestamp, .. }
| Self::SubscriptionCreated { timestamp, .. }
| Self::SubscriptionStatusChanged { timestamp, .. }
| Self::SubscriptionRenewed { timestamp, .. }
| Self::SubscriptionCancelled { timestamp, .. }
| Self::GiftCardCreated { timestamp, .. }
| Self::GiftCardRedeemed { timestamp, .. }
| Self::StoreCreditIssued { timestamp, .. }
| Self::StoreCreditApplied { timestamp, .. }
| Self::LoyaltyPointsEarned { timestamp, .. }
| Self::LoyaltyPointsRedeemed { timestamp, .. }
| Self::X402IntentCreated { timestamp, .. }
| Self::X402IntentSigned { timestamp, .. }
| Self::X402IntentSequenced { timestamp, .. }
| Self::X402IntentSettled { timestamp, .. }
| Self::X402IntentFailed { timestamp, .. }
| Self::X402IntentExpired { timestamp, .. }
| Self::AgentCardCreated { timestamp, .. }
| Self::AgentCardVerified { timestamp, .. }
| Self::AgentCardSuspended { timestamp, .. }
| Self::AgentCardReactivated { timestamp, .. }
| Self::A2AQuoteRequested { timestamp, .. }
| Self::A2AQuoteAccepted { timestamp, .. }
| Self::A2AQuoteRejected { timestamp, .. }
| Self::A2APurchaseInitiated { timestamp, .. }
| Self::A2APurchasePaid { timestamp, .. }
| Self::A2ADeliveryConfirmed { timestamp, .. }
| Self::FixedAssetPlacedInService { timestamp, .. }
| Self::FixedAssetDisposed { timestamp, .. }
| Self::FixedAssetWrittenOff { timestamp, .. }
| Self::DepreciationPosted { timestamp, .. }
| Self::RevenueRecognized { timestamp, .. }
| Self::RevenueContractCompleted { timestamp, .. }
| Self::CycleCountCompleted { timestamp, .. }
| Self::ThreeWayMatchVarianceDetected { timestamp, .. }
| Self::FxRevaluationPosted { timestamp, .. }
| Self::MonthEndCloseCompleted { timestamp, .. } => *timestamp,
}
}
#[must_use = "serialization result should not be discarded"]
pub fn to_json(&self) -> serde_json::Result<String> {
serde_json::to_string(self)
}
pub fn from_json(json: &str) -> serde_json::Result<Self> {
serde_json::from_str(json)
}
}
pub trait EventStore {
fn append(&self, event: &CommerceEvent) -> crate::errors::Result<u64>;
fn get_events_since(
&self,
sequence: u64,
limit: u32,
) -> crate::errors::Result<Vec<(u64, CommerceEvent)>>;
fn get_events_for_aggregate(
&self,
aggregate_type: &str,
aggregate_id: &str,
) -> crate::errors::Result<Vec<CommerceEvent>>;
fn latest_sequence(&self) -> crate::errors::Result<u64>;
}