82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package platformevent
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Status string
|
|
|
|
const (
|
|
StatusPending Status = "pending"
|
|
StatusRetrying Status = "retrying"
|
|
StatusDelivered Status = "delivered"
|
|
StatusDeadLetter Status = "dead_letter"
|
|
)
|
|
|
|
const (
|
|
TypeMessageReceived = "message.received"
|
|
TypeMessageRejected = "message.rejected"
|
|
TypeMessageDeduped = "message.deduplicated"
|
|
TypeMessageProcessing = "message.processing"
|
|
TypeIntentResolved = "intent.resolved"
|
|
TypeHandoffTriggered = "handoff.triggered"
|
|
TypeTicketCreated = "ticket.created"
|
|
TypeTicketAssigned = "ticket.assigned"
|
|
TypeTicketResolved = "ticket.resolved"
|
|
TypeTicketClosed = "ticket.closed"
|
|
TypeReplyGenerated = "reply.generated"
|
|
TypeCallbackDelivered = "callback.delivered"
|
|
TypeCallbackFailed = "callback.failed"
|
|
)
|
|
|
|
type Event struct {
|
|
ID string `json:"event_id"`
|
|
Platform string `json:"platform"`
|
|
EventType string `json:"event_type"`
|
|
SessionID string `json:"session_id,omitempty"`
|
|
TicketID string `json:"ticket_id,omitempty"`
|
|
SourceMessageID string `json:"source_message_id,omitempty"`
|
|
CallbackTarget string `json:"callback_target"`
|
|
Payload map[string]any `json:"payload"`
|
|
Status Status `json:"status"`
|
|
AttemptCount int `json:"attempt_count"`
|
|
NextAttemptAt time.Time `json:"next_attempt_at"`
|
|
OccurredAt time.Time `json:"occurred_at"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeliveredAt *time.Time `json:"delivered_at,omitempty"`
|
|
LastError string `json:"last_error,omitempty"`
|
|
}
|
|
|
|
func (e Event) Validate() error {
|
|
if strings.TrimSpace(e.ID) == "" {
|
|
return fmt.Errorf("event id is required")
|
|
}
|
|
if strings.TrimSpace(e.Platform) == "" {
|
|
return fmt.Errorf("platform is required")
|
|
}
|
|
if strings.TrimSpace(e.EventType) == "" {
|
|
return fmt.Errorf("event type is required")
|
|
}
|
|
if strings.TrimSpace(e.CallbackTarget) == "" {
|
|
return fmt.Errorf("callback target is required")
|
|
}
|
|
switch e.Status {
|
|
case StatusPending, StatusRetrying, StatusDelivered, StatusDeadLetter:
|
|
default:
|
|
return fmt.Errorf("invalid status: %s", e.Status)
|
|
}
|
|
if e.AttemptCount < 0 {
|
|
return fmt.Errorf("attempt count must not be negative")
|
|
}
|
|
if e.NextAttemptAt.IsZero() {
|
|
return fmt.Errorf("next attempt at is required")
|
|
}
|
|
if e.OccurredAt.IsZero() {
|
|
return fmt.Errorf("occurred at is required")
|
|
}
|
|
return nil
|
|
}
|