feat(backend): implement order state machine with validation
This commit is contained in:
parent
89036d7b39
commit
132fef816c
3 changed files with 40 additions and 0 deletions
|
|
@ -395,7 +395,10 @@ const (
|
|||
OrderStatusPending OrderStatus = "Pendente"
|
||||
OrderStatusPaid OrderStatus = "Pago"
|
||||
OrderStatusInvoiced OrderStatus = "Faturado"
|
||||
OrderStatusShipped OrderStatus = "Enviado"
|
||||
OrderStatusDelivered OrderStatus = "Entregue"
|
||||
OrderStatusCompleted OrderStatus = "Concluído"
|
||||
OrderStatusCancelled OrderStatus = "Cancelado"
|
||||
)
|
||||
|
||||
// PaymentMethod enumerates supported payment types.
|
||||
|
|
|
|||
|
|
@ -337,6 +337,37 @@ func (s *Service) GetOrder(ctx context.Context, id uuid.UUID) (*domain.Order, er
|
|||
}
|
||||
|
||||
func (s *Service) UpdateOrderStatus(ctx context.Context, id uuid.UUID, status domain.OrderStatus) error {
|
||||
order, err := s.repo.GetOrder(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// State Machine Logic
|
||||
switch order.Status {
|
||||
case domain.OrderStatusPending:
|
||||
if status != domain.OrderStatusPaid && status != domain.OrderStatusCancelled {
|
||||
return errors.New("invalid transition from Pending")
|
||||
}
|
||||
case domain.OrderStatusPaid:
|
||||
if status != domain.OrderStatusInvoiced && status != domain.OrderStatusShipped && status != domain.OrderStatusCancelled {
|
||||
return errors.New("invalid transition from Paid")
|
||||
}
|
||||
case domain.OrderStatusInvoiced: // Can go to Shipped
|
||||
if status != domain.OrderStatusShipped && status != domain.OrderStatusCancelled {
|
||||
return errors.New("invalid transition from Invoiced")
|
||||
}
|
||||
case domain.OrderStatusShipped:
|
||||
if status != domain.OrderStatusDelivered {
|
||||
return errors.New("invalid transition from Shipped")
|
||||
}
|
||||
case domain.OrderStatusDelivered:
|
||||
if status != domain.OrderStatusCompleted {
|
||||
return errors.New("invalid transition from Delivered")
|
||||
}
|
||||
case domain.OrderStatusCompleted, domain.OrderStatusCancelled:
|
||||
return errors.New("order is in terminal state")
|
||||
}
|
||||
|
||||
return s.repo.UpdateOrderStatus(ctx, id, status)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -646,6 +646,12 @@ func TestUpdateOrderStatus(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("failed to update order status: %v", err)
|
||||
}
|
||||
|
||||
// Test invalid transition
|
||||
err = svc.UpdateOrderStatus(ctx, order.ID, domain.OrderStatusDelivered) // Paid -> Delivered is invalid (skip Shipped)
|
||||
if err == nil {
|
||||
t.Error("expected error for invalid transition Paid -> Delivered")
|
||||
}
|
||||
}
|
||||
|
||||
// --- User Tests ---
|
||||
|
|
|
|||
Loading…
Reference in a new issue