mirror of
https://github.com/System-End/identity-vault.git
synced 2026-04-19 22:05:07 +00:00
only the real bad ones?
This commit is contained in:
parent
ec35dfc938
commit
421c6f2bf4
2 changed files with 28 additions and 15 deletions
|
|
@ -110,21 +110,21 @@ module Backend
|
|||
country_code = verification.identity.country
|
||||
country_name = ISO3166::Country[country_code]&.common_name || country_code
|
||||
|
||||
by_country[country_name] ||= { total: 0, reasons: {} }
|
||||
by_country[country_name] ||= { total: 0, fatal: 0, reasons: {} }
|
||||
by_country[country_name][:total] += 1
|
||||
by_country[country_name][:fatal] += 1 if verification.fatal?
|
||||
|
||||
reason_name = verification.try(:rejection_reason_name) || verification.rejection_reason.humanize
|
||||
by_country[country_name][:reasons][reason_name] ||= 0
|
||||
by_country[country_name][:reasons][reason_name] += 1
|
||||
by_country[country_name][:reasons][reason_name] ||= { count: 0, fatal: verification.fatal? }
|
||||
by_country[country_name][:reasons][reason_name][:count] += 1
|
||||
end
|
||||
|
||||
# Sort countries by total rejections, and reasons within each country by count
|
||||
# Calculate fraud rate and sort by fatal count (most suspicious first)
|
||||
by_country.transform_values do |data|
|
||||
data[:reasons] = data[:reasons].sort_by { |_, count| -count }.to_h
|
||||
data[:top_reason] = data[:reasons].first&.first
|
||||
data[:top_reason_count] = data[:reasons].first&.last || 0
|
||||
data[:reasons] = data[:reasons].sort_by { |_, r| [ r[:fatal] ? 0 : 1, -r[:count] ] }.to_h
|
||||
data[:fatal_rate] = data[:total] > 0 ? (data[:fatal].to_f / data[:total] * 100).round(1) : 0
|
||||
data
|
||||
end.sort_by { |_, data| -data[:total] }.to_h
|
||||
end.sort_by { |_, data| [ -data[:fatal], -data[:total] ] }.to_h
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -103,30 +103,43 @@
|
|||
</div>
|
||||
<hr>
|
||||
<div class="section">
|
||||
<div class="section-header"><h3>🌍 rejections by country</h3></div>
|
||||
<div class="section-content">
|
||||
<% if @rejections_by_country.any? %>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>country</th>
|
||||
<th>rejections</th>
|
||||
<th>top reason</th>
|
||||
<th>fatal</th>
|
||||
<th>total rejected</th>
|
||||
<th>fatal %</th>
|
||||
<th>breakdown</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @rejections_by_country.each do |country, data| %>
|
||||
<% next if data[:fatal] == 0 %>
|
||||
<tr>
|
||||
<td><b><%= country %></b></td>
|
||||
<td style="color: var(--color-red-50);"><b><%= data[:fatal] %></b></td>
|
||||
<td><%= data[:total] %></td>
|
||||
<td><%= data[:top_reason] %> (<%= data[:top_reason_count] %>)</td>
|
||||
<td>
|
||||
<% if data[:fatal_rate] >= 50 %>
|
||||
<span class="badge danger"><%= data[:fatal_rate] %>%</span>
|
||||
<% elsif data[:fatal_rate] >= 25 %>
|
||||
<span class="badge warning"><%= data[:fatal_rate] %>%</span>
|
||||
<% else %>
|
||||
<%= data[:fatal_rate] %>%
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<details>
|
||||
<summary>view all</summary>
|
||||
<ul style="margin: 0.5rem 0 0 1rem; padding: 0;">
|
||||
<% data[:reasons].each do |reason, count| %>
|
||||
<li><%= reason %>: <%= count %></li>
|
||||
<% data[:reasons].each do |reason, r| %>
|
||||
<li>
|
||||
<%= reason %>: <%= r[:count] %>
|
||||
<% if r[:fatal] %><span class="badge danger">fatal</span><% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</details>
|
||||
|
|
@ -136,7 +149,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<% else %>
|
||||
<div class="empty-state">no rejections</div>
|
||||
<div class="empty-state">none</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue