Class: Rubino::API::Operations::Approvals::DecideOperation

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/api/operations/approvals/decide_operation.rb

Overview

POST /v1/runs/:run_id/approvals/:approval_id Resolves a pending approval gate on a paused run by posting the operator’s decision through the in-process GateRegistry.

Raises:

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repository: nil, registry: nil) ⇒ DecideOperation

Accepts an alternate run repository and gate registry for tests.



20
21
22
23
# File 'lib/rubino/api/operations/approvals/decide_operation.rb', line 20

def initialize(repository: nil, registry: nil)
  @repository = repository || ::Rubino::Run::Repository.new
  @registry = registry || ::Rubino::Run::GateRegistry
end

Class Method Details

.call(request) ⇒ Object



15
16
17
# File 'lib/rubino/api/operations/approvals/decide_operation.rb', line 15

def self.call(request)
  new.call(request)
end

Instance Method Details

#call(request) ⇒ Object

Raises:



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/rubino/api/operations/approvals/decide_operation.rb', line 25

def call(request)
  run_id = request.params.fetch("run_id")
  approval_id = request.params.fetch("approval_id")

  raise NotFoundError.new("run", run_id) unless @repository.find(run_id)

  attrs = request.validate!(Schemas::DecideApproval)
  gate = @registry.fetch(run_id)
  raise ConflictError, "no pending decisions for run #{run_id}" if gate.nil?

  # Wrong-run (or replayed) approval_id: the gate never issued it,
  # so refuse — never let an arbitrary id unblock an unrelated await.
  # Duplicate posts return the originally-resolved decision so
  # retries are idempotent (no double-unblock of the run loop).
  status = gate.decide(approval_id, attrs[:decision])
  raise NotFoundError.new("approval", approval_id) if status == :unknown

  resolved = status == :duplicate ? gate.decision_for(approval_id) : attrs[:decision]
  [200, { approval_id: approval_id, decision: resolved }]
end