Geocoding fallback: use the registered AI model when the table can't resolve
Where deterministic geocoding gives up (neighborhood not in the TehranGeo table), fall back to the registered AI model: the auditor now also returns approximate lat/lng for a recognized Tehran neighborhood (folded into the existing single audit call — no extra requests), and Publish uses it only after the source ad and the local table, and only when it falls inside greater Tehran (InTehran bbox guard rejects hallucinated points). Coords order: Divar point → TehranGeo → AI. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -314,6 +314,10 @@ public class IngestionService
|
||||
if (appLat is null && city.Name == "تهران"
|
||||
&& TehranGeo.Locate(district?.Name, districtName, parsed.AreaNote) is { } g)
|
||||
{ appLat = g.lat; appLng = g.lng; }
|
||||
// Last resort — the AI model's inferred coords, but ONLY when they fall inside greater Tehran
|
||||
// (rejects a hallucinated point elsewhere). Uses the registered model where the rules can't decide.
|
||||
if (appLat is null && d?.Lat is double aLat && d?.Lng is double aLng && InTehran(aLat, aLng))
|
||||
{ appLat = aLat; appLng = aLng; }
|
||||
|
||||
var kindStr = (d?.Kind ?? parsed.Kind.ToString()).ToLowerInvariant();
|
||||
|
||||
@@ -544,6 +548,9 @@ public class IngestionService
|
||||
|
||||
private static string Clamp(string s, int max) => s.Length <= max ? s : s[..max].Trim();
|
||||
|
||||
/// <summary>Greater-Tehran bounding box — rejects out-of-area (hallucinated) AI coordinates.</summary>
|
||||
private static bool InTehran(double lat, double lng) => lat is >= 35.4 and <= 35.95 && lng is >= 51.0 and <= 51.8;
|
||||
|
||||
// Gender/seniority tokens that don't belong in a role name (they go to tags / the Gender field).
|
||||
private static readonly string[] RoleModifierWords =
|
||||
{ "آقا", "خانم", "خانوم", "بانو", "مرد", "زن", "کارآموز", "کارورز", "ارشد", "مبتدی" };
|
||||
|
||||
Reference in New Issue
Block a user