Class: ApprovalEngine::ApprovalBuilder
- Inherits:
-
Object
- Object
- ApprovalEngine::ApprovalBuilder
- Defined in:
- app/services/approval_engine/approval_builder.rb
Overview
Stamps a concrete, actionable ledger (Approval → Track → Steps) out of one or more abstract TrackTemplates.
A single template builds a single-track approval. Several templates build a scatter-gather approval: one parallel track per template, all active at once, gathering per the approval’s ‘approvals_required` (`:all` by default).
Each template step is expanded into one Step per resolved actor — so “any one of five senior devs” becomes five sibling steps sharing one consensus policy. Only each track’s first layer starts ‘pending`; later layers wait until the layer before them resolves.
Defined Under Namespace
Classes: BuilderError
Class Method Summary collapse
-
.build!(template:, target:, event_name: nil, trigger_rule: nil) ⇒ Object
Build a single-track approval from one template.
-
.build_parallel!(templates:, target:, event_name: nil, approvals_required: "all") ⇒ Object
Build a scatter-gather approval, one parallel track per template.
-
.build_quarantine_approval!(target:, tenant_id:, reason:) ⇒ Object
The fail-closed quarantine state.
Instance Method Summary collapse
- #build! ⇒ Object
-
#initialize(templates:, target:, event_name: nil, trigger_rule: nil, approvals_required: "all") ⇒ ApprovalBuilder
constructor
A new instance of ApprovalBuilder.
Constructor Details
#initialize(templates:, target:, event_name: nil, trigger_rule: nil, approvals_required: "all") ⇒ ApprovalBuilder
Returns a new instance of ApprovalBuilder.
32 33 34 35 36 37 38 |
# File 'app/services/approval_engine/approval_builder.rb', line 32 def initialize(templates:, target:, event_name: nil, trigger_rule: nil, approvals_required: "all") @templates = templates @target = target @event_name = event_name @trigger_rule = trigger_rule @approvals_required = approvals_required.to_s end |
Class Method Details
.build!(template:, target:, event_name: nil, trigger_rule: nil) ⇒ Object
Build a single-track approval from one template. ‘event_name` is the event that triggered this run (nil when started manually) — recorded on the Approval for audit/display. `trigger_rule` is the rule that matched, when auto-routed, so the approval remembers its provenance.
20 21 22 |
# File 'app/services/approval_engine/approval_builder.rb', line 20 def self.build!(template:, target:, event_name: nil, trigger_rule: nil) new(templates: [ template ], target: target, event_name: event_name, trigger_rule: trigger_rule).build! end |
.build_parallel!(templates:, target:, event_name: nil, approvals_required: "all") ⇒ Object
Build a scatter-gather approval, one parallel track per template. ‘approvals_required` is the gather consensus (default `:all`).
26 27 28 29 30 |
# File 'app/services/approval_engine/approval_builder.rb', line 26 def self.build_parallel!(templates:, target:, event_name: nil, approvals_required: "all") raise BuilderError, "build_parallel! needs at least one template" if templates.blank? new(templates: templates, target: target, event_name: event_name, approvals_required: approvals_required).build! end |
.build_quarantine_approval!(target:, tenant_id:, reason:) ⇒ Object
The fail-closed quarantine state. Built when a dynamic rule blows up, so ops can see exactly why a track never started instead of hitting a 500.
52 53 54 55 56 57 58 59 60 61 |
# File 'app/services/approval_engine/approval_builder.rb', line 52 def self.build_quarantine_approval!(target:, tenant_id:, reason:) Approval.create!(tenant_id: tenant_id, target: target, status: "quarantined").tap do |approval| OutboxEvent.create!( tenant_id: approval.tenant_id, event_name: "approval.quarantined", record: approval, error_payload: reason ) end end |
Instance Method Details
#build! ⇒ Object
40 41 42 43 44 45 46 47 48 |
# File 'app/services/approval_engine/approval_builder.rb', line 40 def build! guard_single_tenant! guard_gather_consensus! ActiveRecord::Base.transaction do approval = build_approval templates.each { |template| build_track!(approval, template) } approval end end |