package orderStatusActions import ( "git.ma-al.com/goc_daniel/b2b/app/model" "git.ma-al.com/goc_daniel/b2b/app/model/enums" "git.ma-al.com/goc_daniel/b2b/app/service/emailService" "git.ma-al.com/goc_daniel/b2b/app/utils/logger" ) var GlobalRegistry = make(ActionRegistry) type ActionID string type ActionContext struct { Order *model.CustomerOrder UserId *uint EmailService *emailService.EmailService } type ActionResult struct { Err error Metadata map[string]any } type OrderAction interface { ID() ActionID Execute(actionCtx ActionContext) ActionResult } type ActionChain []OrderAction func (c ActionChain) Execute(actionCtx ActionContext) []ActionResult { results := make([]ActionResult, 0, len(c)) for _, action := range c { result := action.Execute(actionCtx) results = append(results, result) if result.Err != nil { logger.Debug("action failed", "action_id", action.ID(), "order", actionCtx.Order, "user_id", actionCtx.UserId, "error", result.Err, ) } } return results } type ActionRegistry map[enums.OrderStatus]ActionChain func (r ActionRegistry) Register(status enums.OrderStatus, chain ActionChain) { r[status] = chain } func (r ActionRegistry) ExecuteForStatus(status enums.OrderStatus, actionCtx ActionContext) []ActionResult { chain, exists := r[status] if !exists { return nil } return chain.Execute(actionCtx) } type ActionFunc func(actionCtx ActionContext) ActionResult func (f ActionFunc) ID() ActionID { return "anonymous" } func (f ActionFunc) Execute(actionCtx ActionContext) ActionResult { return f(actionCtx) } type actionAdapter struct { id ActionID fn ActionFunc } func (a *actionAdapter) ID() ActionID { return a.id } func (a *actionAdapter) Execute(actionCtx ActionContext) ActionResult { return a.fn(actionCtx) } func WithID(id ActionID, fn ActionFunc) OrderAction { return &actionAdapter{id: id, fn: fn} }