fixes for resemblance checking

This commit is contained in:
24c02 2025-12-30 17:44:02 -05:00
parent 8412124bb8
commit e0dc5dd8b1
4 changed files with 61 additions and 16 deletions

View file

@ -8,8 +8,13 @@ class Components::Resemblance < Components::Base
end
def view_template
div class: "lowered" do
render @resemblance
div class: "lowered resemblance" do
div class: "section" do
div(class: "section-header") { h3 { resemblance_title } }
div class: "section-content" do
render @resemblance
end
end
div class: "section" do
div(class: "section-header") { h3 { "matched identity" } }
div class: "section-content" do
@ -19,4 +24,19 @@ class Components::Resemblance < Components::Base
render Components::Inspector.new(@resemblance)
end
end
private
def resemblance_title
case @resemblance
when Identity::Resemblance::NameResemblance
"name match"
when Identity::Resemblance::ReusedDocumentResemblance
"document reuse"
when Identity::Resemblance::EmailSubaddressResemblance
"email subaddressing"
else
"resemblance"
end
end
end

View file

@ -49,6 +49,8 @@ class Verification::DocumentVerification < Verification
belongs_to :identity_document, class_name: "Identity::Document"
after_create_commit :check_for_resemblances
# This is the main verification type for document-based verifications
# All existing verification functionality lives here
@ -143,4 +145,8 @@ class Verification::DocumentVerification < Verification
errors.add(:rejection_reason_details, "must be provided when rejection reason details is 'other'")
end
end
def check_for_resemblances
Identity::NoticeResemblancesJob.perform_later(identity)
end
end

View file

@ -2,10 +2,16 @@ module ResemblanceNoticerEngine
TACTICS = [ NameSimilarity, DuplicateDocuments, EmailSubaddressing ]
def self.run(identity)
results = TACTICS.flat_map do |tactic|
tactic.new(identity).run
TACTICS.each do |tactic|
tactic.new(identity).run.each do |resemblance|
existing = identity.resemblances.find_by(
type: resemblance.class.name,
past_identity_id: resemblance.past_identity_id,
document_id: resemblance.document_id,
past_document_id: resemblance.past_document_id
)
resemblance.save! unless existing
end
end
results.each &:save!
end
end

View file

@ -1,21 +1,34 @@
module ResemblanceNoticerEngine
class DuplicateDocuments < Base
def run
checksums = identity.documents.joins(files_attachments: :blob).pluck("active_storage_blobs.checksum")
return [] if checksums.empty?
# Build a map of checksum -> document for the current identity
checksum_to_document = {}
identity.documents.includes(files_attachments: :blob).each do |doc|
doc.files.each do |file|
checksum_to_document[file.blob.checksum] = doc
end
end
return [] if checksum_to_document.empty?
Identity::Document.joins(files_attachments: :blob)
.joins(:identity)
.where(active_storage_blobs: { checksum: checksums })
.where(active_storage_blobs: { checksum: checksum_to_document.keys })
.where.not(identity: identity)
.includes(:identity, files_attachments: :blob)
.map do |duplicate_doc|
Identity::Resemblance::ReusedDocumentResemblance.new(
identity: identity,
past_identity: duplicate_doc.identity,
document: duplicate_doc,
past_document: duplicate_doc,
)
.flat_map do |duplicate_doc|
# Find which of our documents match this duplicate
duplicate_doc.files.filter_map do |file|
our_doc = checksum_to_document[file.blob.checksum]
next unless our_doc
Identity::Resemblance::ReusedDocumentResemblance.new(
identity: identity,
past_identity: duplicate_doc.identity,
document: our_doc,
past_document: duplicate_doc,
)
end
end
end
end