Class: Admin::Privacy::DeletionRequestsController

Inherits:
CrmController show all
Defined in:
app/controllers/admin/privacy/deletion_requests_controller.rb

Overview

Controller: admin review queue for privacy deletion requests.

Constant Summary collapse

MANUAL_SOURCES =
::Privacy::DeletionRequest::SOURCES - %w[facebook_callback]

Constants included from Controllers::ReferenceFindable

Controllers::ReferenceFindable::ID_EMBEDDED_PATTERNS

Constants included from Controllers::AnalyticsEvents

Controllers::AnalyticsEvents::MAX_QUEUED_EVENTS, Controllers::AnalyticsEvents::SESSION_KEY

Constants included from Controllers::ErrorRendering

Controllers::ErrorRendering::NON_CONTENT_PATH_PREFIXES

Constants included from Www::SeoHelper

Www::SeoHelper::AWARDS, Www::SeoHelper::CA_ADDRESS, Www::SeoHelper::CA_BUSINESS_HOURS, Www::SeoHelper::CA_CONTACT_POINT, Www::SeoHelper::CA_CURRENCIES, Www::SeoHelper::CA_DESCRIPTION, Www::SeoHelper::CA_FOUNDING_DATE, Www::SeoHelper::CA_GLOBAL_LOCATION_NUMBER, Www::SeoHelper::CA_LEGAL_NAME, Www::SeoHelper::CA_LOCAL_BUSINESS, Www::SeoHelper::CA_ONLINE_STORE, Www::SeoHelper::CA_RETURN_POLICY, Www::SeoHelper::CA_SALES_DEPARTMENT, Www::SeoHelper::CA_SERVICE_AREA, Www::SeoHelper::CA_URL, Www::SeoHelper::CA_VAT_ID, Www::SeoHelper::CA_WAREHOUSE_DEPARTMENT, Www::SeoHelper::CA_WAREHOUSE_HOURS, Www::SeoHelper::COMPANY_EMAIL, Www::SeoHelper::COMPANY_LOGO, Www::SeoHelper::COMPANY_NAME, Www::SeoHelper::COMPANY_SLOGAN, Www::SeoHelper::EXPERTISE, Www::SeoHelper::FAX_NUMBER, Www::SeoHelper::GS1_COMPANY_PREFIX, Www::SeoHelper::ISO6523_CODE, Www::SeoHelper::PAYMENT_METHODS, Www::SeoHelper::PHONE_NUMBER, Www::SeoHelper::PRIMARY_NAICS, Www::SeoHelper::REFUND_TYPE, Www::SeoHelper::RETURN_FEES, Www::SeoHelper::RETURN_METHOD, Www::SeoHelper::RETURN_POLICY_CATEGORY, Www::SeoHelper::SECONDARY_NAICS, Www::SeoHelper::SOCIAL_PROFILES, Www::SeoHelper::US_ADDRESS, Www::SeoHelper::US_BUSINESS_HOURS, Www::SeoHelper::US_CONTACT_POINT, Www::SeoHelper::US_CURRENCIES, Www::SeoHelper::US_DESCRIPTION, Www::SeoHelper::US_FOUNDING_DATE, Www::SeoHelper::US_GLOBAL_LOCATION_NUMBER, Www::SeoHelper::US_IMAGE, Www::SeoHelper::US_LEGAL_NAME, Www::SeoHelper::US_LOCAL_BUSINESS, Www::SeoHelper::US_ONLINE_STORE, Www::SeoHelper::US_RETURN_POLICY, Www::SeoHelper::US_SALES_DEPARTMENT, Www::SeoHelper::US_SERVICE_AREA, Www::SeoHelper::US_TAX_ID, Www::SeoHelper::US_URL, Www::SeoHelper::US_WAREHOUSE_DEPARTMENT, Www::SeoHelper::US_WAREHOUSE_HOURS

Constants included from IconHelper

IconHelper::CUSTOM_ICON_MAP, IconHelper::CUSTOM_SVG_DIR, IconHelper::DEFAULT_FAMILY

Instance Method Summary collapse

Methods inherited from CrmController

#access_denied, #context_id, #context_object, #crm_home_path, #current_ability, #default_url_options, #download_temp, #get_tempfile_path_for_download, #init_status_job_collector, #initialize_crm_lazy_chunks, #persist_enqueued_status_jobs, #record_not_found, #redirect_to_job_or_fallback, #render_edit_action, #set_context, #set_download_path, #stash_file_for_temp_download, #sync_admin_presence_cookie

Methods inherited from ApplicationController

#account_impersonated?, #add_to_flash, #after_sign_in_path_for, #bypass_forgery_protection?, #chat_enabled?, #cloudflare_cleared?, #default_catalog, #default_url_options, #enable_turbo_frames, #find_publication, #fix_invalid_accept_header, #init_js_utils, #is_globals_call?, #layout_by_resource, #locale_store, #redirect_to, #require_employee_for_crm, #set_base_host, #set_real_ip, #set_report_errors_for, #should_render_layout?, #stamp_impersonation_context, #warmlyyours_canada_ip?, #warmlyyours_ip?, #y

Methods included from Controllers::ReturnPathHandling

#check_for_return_path, #redirect_to_return_path_or_default

Methods included from Controllers::AnalyticsEvents

#consume_queued_analytics_events, #track_event

Methods included from Controllers::DeviceDetection

#device_detector, #is_ie?

Methods included from Controllers::SubdomainDetection

#is_crm_request?, #is_www_request?, #json_request?

Methods included from Controllers::TurboSafeRedirect

#redirect_to

Methods included from Controllers::TrackingDetection

#bot_request?, #gdpr_country?, #gdpr_country_data, #prevent_bots, #set_tracking_cookie, #track_visitor?

Methods included from Controllers::AcceleratedFileSending

#send_file_accelerated, #send_upload_accelerated

Methods included from Controllers::ErrorRendering

#excp_string, #mail_to_for_error_reporting, #render_400, #render_404, #render_406, #render_410, #render_500, #render_invalid_authenticity_token, #render_ip_spoof_error, #render_unpermitted_parameters, #safe_referer_or_fallback

Methods included from Controllers::TurnstileVerification

#load_turnstile_script_tag, #turnstile_lazy_widget, #turnstile_script_tag, #turnstile_widget, #validate_turnstile!

Methods included from Controllers::CloudflareCaching

edge_cached, #edge_cached_action?, #reset_cloudflare_cache, #set_cloudflare_cache, #skip_edge_cache!, #skip_session

Methods included from Controllers::Webpackable

#preload_webpack_fonts, #webpack_css_include, #webpack_css_url, #webpack_js_include, #wpd_is_running?

Methods included from Controllers::Localizable

#cloudflare_country_locale, #determine_request_locale, #geocoder_locale, #guest_user_locale_check, #locale_optional_www_auth_path?, #param_locale, #set_locale, #set_request_locale, #skip_localization?, #warmlyyours_ip_locale

Methods included from Controllers::Authenticable

#access_denied, #authenticate_account, #authenticate_account!, #authenticate_account_from_login_token!, #check_is_a_manager, #check_is_a_sales_manager, #check_is_an_admin, #check_is_an_employee, #check_party, #clear_mismatched_guest_user, #create_guest_user, #credentials?, #current_or_guest_user, #current_or_guest_user_id_read_only, #current_user, #devise_mapping, #fully_logged_in?, #generate_bot_id, #guest_user, #identifiable?, #init_current_user, #initialize_guest, #load_context_user, #logging_in, #resource, #resource_name, #restrict_access_for_non_employees, #scrubbed_request_path, #user_object, #warn_on_session_guest_id_leak

Methods included from ApplicationHelper

#better_number_to_currency, #check_force_logout, #check_or_cross, #check_or_times, #embedded_tab_frame_id, #error_messages, #general_disclaimer_on_product_installation_and_local_codes, #gridjs_from_html_table, #gridjs_table, #is_wy_ip, #line_break, #parent_layout, #pass_or_fail, #render_error_messages_list, #render_video_card, #resolved_auth_form_turbo_frame, #return_path_or, #safe_css_color, #set_return_path_if_present, #set_section_if_present, #tab_frame_id, #to_underscore, #track_page?, #turbo_section_wrapper, #turbo_tabs_request?, #url_on_same_domain_as_request, #widget_index_daily_focus_index_path, #working_hours?, #yes_or_no, #yes_or_no_highlighted, #yes_or_no_with_check_or_cross, #youtube_video

Methods included from UppyUploaderHelper

#file_uploader, #image_uploader, #large_file_uploader_s3, #lead_sketch_uploader, #rma_image_uploader, #rma_image_uploader_s3, #uppy_uploader, #video_uploader

Methods included from Www::ImagesHelper

#image_asset_tag, #image_asset_url

Methods included from Www::SeoHelper

#add_page_schema, #add_webpage_schema, #canada?, #company_social_links, #ensure_context_json, #json_ld_script_tag, #local_business_schema, #online_store_id, #online_store_schema, #page_main_entity, #page_main_entity_json, #render_auto_collection_page_schema, #render_collection_page_schema, #render_local_business_schema, #render_online_store_schema, #render_page_schemas, #render_page_video_schemas, #render_webpage_schema, #render_webpage_schema_with_collections, #usa?

Methods included from UrlsHelper

#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?

Methods included from IconHelper

#account_nav_icon, #fa_icon, #star_rating_html

Instance Method Details

#approveObject

POST /admin/privacy/deletion_requests/:id/approve — clear the Tier-3
hold and re-enqueue the worker.



91
92
93
94
95
96
97
98
# File 'app/controllers/admin/privacy/deletion_requests_controller.rb', line 91

def approve
  return redirect_back_with_error(:approve) unless @request.can_start_processing?

  @request.update!(reviewed_by: , reviewed_at: Time.current)
  ::Privacy::DataDeletionWorker.perform_async(@request.id)
  flash[:success] = "Approved request ##{@request.id}; scrub enqueued."
  redirect_to admin_privacy_deletion_request_path(@request)
end

#createObject

POST /admin/privacy/deletion_requests — create a manual request,
resolve account_id / party_id from email or account_id input,
then enqueue the worker. The same Tier-3 review gate + scrub
pipeline applies; admin doesn't need to do anything else unless a
trigger fires (in which case they get a held_for_review email).



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/controllers/admin/privacy/deletion_requests_controller.rb', line 46

def create
  @sources = MANUAL_SOURCES
  attrs    = manual_request_params

  @request = ::Privacy::DeletionRequest.new(
    source: attrs[:source].presence_in(MANUAL_SOURCES) || 'manual_email'
  )
  # Echo the virtual attrs so a re-render preserves what the admin typed.
  @request.  = attrs[:account_lookup]
  @request.contact_email   = attrs[:contact_email]
  @request.intake_notes    = attrs[:intake_notes]
  @request. = attrs[:require_account]

  if attrs[:account_lookup].blank?
    @request.errors.add(:account_lookup,
                        "can't be blank — enter an account email, login, or numeric account ID")
    render :new, status: :unprocessable_entity
    return
  end

   = (attrs[:account_lookup])
  if .nil? && attrs[:require_account] == '1'
    @request.errors.add(:account_lookup,
                        "did not match any account. Uncheck 'Require matching account' to record a no_account_found row anyway.")
    render :new, status: :unprocessable_entity
    return
  end

  @request. = 
  @request.party   = &.party
  @request.data = {
    contact_email:  attrs[:contact_email].presence,
    account_lookup: attrs[:account_lookup],
    intake_notes:   attrs[:intake_notes].presence,
    created_by:     .email
  }.compact
  @request.save!

  ::Privacy::DataDeletionWorker.perform_async(@request.id)
  flash[:success] = "Created request ##{@request.id}; worker enqueued."
  redirect_to admin_privacy_deletion_request_path(@request)
end

#declineObject

POST /admin/privacy/deletion_requests/:id/decline — terminal "no".



101
102
103
104
105
106
107
108
# File 'app/controllers/admin/privacy/deletion_requests_controller.rb', line 101

def decline
  return redirect_back_with_error(:decline) unless @request.can_decline?

  @request.update!(reviewed_by: , reviewed_at: Time.current)
  @request.decline
  flash[:success] = "Declined request ##{@request.id}."
  redirect_to admin_privacy_deletion_request_path(@request)
end

#indexObject

GET /admin/privacy/deletion_requests



23
24
25
26
# File 'app/controllers/admin/privacy/deletion_requests_controller.rb', line 23

def index
  @needs_review_requests = ::Privacy::DeletionRequest.needs_review.recent.limit(100)
  @recent_requests       = ::Privacy::DeletionRequest.recent.limit(100)
end

#newObject

GET /admin/privacy/deletion_requests/new — manual intake form for
requests that arrived by email / postal mail / in-person rather
than through Meta's webhook.



36
37
38
39
# File 'app/controllers/admin/privacy/deletion_requests_controller.rb', line 36

def new
  @request = ::Privacy::DeletionRequest.new(source: 'manual_email')
  @sources = MANUAL_SOURCES
end

#retry_requestObject

POST /admin/privacy/deletion_requests/:id/retry — failed → pending, re-enqueue.



111
112
113
114
115
116
117
118
# File 'app/controllers/admin/privacy/deletion_requests_controller.rb', line 111

def retry_request
  return redirect_back_with_error(:retry) unless @request.can_retry_processing?

  @request.retry_processing
  ::Privacy::DataDeletionWorker.perform_async(@request.id)
  flash[:success] = "Re-enqueued request ##{@request.id}."
  redirect_to admin_privacy_deletion_request_path(@request)
end

#showObject

GET /admin/privacy/deletion_requests/:id



29
30
31
# File 'app/controllers/admin/privacy/deletion_requests_controller.rb', line 29

def show
  # Renders details + actions; no extra setup needed.
end