mirror of
https://github.com/hanzo-fi/stack.git
synced 2026-10-30 20:34:43 +00:00
174 lines
4.2 KiB
Go
174 lines
4.2 KiB
Go
package triggers
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
|
|
sharedapi "github.com/formancehq/stack/libs/go-libs/api"
|
|
"github.com/formancehq/stack/libs/go-libs/bun/bunpaginate"
|
|
|
|
"github.com/formancehq/orchestration/internal/workflow"
|
|
"github.com/pkg/errors"
|
|
"github.com/uptrace/bun"
|
|
)
|
|
|
|
var ErrWorkflowNotExists = errors.New("workflow does not exists")
|
|
|
|
type VariableEvaluationResult struct {
|
|
Value string `json:"value,omitempty"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
type FilterEvaluationResult struct {
|
|
Match bool `json:"match"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
type TestTriggerResult struct {
|
|
Filter *FilterEvaluationResult `json:"filter"`
|
|
Variables map[string]VariableEvaluationResult `json:"variables"`
|
|
}
|
|
|
|
type TriggerManager struct {
|
|
db *bun.DB
|
|
expressionEvaluator *expressionEvaluator
|
|
}
|
|
|
|
func (m *TriggerManager) ListTriggers(ctx context.Context, query ListTriggersQuery) (*sharedapi.Cursor[Trigger], error) {
|
|
ret := make([]Trigger, 0)
|
|
q := m.db.NewSelect().
|
|
Model(&ret).
|
|
Where("deleted_at is null")
|
|
|
|
return bunpaginate.UsingOffset[any, Trigger](ctx, q, bunpaginate.OffsetPaginatedQuery[any](query))
|
|
}
|
|
|
|
func (m *TriggerManager) TestTrigger(ctx context.Context, triggerID string, event map[string]any) (*TestTriggerResult, error) {
|
|
trigger := &Trigger{}
|
|
err := m.db.NewSelect().
|
|
Model(trigger).
|
|
Where("deleted_at is null").
|
|
Where("id = ?", triggerID).
|
|
Scan(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ret := TestTriggerResult{}
|
|
if filter := trigger.Filter; filter != nil {
|
|
ret.Filter = &FilterEvaluationResult{}
|
|
ret.Filter.Match, err = m.expressionEvaluator.evalFilter(event, *filter)
|
|
if err != nil {
|
|
ret.Filter.Error = err.Error()
|
|
}
|
|
}
|
|
if (ret.Filter == nil || ret.Filter.Match) && len(trigger.Vars) > 0 {
|
|
ret.Variables = map[string]VariableEvaluationResult{}
|
|
for key, expr := range trigger.Vars {
|
|
v := VariableEvaluationResult{}
|
|
v.Value, err = m.expressionEvaluator.evalVariable(event, expr)
|
|
if err != nil {
|
|
v.Error = err.Error()
|
|
}
|
|
ret.Variables[key] = v
|
|
}
|
|
}
|
|
|
|
return &ret, nil
|
|
}
|
|
|
|
func (m *TriggerManager) GetTrigger(ctx context.Context, triggerID string) (*Trigger, error) {
|
|
ret := &Trigger{}
|
|
err := m.db.NewSelect().
|
|
Model(ret).
|
|
Where("deleted_at is null").
|
|
Where("id = ?", triggerID).
|
|
Scan(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ret, nil
|
|
}
|
|
|
|
func (m *TriggerManager) DeleteTrigger(ctx context.Context, triggerID string) error {
|
|
updated, err := m.db.NewUpdate().
|
|
Model(&Trigger{}).
|
|
Where("deleted_at is null").
|
|
Where("id = ?", triggerID).
|
|
Set("deleted_at = ?", time.Now()).
|
|
Exec(ctx)
|
|
rowsAffected, err := updated.RowsAffected()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if rowsAffected == 0 {
|
|
return sql.ErrNoRows
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (m *TriggerManager) CreateTrigger(ctx context.Context, data TriggerData) (*Trigger, error) {
|
|
|
|
if err := data.Validate(); err != nil {
|
|
return nil, errors.Wrap(err, "validating data")
|
|
}
|
|
|
|
exists, err := m.db.NewSelect().
|
|
Model(&workflow.Workflow{}).
|
|
Where("deleted_at is null").
|
|
Where("id = ?", data.WorkflowID).
|
|
Exists(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !exists {
|
|
return nil, ErrWorkflowNotExists
|
|
}
|
|
|
|
trigger, err := NewTrigger(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
_, err = m.db.NewInsert().
|
|
Model(trigger).
|
|
Exec(ctx)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return trigger, nil
|
|
}
|
|
|
|
func (m *TriggerManager) ListTriggersOccurrences(ctx context.Context, query ListTriggersOccurrencesQuery) (*sharedapi.Cursor[Occurrence], error) {
|
|
ret := make([]Occurrence, 0)
|
|
q := m.db.NewSelect().
|
|
Model(&ret).
|
|
Relation("WorkflowInstance")
|
|
|
|
if query.Options.TriggerID != "" {
|
|
q = q.Where("trigger_id = ?", query.Options.TriggerID)
|
|
}
|
|
|
|
return bunpaginate.UsingOffset[ListTriggersOccurrencesOptions, Occurrence](ctx, q, bunpaginate.OffsetPaginatedQuery[ListTriggersOccurrencesOptions](query))
|
|
}
|
|
|
|
func NewManager(db *bun.DB, expressionEvaluator *expressionEvaluator) *TriggerManager {
|
|
return &TriggerManager{
|
|
db: db,
|
|
expressionEvaluator: expressionEvaluator,
|
|
}
|
|
}
|
|
|
|
type ListTriggersQuery bunpaginate.OffsetPaginatedQuery[any]
|
|
|
|
type ListTriggersOccurrencesOptions struct {
|
|
TriggerID string
|
|
}
|
|
|
|
type ListTriggersOccurrencesQuery bunpaginate.OffsetPaginatedQuery[ListTriggersOccurrencesOptions]
|