Class: OnlineMigrations::DataMigrations::CleanupRedundantElectricalSpecs

Inherits:
OnlineMigrations::DataMigration
  • Object
show all
Defined in:
lib/online_migrations/data_migrations/cleanup_redundant_electrical_specs.rb

Overview

Phase 3 of the towel-warmer wattage reconciliation. Sweeps per-item
static electrical-spec rows (watts, voltage, amps, ohms with
method = 'text', no PL or PC) and either deletes redundant rows or
promotes uniform-safe cohorts to PL templates.

Two decision buckets (audit doc:
doc/tasks/202605080722_ELECTRICAL_SPEC_PL_PC_AUDIT.md):

  1. delete — the spec's value is exactly covered by an existing
    PL/PC-level spec the resolver would otherwise return (audit bucket
    1). Hard delete; items inherit through the existing template.

  2. promote — uniform-safe bucket-2 cohort (≥3 items in same
    primary-PL share value, the PL has no other distinct value for the
    token across all per-item rows, and the PL is not id=117 "Custom").
    Find-or-create a template = true PL spec; link the per-item row
    via template_product_specification_id. The per-item row is kept
    (derived-keep) — same end behavior, plus explicit lineage.

Everything else is skip — bucket 3 (genuinely per-item) and the
bucket-2 cohorts that fail uniformity / land at "Custom" are left
alone for a later, product-team-reviewed pass.

See Also:

Constant Summary collapse

BATCH_SIZE =

Spec rows are heavy on callbacks (translations, render refresh
enqueue). Match SplitShared's BATCH_SIZE.

25
TOKENS =

Tokens we sweep. Mirrors Models::ItemSpecificationHelper::PER_ITEM_SPEC_TOKENS.

Models::ItemSpecificationHelper::PER_ITEM_SPEC_TOKENS.map(&:to_s).freeze
CUSTOM_PL_ID =

PL id for the catch-all "Custom" line. Items in this PL share no
semantic identity, so promoting cohorts here would create
meaningless templates that side-effect onto unrelated future items.

117
TEMPLATE_MIN_COHORT =

Minimum cohort size at (primary_pl_id, token, value) to promote.
Pairs are not promoted — risk/value not high enough.

3

Instance Method Summary collapse

Instance Method Details

#collectionActiveRecord::Batches::BatchEnumerator

Yields batches of per-item static electrical-spec rows that have
not already been processed (template_product_specification_id IS NULL). Idempotent: a re-run after a partial run finds only
remaining rows.

Returns:

  • (ActiveRecord::Batches::BatchEnumerator)


53
54
55
56
57
58
59
60
# File 'lib/online_migrations/data_migrations/cleanup_redundant_electrical_specs.rb', line 53

def collection
  ProductSpecification
    .where(token: TOKENS, method: 'text')
    .where(product_line_id: nil, product_category_id: nil)
    .where(template_product_specification_id: nil)
    .where(id: spec_ids_with_decision)
    .in_batches(of: BATCH_SIZE)
end

#countInteger

Number of specs queued for processing across all decisions.

Returns:

  • (Integer)


73
# File 'lib/online_migrations/data_migrations/cleanup_redundant_electrical_specs.rb', line 73

def count = decisions.size

#process(specs) ⇒ void

This method returns an undefined value.

Processes one batch — looks up each spec's pre-computed decision
and acts.

Parameters:



67
68
69
# File 'lib/online_migrations/data_migrations/cleanup_redundant_electrical_specs.rb', line 67

def process(specs)
  specs.find_each { |spec| process_one(spec) }
end