Ran for less than 5 seconds, finished .
# frozen_string_literal: true
# Archives TreeNodes whose Company GUID appears in the uploaded CSV.
#
# Reconciles profiles that were deleted in AgentPort during a sync-outage
# window but never archived on our side (ADO #71255). Only the `status`
# column is changed; rows with a blank Company GUID, GUIDs with no matching
# TreeNode, and already-archived nodes are skipped.
#
# Every row's outcome (archived / already_archived / not_found /
# blank_company_guid) is written to a CSV report, which is emailed to the
# operator-supplied recipients when the run completes or errors — this is the
# per-Company-GUID confirmation required by acceptance criteria #4.
#
# The CSV is expected to expose a `CompanyGUID` column (the header used in the
# customer-profile backfill report). Because `tree_nodes.company_guid` is
# unique, each GUID matches at most one TreeNode.
class Maintenance::ArchiveTreeNodesByCompanyGuidTask < MaintenanceTasks::Task
include ArrayHelper
csv_collection
attribute :emails, :string
validates :emails, presence: true, fcm_email_format: true
HEADER_COMPANY_GUID = 'CompanyGUID'
REPORT_COLUMNS = %w[company_guid result tree_node_id].freeze
REPORT_SENDER = 'Archive Tree Nodes By Company GUID'
after_start :prepare_csv_path
after_complete :send_report
after_error :send_report
def process(row)
company_guid = row.field(HEADER_COMPANY_GUID)&.strip
# A blank GUID would match a TreeNode with NULL/empty company_guid (both
# allowed by the schema) and archive an unrelated node, so skip it.
return append_report(company_guid, :blank_company_guid) if company_guid.blank?
tree_node = TreeNode.find_by_company_guid(company_guid)
return append_report(company_guid, :not_found) if tree_node.nil?
if tree_node.status == TreeNodes::Statuses::ARCHIVED
return append_report(company_guid, :already_archived, tree_node)
end
tree_node.update!(status: TreeNodes::Statuses::ARCHIVED)
append_report(company_guid, :archived, tree_node)
end
def csv_path
@csv_path ||= Rails.root.join('tmp', "archive_tree_nodes_by_company_guid_#{Time.now.to_i}.csv").to_s
end
private
def prepare_csv_path
@csv_path = Rails.root.join('tmp', "archive_tree_nodes_by_company_guid_#{Time.now.to_i}.csv").to_s
File.write(csv_path, REPORT_COLUMNS.to_csv)
end
def send_report
return unless csv_path && File.exist?(csv_path)
CsvReportMailer.send_report(
recipients: emails_array(emails),
file_path: csv_path,
report_sender: REPORT_SENDER
).deliver_now
ensure
File.delete(csv_path) if csv_path && File.exist?(csv_path)
end
def append_report(company_guid, result, tree_node = nil)
File.open(csv_path, 'a') do |file|
file.puts([company_guid, result, tree_node&.id].to_csv)
end
end
end
Processed 10 out of 10 items (100%).
Ran for less than 5 seconds, finished .
[FILTERED]
-1