mirror of
https://github.com/System-End/identity-vault.git
synced 2026-04-19 20:55:11 +00:00
179 lines
6.6 KiB
Ruby
179 lines
6.6 KiB
Ruby
module Backend
|
|
class VerificationsController < ApplicationController
|
|
before_action :set_verification, only: [ :show, :approve, :reject, :ignore ]
|
|
|
|
hint :list_navigation, on: [ :index, :pending ]
|
|
hint :pagination, on: [ :index, :pending ]
|
|
hint :back_navigation, on: [ :index, :pending ]
|
|
hint :verification_review, on: :show
|
|
|
|
def index
|
|
authorize Verification
|
|
|
|
set_keyboard_shortcut(:back, backend_root_path)
|
|
|
|
@recent_verifications = Verification.includes(:identity, :identity_document)
|
|
.where.not(status: "pending")
|
|
.order(updated_at: :desc)
|
|
.page(params[:page])
|
|
.per(20)
|
|
end
|
|
|
|
def pending
|
|
authorize Verification
|
|
|
|
set_keyboard_shortcut(:back, backend_root_path)
|
|
|
|
@pending_verifications = Verification.includes(:identity, :identity_document, identity_document: { files_attachments: :blob })
|
|
.where(status: "pending")
|
|
.order(created_at: :asc)
|
|
.page(params[:page])
|
|
.per(20)
|
|
@average_hangtime = @pending_verifications.average("EXTRACT(EPOCH FROM (NOW() - COALESCE(verifications.pending_at, verifications.created_at)))").to_i if @pending_verifications.any?
|
|
end
|
|
|
|
def show
|
|
authorize @verification
|
|
|
|
set_keyboard_shortcut(:back, pending_backend_verifications_path)
|
|
if @verification.pending?
|
|
set_keyboard_shortcut(:approve_ysws, approve_backend_verification_path(@verification))
|
|
set_keyboard_shortcut(:approve_not_ysws, approve_backend_verification_path(@verification))
|
|
set_keyboard_shortcut(:focus_reject, true)
|
|
end
|
|
|
|
# Fetch verification activities
|
|
verification_activities = @verification.activities.includes(:owner)
|
|
|
|
# Fetch break glass activities efficiently with a single query
|
|
break_glass_activities = []
|
|
unless @verification.is_a?(Verification::VouchVerification)
|
|
@relevant_object = @verification.identity_document || @verification.aadhaar_record
|
|
break_glass_record_ids = @relevant_object&.break_glass_records&.pluck(:id) || []
|
|
break_glass_activities = PublicActivity::Activity
|
|
.where(trackable_type: "BreakGlassRecord", trackable_id: break_glass_record_ids)
|
|
.includes(:trackable, :owner)
|
|
end
|
|
@activities = (verification_activities + break_glass_activities).sort_by(&:created_at).reverse
|
|
end
|
|
|
|
def approve
|
|
authorize @verification, :approve?
|
|
|
|
@verification.approve!
|
|
|
|
# Set YSWS eligibility if provided
|
|
if params[:ysws_eligible].present?
|
|
ysws_eligible = params[:ysws_eligible] == "true"
|
|
@verification.identity.update!(ysws_eligible: ysws_eligible)
|
|
|
|
# Send appropriate mailer based on YSWS eligibility and adult program status
|
|
if ysws_eligible || @verification.identity.came_in_through_adult_program
|
|
VerificationMailer.approved(@verification).deliver_now
|
|
else
|
|
IdentityMailer.approved_but_ysws_ineligible(@verification.identity).deliver_now
|
|
Slack::NotifyGuardiansJob.perform_later(@verification.identity)
|
|
end
|
|
|
|
eligibility_text = ysws_eligible ? "YSWS eligible" : "YSWS ineligible"
|
|
flash[:success] = "Document approved and marked as #{eligibility_text}!"
|
|
else
|
|
VerificationMailer.approved(@verification).deliver_now
|
|
flash[:success] = "Document approved successfully!"
|
|
end
|
|
|
|
@verification.create_activity(key: "verification.approve", owner: current_user, recipient: @verification.identity, parameters: { ysws_eligible: ysws_eligible })
|
|
|
|
# Auto-promote on verification approval for scenarios that opt in.
|
|
begin
|
|
ident = @verification.identity
|
|
if ident.present? && ident.slack_id.present? && ident.promote_click_count == 0
|
|
scenario = ident.onboarding_scenario_instance
|
|
if scenario&.promote_on_verification
|
|
RalseiEngine.promote_on_verification(ident)
|
|
Rails.logger.info "Auto-promoted identity #{ident.id} on verification #{@verification.id}"
|
|
end
|
|
end
|
|
rescue => e
|
|
Rails.logger.error "Auto-promote on verification approval failed: #{e.message}"
|
|
Sentry.capture_exception(e) if defined?(Sentry)
|
|
end
|
|
|
|
redirect_to pending_backend_verifications_path
|
|
end
|
|
|
|
def reject
|
|
authorize @verification, :reject?
|
|
|
|
reason = params[:rejection_reason]
|
|
details = params[:rejection_reason_details]
|
|
internal_comment = params[:internal_rejection_comment]
|
|
|
|
if reason.blank?
|
|
flash[:error] = "Rejection reason is required"
|
|
redirect_to backend_verification_path(@verification)
|
|
return
|
|
end
|
|
|
|
@verification.mark_as_rejected!(reason, details)
|
|
@verification.internal_rejection_comment = internal_comment if internal_comment.present?
|
|
@verification.save!
|
|
|
|
@verification.create_activity(key: "verification.reject", owner: current_user, recipient: @verification.identity, parameters: { reason: reason, details: details, internal_comment: internal_comment })
|
|
|
|
flash[:success] = "Document rejected with feedback"
|
|
redirect_to pending_backend_verifications_path
|
|
end
|
|
|
|
def ignore
|
|
authorize @verification, :ignore?
|
|
|
|
if params[:reason].blank?
|
|
flash[:alert] = "Reason is required to ignore verification"
|
|
redirect_to backend_verification_path(@verification) and return
|
|
end
|
|
|
|
@verification.update!(
|
|
ignored_at: Time.current,
|
|
ignored_reason: params[:reason],
|
|
)
|
|
|
|
@verification.create_activity(
|
|
:ignored,
|
|
owner: current_user,
|
|
parameters: { reason: params[:reason] },
|
|
)
|
|
|
|
flash[:notice] = "Verification ignored successfully"
|
|
redirect_to backend_identity_path(@verification.identity)
|
|
end
|
|
|
|
rescue_from AASM::InvalidTransition, with: :oops
|
|
|
|
private
|
|
|
|
def set_verification
|
|
@verification = Verification
|
|
.includes(:identity, identity_document: :break_glass_records)
|
|
.find_by_public_id!(params[:id])
|
|
|
|
ActiveRecord::Associations::Preloader.new(
|
|
records: [ @verification.identity ],
|
|
associations: { resemblances: [ :past_identity ] }
|
|
).call
|
|
|
|
doc_resemblances = @verification.identity.resemblances.select { |r| r.is_a?(Identity::Resemblance::ReusedDocumentResemblance) }
|
|
if doc_resemblances.any?
|
|
ActiveRecord::Associations::Preloader.new(
|
|
records: doc_resemblances,
|
|
associations: [ :document, { past_document: :verification } ]
|
|
).call
|
|
end
|
|
end
|
|
|
|
def oops
|
|
flash[:warning] = "This verification has already been processed?"
|
|
redirect_to pending_backend_verifications_path
|
|
end
|
|
end
|
|
end
|