package event import ( "time" "github.com/genex/trading-service/internal/domain/vo" ) // DomainEvent is the base interface for all domain events. type DomainEvent interface { EventName() string OccurredAt() time.Time } // EventPublisher defines the interface for publishing domain events. type EventPublisher interface { Publish(event DomainEvent) error } // --- Concrete Domain Events --- // OrderPlacedEvent is emitted when a new order is successfully placed. type OrderPlacedEvent struct { OrderID string `json:"orderId"` UserID string `json:"userId"` CouponID string `json:"couponId"` Side vo.OrderSide `json:"side"` Type vo.OrderType `json:"type"` Price float64 `json:"price"` Quantity int `json:"quantity"` OccurredOn time.Time `json:"occurredAt"` } func NewOrderPlacedEvent(orderID, userID, couponID string, side vo.OrderSide, orderType vo.OrderType, price float64, quantity int) OrderPlacedEvent { return OrderPlacedEvent{ OrderID: orderID, UserID: userID, CouponID: couponID, Side: side, Type: orderType, Price: price, Quantity: quantity, OccurredOn: time.Now(), } } func (e OrderPlacedEvent) EventName() string { return "order.placed" } func (e OrderPlacedEvent) OccurredAt() time.Time { return e.OccurredOn } // OrderMatchedEvent is emitted when an order is partially or fully matched. type OrderMatchedEvent struct { OrderID string `json:"orderId"` CouponID string `json:"couponId"` FilledQty int `json:"filledQty"` FilledPrice float64 `json:"filledPrice"` IsFull bool `json:"isFull"` OccurredOn time.Time `json:"occurredAt"` } func NewOrderMatchedEvent(orderID, couponID string, filledQty int, filledPrice float64, isFull bool) OrderMatchedEvent { return OrderMatchedEvent{ OrderID: orderID, CouponID: couponID, FilledQty: filledQty, FilledPrice: filledPrice, IsFull: isFull, OccurredOn: time.Now(), } } func (e OrderMatchedEvent) EventName() string { return "order.matched" } func (e OrderMatchedEvent) OccurredAt() time.Time { return e.OccurredOn } // OrderCancelledEvent is emitted when an order is cancelled. type OrderCancelledEvent struct { OrderID string `json:"orderId"` UserID string `json:"userId"` CouponID string `json:"couponId"` OccurredOn time.Time `json:"occurredAt"` } func NewOrderCancelledEvent(orderID, userID, couponID string) OrderCancelledEvent { return OrderCancelledEvent{ OrderID: orderID, UserID: userID, CouponID: couponID, OccurredOn: time.Now(), } } func (e OrderCancelledEvent) EventName() string { return "order.cancelled" } func (e OrderCancelledEvent) OccurredAt() time.Time { return e.OccurredOn } // TradeExecutedEvent is emitted when a trade is completed. type TradeExecutedEvent struct { TradeID string `json:"tradeId"` CouponID string `json:"couponId"` BuyOrderID string `json:"buyOrderId"` SellOrderID string `json:"sellOrderId"` BuyerID string `json:"buyerId"` SellerID string `json:"sellerId"` Price float64 `json:"price"` Quantity int `json:"quantity"` OccurredOn time.Time `json:"occurredAt"` } func NewTradeExecutedEvent(tradeID, couponID, buyOrderID, sellOrderID, buyerID, sellerID string, price float64, quantity int) TradeExecutedEvent { return TradeExecutedEvent{ TradeID: tradeID, CouponID: couponID, BuyOrderID: buyOrderID, SellOrderID: sellOrderID, BuyerID: buyerID, SellerID: sellerID, Price: price, Quantity: quantity, OccurredOn: time.Now(), } } func (e TradeExecutedEvent) EventName() string { return "trade.executed" } func (e TradeExecutedEvent) OccurredAt() time.Time { return e.OccurredOn } // NoopEventPublisher is a no-op publisher used as a default/fallback. type NoopEventPublisher struct{} func (p *NoopEventPublisher) Publish(event DomainEvent) error { return nil }