package model import "time" // IngestedEvent mirrors the shape ingest publishes onto Kafka. // Keep these two structs in lock-step (we are intentionally NOT importing // ingest's package -- bulker compiles standalone). type IngestedEvent struct { WorkspaceID string `json:"workspace_id"` SourceID string `json:"source_id"` MessageID string `json:"message_id"` Type string `json:"type"` AnonymousID string `json:"anonymous_id,omitempty"` UserID string `json:"user_id,omitempty"` GroupID string `json:"group_id,omitempty"` Event string `json:"event,omitempty"` Name string `json:"name,omitempty"` Category string `json:"category,omitempty"` Properties map[string]any `json:"properties,omitempty"` Traits map[string]any `json:"traits,omitempty"` Context map[string]any `json:"context,omitempty"` IP string `json:"ip,omitempty"` UserAgent string `json:"user_agent,omitempty"` Timestamp time.Time `json:"timestamp"` SentAt time.Time `json:"sent_at"` ReceivedAt time.Time `json:"received_at"` } // DLQRecord is the JSON shape the bulker reads from the DLQ topic. type DLQRecord struct { WorkspaceID string `json:"workspace_id"` SourceID string `json:"source_id"` MessageID string `json:"message_id"` Reason string `json:"reason"` Field string `json:"field"` RawPayload string `json:"raw_payload"` ReceivedAt time.Time `json:"received_at"` }