ultisuite-backend/internal/api/mail/service_rules_simulate.go
R3D347HR4Y cd0a80f5e8 huhu
2026-05-25 13:52:27 +02:00

102 lines
2.9 KiB
Go

package mail
import (
"context"
"encoding/json"
"errors"
"github.com/jackc/pgx/v5"
"github.com/ultisuite/ulti-backend/internal/mail/rules"
)
func (s *Service) SimulateRule(ctx context.Context, externalID string, req *simulateRuleRequest) (any, error) {
msg := &rules.Message{
ID: "simulation",
From: req.Message.From,
To: req.Message.To,
Subject: req.Message.Subject,
BodyText: req.Message.BodyText,
HasAttachments: req.Message.HasAttachments,
Labels: req.Message.Labels,
}
engine := rules.NewEngine(s.db)
wf, conditions, actions, err := s.resolveSimulateRulePayload(ctx, externalID, req)
if err != nil {
return nil, err
}
if wf != nil && len(wf.Nodes) > 0 {
var userID string
_ = s.db.QueryRow(ctx, `SELECT id FROM users WHERE external_id = $1`, externalID).Scan(&userID)
return engine.SimulateWorkflow(ctx, userID, wf, msg, &rules.EventContext{Type: rules.TriggerMessageReceived}), nil
}
return engine.SimulateRule(ctx, conditions, actions, msg), nil
}
func (s *Service) resolveSimulateRulePayload(ctx context.Context, externalID string, req *simulateRuleRequest) (*rules.Workflow, []rules.Condition, []rules.Action, error) {
if req.RuleID != "" {
var condJSON, actJSON, wfJSON []byte
err := s.db.QueryRow(ctx, `
SELECT conditions, actions, workflow
FROM mail_rules
WHERE id = $1 AND user_id = (SELECT id FROM users WHERE external_id = $2)
`, req.RuleID, externalID).Scan(&condJSON, &actJSON, &wfJSON)
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return nil, nil, nil, ErrNotFound
}
return nil, nil, nil, err
}
wf, err := rules.ParseWorkflow(wfJSON)
if err != nil {
return nil, nil, nil, err
}
if wf != nil && len(wf.Nodes) > 0 {
return wf, nil, nil, nil
}
conditions, actions, err := unmarshalRuleConditionsActions(condJSON, actJSON)
return nil, conditions, actions, err
}
if req.Rule.Workflow != nil {
wfJSON, err := json.Marshal(req.Rule.Workflow)
if err != nil {
return nil, nil, nil, err
}
wf, err := rules.ParseWorkflow(wfJSON)
if err != nil {
return nil, nil, nil, err
}
if wf != nil && len(wf.Nodes) > 0 {
return wf, nil, nil, nil
}
}
condJSON, err := json.Marshal(req.Rule.Conditions)
if err != nil {
return nil, nil, nil, err
}
actJSON, err := json.Marshal(req.Rule.Actions)
if err != nil {
return nil, nil, nil, err
}
conditions, actions, err := unmarshalRuleConditionsActions(condJSON, actJSON)
return nil, conditions, actions, err
}
func unmarshalRuleConditionsActions(condJSON, actJSON []byte) ([]rules.Condition, []rules.Action, error) {
var conditions []rules.Condition
var actions []rules.Action
if err := json.Unmarshal(condJSON, &conditions); err != nil {
return nil, nil, err
}
if err := json.Unmarshal(actJSON, &actions); err != nil {
return nil, nil, err
}
return conditions, actions, nil
}