Documentation
¶
Overview ¶
Package approval implements the optional human-in-the-loop approval layer. It allows selected tasks to be paused until an explicit approval or reject decision is recorded.
Index ¶
- Constants
- func AutoApprove(ctx context.Context, svc Service, interval time.Duration) func()
- func AutoDecider(ctx context.Context, svc Service, fn DecisionFunc, interval time.Duration) (stop func())
- func AutoExpire(ctx context.Context, svc Service, reason string, interval time.Duration) (stop func())
- func AutoReject(ctx context.Context, svc Service, reason string, interval time.Duration) func()
- type Decision
- type DecisionFunc
- type Event
- type PendingFilter
- type Request
- type Service
Constants ¶
const ( TopicRequestCreated = "request.created" TopicRequestUpdated = "request.updated" TopicRequestExpired = "request.expired" TopicDecisionCreated = "decision.created" // legacy – used only for backward compatibility LegacyTopicRequestNew = "request.new" LegacyTopicDecisionNew = "decision.new" )
Standard event topics – keep old names for one transition cycle.
Variables ¶
This section is empty.
Functions ¶
func AutoApprove ¶
AutoApprove automatically approves all pending requests
func AutoDecider ¶
func AutoDecider(ctx context.Context, svc Service, fn DecisionFunc, interval time.Duration) (stop func())
AutoDecider starts a goroutine that polls ListPending and applies fn to every request. It returns stop() – call it (or cancel ctx) to exit.
func AutoExpire ¶ added in v0.1.2
func AutoExpire(ctx context.Context, svc Service, reason string, interval time.Duration) (stop func())
AutoExpire periodically checks pending requests and auto-rejects those whose ExpiresAt deadline has passed. It publishes a request.expired event before recording the rejection decision.
stop := approval.AutoExpire(ctx, svc, "expired", 1*time.Second)
Passing interval <= 0 defaults to 30 s. Empty reason defaults to "expired".
Types ¶
type Decision ¶
type Decision struct {
ID string `json:"id"` // same as request.ID
Approved bool `json:"approved"`
Reason string `json:"reason,omitempty"`
DecidedAt time.Time `json:"decidedAt"`
}
Decision represents approval decision
func WaitForDecision ¶ added in v0.1.2
func WaitForDecision(ctx context.Context, svc Service, id string, timeout time.Duration) (*Decision, error)
WaitForDecision blocks until an approval decision for the given request ID appears on the Service event queue, or the context / timeout expires. It consumes messages from the queue and acknowledges them once processed. If timeout <= 0 the call relies solely on the lifetime of ctx.
type DecisionFunc ¶
DecisionFunc decides what to do with a pending request. Return (true, "") to approve
(false, "…") to reject with reason.
type Event ¶
type Event struct {
Topic string // see topic constants below
Data interface{} // *Request | *Decision
Headers map[string]string `json:"headers,omitempty"` // optional – tenant, correlation-id etc.
}
Event envelope reused from the previous sketch.
type PendingFilter ¶ added in v0.1.2
PendingFilter is a predicate applied to *Request when filtering the list of pending approval requests. All supplied filters must return true for a request to be included in the output slice.
func WithAction ¶ added in v0.1.2
func WithAction(action string) PendingFilter
WithAction returns a PendingFilter that keeps requests whose Action matches the supplied value (empty string disables the filter).
func WithProcessID ¶ added in v0.1.2
func WithProcessID(id string) PendingFilter
WithProcessID returns a PendingFilter that keeps requests whose ProcessID matches the supplied id (empty id disables the filter and passes everything).
type Request ¶
type Request struct {
ID string `json:"id"` // Globally unique, primary key
ProcessID string `json:"processId"` // Refers to process.ID
ExecutionID string `json:"executionId"` // Refers to execution.ID
Action string `json:"action"` // "service.method"
Args json.RawMessage `json:"args,omitempty"` // JSON-encoded expanded input, may be null
CreatedAt time.Time `json:"createdAt"` // RFC-3339 timestamp
ExpiresAt *time.Time `json:"expiresAt,omitempty"` // Optional deadline
Meta map[string]interface{} `json:"meta,omitempty"` // Free-form map: tenant, user, environment, etc.
}
Request represents a request for approval
func ListPending ¶ added in v0.1.2
ListPending returns pending requests that satisfy all provided filters. It delegates the retrieval to Service.ListPending and then applies the filters client-side, avoiding changes to the underlying Service interface.
Example:
reqs, _ := approval.ListPending(ctx, svc, approval.WithProcessID(pid))
type Service ¶
type Service interface {
RequestApproval(ctx context.Context, r *Request) error
ListPending(ctx context.Context) ([]*Request, error)
Decide(ctx context.Context, id string, approved bool, reason string) (*Decision, error)
Queue() messaging.Queue[Event]
}
Service defines the approval service interface.