Class: Ecoportal::API::GraphQL::Diff::Strategy
- Inherits:
-
Object
- Object
- Ecoportal::API::GraphQL::Diff::Strategy
- Defined in:
- lib/ecoportal/api/graphql/diff/strategy.rb
Overview
Composable configuration for a diff. There is NO single diff — different processes need
different modes (see template_diff_pairing_domain.md §8). A Strategy is the value object
that names the axes, consumed by the diff front-end (VersionDiff / CrossObjectDiff) and
by Deploy.
Axes:
pairing — how counterpart objects are identified across the two snapshots: :id same object, retained Mongo ids (self-version) — NO equivalence needed; :genome pair by genomeSignature (cross-object; a strong-but-fallible signal); :type_label pair by __typename + label (cross-object; the TypedFieldsPairing precedent); :assisted the full multi-signal
Pairing::Engine(+Ledger), human-in-the-loop for ambiguous/unmatched — the general cross-object case.:idis the default and keeps the existing self-version behaviour untouched.scope — which change kinds are emitted: :structural stages / sections / fields (add/remove/move/relabel/retype) + options + gauge; :config_only field configuration (byType), select options, gauge stops — NOT structure; :data_migration field<->field data pairing only (structure-agnostic): pairings + type/label changes on paired fields, no add/remove of scaffolding.
move_sensitive — when false, section/stage MOVES are suppressed (a section-agnostic diff that only cares about a field's data pairing, not where it now lives).
intent — the consuming process (documentation only; does not alter emission, but lets a caller/
Deploybranch on it): :changelog what changed, for a ticket / review checklist; :deploy UAT->PROD replay delta (drives placeholderId threading ON in Deploy); :sync_readiness can this register/subset be synced to the active template.
Cross-object pairings (:genome/:type_label/:assisted) require a pairing map to translate the
two id-spaces before change emission — see CrossObjectDiff. :id needs no map.
Constant Summary collapse
- PAIRINGS =
%i[id genome type_label assisted].freeze
- SCOPES =
%i[structural config_only data_migration].freeze
- INTENTS =
%i[changelog deploy sync_readiness].freeze
- STRUCTURAL_KINDS =
Change KINDS considered structure vs configuration — used to filter by
scope. %i[stage section field].freeze
- CONFIG_KINDS =
%i[field_config option gauge_stop].freeze
Instance Attribute Summary collapse
-
#intent ⇒ Object
readonly
Returns the value of attribute intent.
-
#pairing ⇒ Object
readonly
Returns the value of attribute pairing.
-
#scope ⇒ Object
readonly
Returns the value of attribute scope.
Class Method Summary collapse
-
.default ⇒ Object
The default self-version strategy (id-paired, structural, move-aware, changelog).
Instance Method Summary collapse
-
#cross_object? ⇒ Boolean
True when pairing does NOT rely on retained ids — the two snapshots live in different id-spaces and need a pairing map (
CrossObjectDiff) before change emission. -
#emit_kind?(kind) ⇒ Boolean
Should a change of this KIND be emitted under this scope?.
-
#emit_move? ⇒ Boolean
Should a :moved change be emitted? Suppressed when move-insensitive, or under a scope that ignores scaffolding placement (config_only / data_migration never care about moves).
-
#filter(changes) ⇒ Object
Filter a raw change-set to what this strategy emits (scope + move-sensitivity).
-
#initialize(pairing: :id, scope: :structural, move_sensitive: true, intent: :changelog) ⇒ Strategy
constructor
A new instance of Strategy.
- #move_sensitive? ⇒ Boolean
- #to_h ⇒ Object
Constructor Details
#initialize(pairing: :id, scope: :structural, move_sensitive: true, intent: :changelog) ⇒ Strategy
Returns a new instance of Strategy.
48 49 50 51 52 53 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 48 def initialize(pairing: :id, scope: :structural, move_sensitive: true, intent: :changelog) @pairing = validate!(:pairing, pairing, PAIRINGS) @scope = validate!(:scope, scope, SCOPES) @move_sensitive = move_sensitive ? true : false @intent = validate!(:intent, intent, INTENTS) end |
Instance Attribute Details
#intent ⇒ Object (readonly)
Returns the value of attribute intent.
46 47 48 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 46 def intent @intent end |
#pairing ⇒ Object (readonly)
Returns the value of attribute pairing.
46 47 48 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 46 def pairing @pairing end |
#scope ⇒ Object (readonly)
Returns the value of attribute scope.
46 47 48 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 46 def scope @scope end |
Class Method Details
.default ⇒ Object
The default self-version strategy (id-paired, structural, move-aware, changelog). This is
exactly the behaviour VersionDiff had before Phase 4 — used when no strategy is passed.
57 58 59 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 57 def self.default new end |
Instance Method Details
#cross_object? ⇒ Boolean
True when pairing does NOT rely on retained ids — the two snapshots live in different
id-spaces and need a pairing map (CrossObjectDiff) before change emission.
67 68 69 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 67 def cross_object? @pairing != :id end |
#emit_kind?(kind) ⇒ Boolean
Should a change of this KIND be emitted under this scope?
72 73 74 75 76 77 78 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 72 def emit_kind?(kind) case @scope when :structural then true when :config_only then CONFIG_KINDS.include?(kind) when :data_migration then kind == :field # field-level data pairing only end end |
#emit_move? ⇒ Boolean
Should a :moved change be emitted? Suppressed when move-insensitive, or under a scope that ignores scaffolding placement (config_only / data_migration never care about moves).
82 83 84 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 82 def emit_move? move_sensitive? && @scope == :structural end |
#filter(changes) ⇒ Object
Filter a raw change-set to what this strategy emits (scope + move-sensitivity). The diff front-ends compute the full change-set once and let the strategy decide what survives.
88 89 90 91 92 93 94 95 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 88 def filter(changes) Array(changes).select do |change| next false unless emit_kind?(change.kind) next false if change.op == :moved && !emit_move? true end end |
#move_sensitive? ⇒ Boolean
61 62 63 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 61 def move_sensitive? @move_sensitive end |
#to_h ⇒ Object
97 98 99 |
# File 'lib/ecoportal/api/graphql/diff/strategy.rb', line 97 def to_h { pairing: @pairing, scope: @scope, move_sensitive: move_sensitive?, intent: @intent } end |