Module: Plutonium::Wizard

Defined in:
lib/plutonium/wizard.rb,
lib/plutonium/wizard/dsl.rb,
lib/plutonium/wizard/base.rb,
lib/plutonium/wizard/data.rb,
lib/plutonium/wizard/gate.rb,
lib/plutonium/wizard/step.rb,
lib/plutonium/wizard/state.rb,
lib/plutonium/wizard/errors.rb,
lib/plutonium/wizard/resume.rb,
lib/plutonium/wizard/runner.rb,
lib/plutonium/wizard/driving.rb,
lib/plutonium/wizard/session.rb,
lib/plutonium/wizard/sweep_job.rb,
lib/plutonium/wizard/controller.rb,
lib/plutonium/wizard/store/base.rb,
lib/plutonium/wizard/attachments.rb,
lib/plutonium/wizard/review_step.rb,
lib/plutonium/wizard/instance_key.rb,
lib/plutonium/wizard/step_adapter.rb,
lib/plutonium/wizard/store/memory.rb,
lib/plutonium/wizard/configuration.rb,
lib/plutonium/wizard/field_capture.rb,
lib/plutonium/wizard/field_importer.rb,
lib/plutonium/wizard/lazy_persisted.rb,
lib/plutonium/wizard/attachment_data.rb,
lib/plutonium/wizard/base_controller.rb,
lib/plutonium/wizard/route_resolution.rb,
lib/plutonium/wizard/store/active_record.rb

Overview

The Plutonium wizard subsystem: multi-step, DB-backed, data-capture wizards.

Defined Under Namespace

Modules: Attachments, Controller, DSL, Data, Driving, FieldImporter, Gate, InstanceKey, Resume, RouteResolution, Store Classes: AttachmentData, Base, BaseController, Configuration, FieldCapture, LazyPersisted, NotAnchoredError, ReviewStep, Runner, Session, State, Step, StepAdapter, StepError, SweepJob, UnknownWizardError

Class Method Summary collapse

Class Method Details

.compute_instance_key(wizard_class:, current_user:, current_scoped_entity:, anchor:, wizard_token:) ⇒ String

Compute a wizard run's identity digest (§4.1), shared by the runner/driving layer (which creates rows) and the gate (which recomputes the key) so the two are byte-identical — if they diverge, one-time gating silently breaks.

A wizard with a concurrency_key is hashed over its resolved key value(s) (the tenant is folded in by Plutonium::Wizard::Base#concurrency_key_value); otherwise it's hashed over the per-launch wizard_token.

The wizard's concurrency_key resolver and tenancy fold run in a transient wizard instance seeded with the identity context. A resolver that references a missing context method raises a clear error.

Returns:

  • (String)

    the hex SHA256 instance_key



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/plutonium/wizard.rb', line 35

def self.compute_instance_key(wizard_class:, current_user:, current_scoped_entity:, anchor:, wizard_token:)
  unless wizard_class.concurrency_key?
    return InstanceKey.tokened(wizard_class.name, wizard_token)
  end

  probe = wizard_class.new
  probe.current_user = current_user
  probe.current_scoped_entity = current_scoped_entity
  probe.wizard_token = wizard_token
  probe.anchor = anchor if wizard_class.anchored?
  key_value = probe.concurrency_key_value
  InstanceKey.concurrency(wizard_class.name, key_value)
rescue NameError => e
  raise ArgumentError,
    "#{wizard_class.name}'s concurrency_key referenced a method that isn't " \
    "available in this context (#{e.message}). Available: current_user, " \
    "current_scoped_entity, anchor, wizard_token, or a host method."
end

.in_progress_for(view_context, anchor: nil, wizard: nil) ⇒ Array<Plutonium::Wizard::Resume::Entry>

The "continue where you left off" listing (§4.5): in-progress wizard runs for the current user, narrowed to the current tenant scope when the portal is entity-scoped, each enriched with the wizard's label/icon, current step (+ label), updated_at, and a resolved resume_url (nil with a reason when a mount can't be resolved generically).

This is the public, ergonomic API: like interactions, it takes the view_context and derives the run owner and tenant scope from the controller it carries — current_user (the run owner) and current_scoped_entity (the tenant, when scoped_to_entity?; nil for a non-scoped portal). It delegates to Plutonium::Wizard::Resume.entries_for, which does that derivation and builds the resume URLs in this portal.

Plutonium::Wizard.in_progress_for(view_context)
Plutonium::Wizard.in_progress_for(view_context, wizard: ConfigureCompanyWizard)
Plutonium::Wizard.in_progress_for(view_context, anchor: company)

anchor: and wizard: are OPTIONAL narrowing filters applied IN THE QUERY, before each row is enriched (resume-URL built, anchor loaded) — so filtering here is cheaper than select-ing the returned array, which enriches every row first. Use them for the per-record / per-wizard resume widgets (e.g. "does this company have an unfinished configure draft?"). They compose. Omit both for the full "continue where you left off" dashboard list.

Parameters:

  • view_context (ActionView::Base)

    the current view context (as interactions take)

  • anchor (ActiveRecord::Base, nil) (defaults to: nil)

    narrow to runs anchored against this record

  • wizard (Class, nil) (defaults to: nil)

    narrow to runs of this wizard class

Returns:



82
83
84
# File 'lib/plutonium/wizard.rb', line 82

def self.in_progress_for(view_context, anchor: nil, wizard: nil)
  Resume.entries_for(view_context, anchor: anchor, wizard: wizard)
end

.safe_attribute_type(type) ⇒ Object

The union data schema (§2.6) and the runner's inline validator both build anonymous ActiveModel classes from a step's attribute_schema. A using: import contributes the model's column types (e.g. :text), which ActiveModel's type registry doesn't know. Fall back to :string for any type the registry can't resolve so the snapshot/validator still builds — the staged value is stored/displayed as-is.



15
16
17
18
19
20
# File 'lib/plutonium/wizard.rb', line 15

def self.safe_attribute_type(type)
  ActiveModel::Type.lookup(type)
  type
rescue ArgumentError
  :string
end