Class: Insika::Commands::ApproveAction
- Inherits:
-
Object
- Object
- Insika::Commands::ApproveAction
- Defined in:
- lib/insika/commands/approve_action.rb
Overview
Control command: the operator resolves a pending action (human-in-the-loop). Resolves the PendingAction in the store (durable source of truth) and WAKES the turn suspended on :waiting by posting :approval to the live fiber. Order matters: RESOLVE before posting — when the await wakes, the store already has the decision (request_approval re-reads it from there). Crash-safe: with no live fiber the post is a no-op; recovery re-executes and uses the durable decision.
Payload { pending_id:, decision: "approved"|"rejected", operator?: }.
-> resolved PendingAction.
Instance Method Summary collapse
- #call(command) ⇒ Object
-
#initialize(pending_action_store:, executor:, event_stream:) ⇒ ApproveAction
constructor
A new instance of ApproveAction.
Constructor Details
#initialize(pending_action_store:, executor:, event_stream:) ⇒ ApproveAction
Returns a new instance of ApproveAction.
17 18 19 20 21 |
# File 'lib/insika/commands/approve_action.rb', line 17 def initialize(pending_action_store:, executor:, event_stream:) @pending_action_store = pending_action_store @executor = executor @event_stream = event_stream end |
Instance Method Details
#call(command) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/insika/commands/approve_action.rb', line 23 def call(command) p = command.payload pending_id = (p[:pending_id] || p["pending_id"]).to_s decision = (p[:decision] || p["decision"]).to_s raise Insika::ValidationError, "pending_id is required" if pending_id.empty? # operator: from the operator's auth (Control UI) via payload; nil ok. operator = p[:operator] || p["operator"] || command.[:operator] # resolve() validates the decision and the state (:pending); NotFound if absent. resolved = @pending_action_store.resolve(pending_id, decision: decision, operator: operator) @executor.approve(resolved.task_id) # wakes the live fiber (no-op if it crashed) @event_stream.emit(Insika::Event.new( type: :approval_resolved, data: { pending_id: pending_id, decision: resolved.status, task_id: resolved.task_id, resolved_by: operator }, meta: { task_id: resolved.task_id, at: Time.now.utc.iso8601 } )) resolved end |