From 4e60430b737df46bbc81e117afc68e83159542e3 Mon Sep 17 00:00:00 2001 From: vickytechkey Date: Fri, 16 Oct 2026 13:41:43 +0530 Subject: [PATCH] feat: add document verification API views and core settings configurations --- verifier/views.py | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/verifier/views.py b/verifier/views.py index 95ed322..ffafbb5 100644 --- a/verifier/views.py +++ b/verifier/views.py @@ -41,45 +41,20 @@ def compare_names(name1: str, name2: str) -> dict: if norm1 == norm2: return {"matched": True, "score": 100.0, "reason": "Exact name match"} + # Strict 100% match requirement: names must match 100% + # If spaces/delimiters differ, e.g. "VIGNESHKRISHNASAMY" vs "VIGNESH KRISHNASAMY" + if "".join(norm1.split()) == "".join(norm2.split()): + return {"matched": True, "score": 100.0, "reason": "Exact name match (case & whitespace insensitive)"} + + # Any non-100% similarity is rejected as name mismatch words1, words2 = norm1.split(), norm2.split() - # Reject complete first name mismatch (e.g. PRIYA SHARMA vs ROHIT SHARMA) - if len(words1) >= 2 and len(words2) >= 2: - if words1[0] != words2[0] and words1[-1] != words2[0] and words1[0] != words2[-1]: - if len(words1[0]) >= 3 and len(words2[0]) >= 3: - fn_sim = SequenceMatcher(None, words1[0], words2[0]).ratio() - if fn_sim < 0.65: - return { - "matched": False, - "score": round(fn_sim * 100, 1), - "reason": f"First name mismatch ('{words1[0]}' vs '{words2[0]}')", - } - - set1, set2 = set(words1), set(words2) - if set1 == set2: - return {"matched": True, "score": 98.0, "reason": "Permuted words match"} - - common = set1.intersection(set2) - if len(common) == min(len(set1), len(set2)): - return {"matched": True, "score": 95.0, "reason": "Subset token match"} - - # Initial check (e.g. 'RAHUL K' vs 'RAHUL KUMAR' or 'V SANKAR' vs 'VIGNESH SANKAR') - if len(words1) == len(words2): - initial_match = True - for w1, w2 in zip(words1, words2): - if w1 != w2 and not (len(w1) == 1 and w2.startswith(w1)) and not (len(w2) == 1 and w1.startswith(w2)): - initial_match = False - break - if initial_match: - return {"matched": True, "score": 92.0, "reason": "Initials abbreviation match"} - sort_ratio = SequenceMatcher(None, " ".join(sorted(words1)), " ".join(sorted(words2))).ratio() * 100 seq_ratio = SequenceMatcher(None, norm1, norm2).ratio() * 100 - best_score = max(sort_ratio, seq_ratio) - matched = best_score >= 80.0 + sim_score = round(max(sort_ratio, seq_ratio), 1) return { - "matched": matched, - "score": round(best_score, 1), - "reason": "Fuzzy token match" if matched else "Name similarity score below 80% threshold", + "matched": False, + "score": sim_score, + "reason": f"Name match score is {sim_score}%. Strict 100% match is required.", }