Documentation
¶
Index ¶
- Variables
- func NewAllPassStrategy() approval.PassRuleStrategy
- func NewExpressionConditionEvaluator() approval.ConditionEvaluator
- func NewFieldConditionEvaluator() approval.ConditionEvaluator
- func NewOnePassStrategy() approval.PassRuleStrategy
- func NewOneRejectStrategy() approval.PassRuleStrategy
- func NewRatioPassStrategy() approval.PassRuleStrategy
- type AllPassStrategy
- type AssigneeResolver
- func NewDepartmentAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
- func NewDepartmentLeaderAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
- func NewFormFieldAssigneeResolver() AssigneeResolver
- func NewRoleAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
- func NewSelfAssigneeResolver() AssigneeResolver
- func NewSuperiorAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
- func NewUserAssigneeResolver() AssigneeResolver
- type CompositeAssigneeResolver
- type DepartmentAssigneeResolver
- type DepartmentLeaderAssigneeResolver
- type ExpressionConditionEvaluator
- type FieldConditionEvaluator
- type FormFieldAssigneeResolver
- type OnePassStrategy
- type OneRejectStrategy
- type RatioPassStrategy
- type ResolveContext
- type RoleAssigneeResolver
- type SelfAssigneeResolver
- type StrategyRegistry
- func (r *StrategyRegistry) CompositeAssigneeResolver() *CompositeAssigneeResolver
- func (r *StrategyRegistry) GetConditionEvaluator(t approval.ConditionKind) (approval.ConditionEvaluator, error)
- func (r *StrategyRegistry) GetPassRuleStrategy(rule approval.PassRule) (approval.PassRuleStrategy, error)
- func (r *StrategyRegistry) ValidateBuiltins() error
- type SuperiorAssigneeResolver
- type UserAssigneeResolver
Constants ¶
This section is empty.
Variables ¶
var ( // Assignee resolver errors. ErrAssigneeServiceNil = errors.New("assignee service is nil") ErrApplicantIDEmpty = errors.New("applicant ID is empty") ErrFormFieldNameEmpty = errors.New("form field name is empty") ErrFormFieldValueEmpty = errors.New("form field value is empty") ErrUnsupportedFieldValueType = errors.New("unsupported form field value type") ErrAssigneeResolverNotFound = errors.New("assignee resolver not found") // Registry lookup errors. ErrPassRuleNotFound = errors.New("pass rule strategy not found") ErrConditionEvaluatorNotFound = errors.New("condition evaluator not found") // Expression evaluation errors. ErrExpressionReturnedNonBool = errors.New("expression returned non-bool type") )
var Module = fx.Module( "vef:approval:strategy", fx.Provide( fx.Annotate(NewAllPassStrategy, fx.ResultTags(`group:"vef:approval:pass_rule_strategies"`)), fx.Annotate(NewOnePassStrategy, fx.ResultTags(`group:"vef:approval:pass_rule_strategies"`)), fx.Annotate(NewRatioPassStrategy, fx.ResultTags(`group:"vef:approval:pass_rule_strategies"`)), fx.Annotate(NewOneRejectStrategy, fx.ResultTags(`group:"vef:approval:pass_rule_strategies"`)), fx.Annotate(NewUserAssigneeResolver, fx.ResultTags(`group:"vef:approval:assignee_resolvers"`)), fx.Annotate(NewRoleAssigneeResolver, fx.ResultTags(`group:"vef:approval:assignee_resolvers"`)), fx.Annotate(NewDepartmentAssigneeResolver, fx.ResultTags(`group:"vef:approval:assignee_resolvers"`)), fx.Annotate(NewSelfAssigneeResolver, fx.ResultTags(`group:"vef:approval:assignee_resolvers"`)), fx.Annotate(NewSuperiorAssigneeResolver, fx.ResultTags(`group:"vef:approval:assignee_resolvers"`)), fx.Annotate(NewDepartmentLeaderAssigneeResolver, fx.ResultTags(`group:"vef:approval:assignee_resolvers"`)), fx.Annotate(NewFormFieldAssigneeResolver, fx.ResultTags(`group:"vef:approval:assignee_resolvers"`)), fx.Annotate(NewFieldConditionEvaluator, fx.ResultTags(`group:"vef:approval:condition_evaluators"`)), fx.Annotate(NewExpressionConditionEvaluator, fx.ResultTags(`group:"vef:approval:condition_evaluators"`)), fx.Annotate( NewStrategyRegistry, fx.ParamTags( `group:"vef:approval:pass_rule_strategies"`, `group:"vef:approval:assignee_resolvers"`, `group:"vef:approval:condition_evaluators"`, ), ), ), fx.Invoke(func(r *StrategyRegistry) error { return r.ValidateBuiltins() }), )
Module provides built-in strategies with FX group extensibility.
Functions ¶
func NewAllPassStrategy ¶
func NewAllPassStrategy() approval.PassRuleStrategy
NewAllPassStrategy creates a new AllPassStrategy.
func NewExpressionConditionEvaluator ¶
func NewExpressionConditionEvaluator() approval.ConditionEvaluator
NewExpressionConditionEvaluator creates a new ExpressionConditionEvaluator.
func NewFieldConditionEvaluator ¶
func NewFieldConditionEvaluator() approval.ConditionEvaluator
NewFieldConditionEvaluator creates a new FieldConditionEvaluator.
func NewOnePassStrategy ¶
func NewOnePassStrategy() approval.PassRuleStrategy
NewOnePassStrategy creates a new OnePassStrategy.
func NewOneRejectStrategy ¶
func NewOneRejectStrategy() approval.PassRuleStrategy
NewOneRejectStrategy creates a new OneRejectStrategy.
func NewRatioPassStrategy ¶
func NewRatioPassStrategy() approval.PassRuleStrategy
NewRatioPassStrategy creates a new RatioPassStrategy.
Types ¶
type AllPassStrategy ¶
type AllPassStrategy struct{}
AllPassStrategy requires all assignees to approve.
func (*AllPassStrategy) Evaluate ¶
func (*AllPassStrategy) Evaluate(ctx approval.PassRuleContext) approval.PassRuleResult
func (*AllPassStrategy) Rule ¶
func (*AllPassStrategy) Rule() approval.PassRule
type AssigneeResolver ¶
type AssigneeResolver interface {
// Kind returns the assignee kind this resolver handles (user, role, department_leader, superior, etc.).
Kind() approval.AssigneeKind
// Resolve resolves concrete assignees from the assignee configuration in ResolveContext.
Resolve(ctx context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)
}
AssigneeResolver resolves assignees for a specific kind.
func NewDepartmentAssigneeResolver ¶ added in v0.20.1
func NewDepartmentAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
NewDepartmentAssigneeResolver creates a new DepartmentAssigneeResolver.
func NewDepartmentLeaderAssigneeResolver ¶ added in v0.20.1
func NewDepartmentLeaderAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
NewDepartmentLeaderAssigneeResolver creates a new DepartmentLeaderAssigneeResolver.
func NewFormFieldAssigneeResolver ¶
func NewFormFieldAssigneeResolver() AssigneeResolver
NewFormFieldAssigneeResolver creates a new FormFieldAssigneeResolver.
func NewRoleAssigneeResolver ¶
func NewRoleAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
NewRoleAssigneeResolver creates a new RoleAssigneeResolver.
func NewSelfAssigneeResolver ¶
func NewSelfAssigneeResolver() AssigneeResolver
NewSelfAssigneeResolver creates a new SelfAssigneeResolver.
func NewSuperiorAssigneeResolver ¶
func NewSuperiorAssigneeResolver(svc approval.AssigneeService) AssigneeResolver
NewSuperiorAssigneeResolver creates a new SuperiorAssigneeResolver.
func NewUserAssigneeResolver ¶
func NewUserAssigneeResolver() AssigneeResolver
NewUserAssigneeResolver creates a new UserAssigneeResolver.
type CompositeAssigneeResolver ¶
type CompositeAssigneeResolver struct {
// contains filtered or unexported fields
}
CompositeAssigneeResolver chains multiple resolvers and resolves assignees based on config kind.
func NewCompositeAssigneeResolver ¶
func NewCompositeAssigneeResolver(resolvers ...AssigneeResolver) *CompositeAssigneeResolver
NewCompositeAssigneeResolver creates a composite resolver from individual resolvers.
func (*CompositeAssigneeResolver) ResolveAll ¶
func (c *CompositeAssigneeResolver) ResolveAll(ctx context.Context, assignees []approval.FlowNodeAssignee, baseRC *ResolveContext) ([]approval.ResolvedAssignee, error)
ResolveAll resolves assignees from multiple configs.
type DepartmentAssigneeResolver ¶ added in v0.20.1
type DepartmentAssigneeResolver struct {
// contains filtered or unexported fields
}
DepartmentAssigneeResolver resolves department leaders as assignees.
func (*DepartmentAssigneeResolver) Kind ¶ added in v0.20.1
func (*DepartmentAssigneeResolver) Kind() approval.AssigneeKind
func (*DepartmentAssigneeResolver) Resolve ¶ added in v0.20.1
func (r *DepartmentAssigneeResolver) Resolve(ctx context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)
type DepartmentLeaderAssigneeResolver ¶ added in v0.20.1
type DepartmentLeaderAssigneeResolver struct {
// contains filtered or unexported fields
}
DepartmentLeaderAssigneeResolver resolves department leaders as assignees.
func (*DepartmentLeaderAssigneeResolver) Kind ¶ added in v0.20.1
func (*DepartmentLeaderAssigneeResolver) Kind() approval.AssigneeKind
func (*DepartmentLeaderAssigneeResolver) Resolve ¶ added in v0.20.1
func (r *DepartmentLeaderAssigneeResolver) Resolve(ctx context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)
type ExpressionConditionEvaluator ¶
type ExpressionConditionEvaluator struct{}
ExpressionConditionEvaluator evaluates expr-lang expressions.
func (*ExpressionConditionEvaluator) Evaluate ¶
func (*ExpressionConditionEvaluator) Evaluate(_ context.Context, cond approval.Condition, ec *approval.EvaluationContext) (bool, error)
func (*ExpressionConditionEvaluator) Kind ¶
func (*ExpressionConditionEvaluator) Kind() approval.ConditionKind
type FieldConditionEvaluator ¶
type FieldConditionEvaluator struct {
// contains filtered or unexported fields
}
FieldConditionEvaluator evaluates field-based conditions by converting them to expressions and delegating to ExpressionConditionEvaluator.
func (*FieldConditionEvaluator) Evaluate ¶
func (e *FieldConditionEvaluator) Evaluate(ctx context.Context, cond approval.Condition, ec *approval.EvaluationContext) (bool, error)
func (*FieldConditionEvaluator) Kind ¶
func (*FieldConditionEvaluator) Kind() approval.ConditionKind
type FormFieldAssigneeResolver ¶
type FormFieldAssigneeResolver struct{}
FormFieldAssigneeResolver resolves assignees from a form field value.
func (*FormFieldAssigneeResolver) Kind ¶
func (*FormFieldAssigneeResolver) Kind() approval.AssigneeKind
func (*FormFieldAssigneeResolver) Resolve ¶
func (*FormFieldAssigneeResolver) Resolve(ctx context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)
type OnePassStrategy ¶
type OnePassStrategy struct{}
OnePassStrategy passes when at least one assignee approves.
func (*OnePassStrategy) Evaluate ¶
func (*OnePassStrategy) Evaluate(ctx approval.PassRuleContext) approval.PassRuleResult
func (*OnePassStrategy) Rule ¶
func (*OnePassStrategy) Rule() approval.PassRule
type OneRejectStrategy ¶
type OneRejectStrategy struct{}
OneRejectStrategy fails when any assignee rejects (veto power). Note: the Evaluate logic is identical to AllPassStrategy because both strategies share the same semantics under the current PassRuleContext model — any rejection causes failure, and all must approve for success. They are kept separate as distinct PassRule enum values so they can diverge if PassRuleContext is extended in the future (e.g., with an "abstain" status).
func (*OneRejectStrategy) Evaluate ¶
func (*OneRejectStrategy) Evaluate(ctx approval.PassRuleContext) approval.PassRuleResult
func (*OneRejectStrategy) Rule ¶
func (*OneRejectStrategy) Rule() approval.PassRule
type RatioPassStrategy ¶
type RatioPassStrategy struct{}
RatioPassStrategy passes when approval ratio meets threshold.
func (*RatioPassStrategy) Evaluate ¶
func (*RatioPassStrategy) Evaluate(ctx approval.PassRuleContext) approval.PassRuleResult
func (*RatioPassStrategy) Rule ¶
func (*RatioPassStrategy) Rule() approval.PassRule
type ResolveContext ¶
type ResolveContext struct {
DB orm.DB
ApplicantID string
ApplicantName string
ApplicantDepartmentID *string
FormData approval.FormData
UserResolver approval.UserInfoResolver
IDs []string
FormField *string
}
ResolveContext provides context for assignee resolution.
type RoleAssigneeResolver ¶
type RoleAssigneeResolver struct {
// contains filtered or unexported fields
}
RoleAssigneeResolver resolves assignees from role IDs via AssigneeService.
func (*RoleAssigneeResolver) Kind ¶
func (*RoleAssigneeResolver) Kind() approval.AssigneeKind
func (*RoleAssigneeResolver) Resolve ¶
func (r *RoleAssigneeResolver) Resolve(ctx context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)
type SelfAssigneeResolver ¶
type SelfAssigneeResolver struct{}
SelfAssigneeResolver resolves the applicant as assignee.
func (*SelfAssigneeResolver) Kind ¶
func (*SelfAssigneeResolver) Kind() approval.AssigneeKind
func (*SelfAssigneeResolver) Resolve ¶
func (*SelfAssigneeResolver) Resolve(_ context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)
type StrategyRegistry ¶
type StrategyRegistry struct {
// contains filtered or unexported fields
}
StrategyRegistry holds all strategy implementations indexed by their type.
func NewStrategyRegistry ¶
func NewStrategyRegistry( passRules []approval.PassRuleStrategy, assignees []AssigneeResolver, conditions []approval.ConditionEvaluator, ) *StrategyRegistry
NewStrategyRegistry creates a registry from slices (designed for FX group injection). It does not validate completeness on construction so test suites can build registries with partial strategy sets. Production modules call ValidateBuiltins via fx.Invoke after construction.
func (*StrategyRegistry) CompositeAssigneeResolver ¶
func (r *StrategyRegistry) CompositeAssigneeResolver() *CompositeAssigneeResolver
CompositeAssigneeResolver returns the cached CompositeAssigneeResolver.
func (*StrategyRegistry) GetConditionEvaluator ¶
func (r *StrategyRegistry) GetConditionEvaluator(t approval.ConditionKind) (approval.ConditionEvaluator, error)
GetConditionEvaluator returns the condition evaluator for the given type.
func (*StrategyRegistry) GetPassRuleStrategy ¶
func (r *StrategyRegistry) GetPassRuleStrategy(rule approval.PassRule) (approval.PassRuleStrategy, error)
GetPassRuleStrategy returns the pass rule strategy for the given rule.
func (*StrategyRegistry) ValidateBuiltins ¶ added in v0.24.0
func (r *StrategyRegistry) ValidateBuiltins() error
ValidateBuiltins asserts that every built-in enum value the framework guarantees has a registered strategy. The production strategy.Module invokes this during boot so misconfigurations surface immediately rather than as a runtime "strategy not found" error deep inside a flow.
type SuperiorAssigneeResolver ¶
type SuperiorAssigneeResolver struct {
// contains filtered or unexported fields
}
SuperiorAssigneeResolver resolves the direct superior as assignee.
func (*SuperiorAssigneeResolver) Kind ¶
func (*SuperiorAssigneeResolver) Kind() approval.AssigneeKind
func (*SuperiorAssigneeResolver) Resolve ¶
func (r *SuperiorAssigneeResolver) Resolve(ctx context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)
type UserAssigneeResolver ¶
type UserAssigneeResolver struct{}
UserAssigneeResolver resolves assignees from fixed user IDs.
func (*UserAssigneeResolver) Kind ¶
func (*UserAssigneeResolver) Kind() approval.AssigneeKind
func (*UserAssigneeResolver) Resolve ¶
func (*UserAssigneeResolver) Resolve(ctx context.Context, rc *ResolveContext) ([]approval.ResolvedAssignee, error)