Files
GL/domain/ledger/event.go

75 lines
2.1 KiB
Go

package ledger
import (
"encoding/hex"
"fmt"
"strings"
"time"
)
type TransactionState string
const (
TransactionStateCreated TransactionState = "CREATED"
TransactionStatePendingTransaction TransactionState = "PENDING_TRANSACTION"
TransactionStatePendingAdmin TransactionState = "PENDING_ADMIN"
TransactionStateSuccessful TransactionState = "SUCCESSFUL"
TransactionStateFailed TransactionState = "FAILED"
TransactionStateSuspended TransactionState = "SUSPENDED"
)
func (s TransactionState) Valid() bool {
switch s {
case TransactionStateCreated,
TransactionStatePendingTransaction,
TransactionStatePendingAdmin,
TransactionStateSuccessful,
TransactionStateFailed,
TransactionStateSuspended:
return true
default:
return false
}
}
type TransactionEvent struct {
ID string
SourceService string
IdempotencyKey string
SourceTransactionID string
TrackingCode string
EventVersion uint32
State TransactionState
ErrorCode string
ErrorMessage string
OccurredAt time.Time
RecordedAt time.Time
CorrelationID string
ActorID string
Blockchain BlockchainReference
Metadata map[string]string
PayloadHash string
}
func (e TransactionEvent) Validate() error {
if e.ID == "" || e.SourceService == "" || e.IdempotencyKey == "" || e.SourceTransactionID == "" {
return fmt.Errorf("transaction event identity fields are required")
}
if e.EventVersion == 0 {
return fmt.Errorf("event version must be positive")
}
if !e.State.Valid() {
return fmt.Errorf("invalid transaction state %q", e.State)
}
if e.OccurredAt.IsZero() {
return fmt.Errorf("occurred time is required")
}
if len(e.PayloadHash) != 64 || e.PayloadHash != strings.ToLower(e.PayloadHash) {
return fmt.Errorf("payload hash must be a lowercase SHA-256 hex string")
}
if _, err := hex.DecodeString(e.PayloadHash); err != nil {
return fmt.Errorf("payload hash must be a lowercase SHA-256 hex string")
}
return nil
}