AI tag/category assignment + phone extraction from web ads
CI/CD / CI · dotnet build (push) Successful in 2m37s
CI/CD / Deploy · hamkadr (push) Successful in 1m11s

AI (when enabled, now that the server proxy is up):
- AiStructured gains phone, personName, yearsExperience, isLicensed.
- The auditor appends an authoritative output-schema to the admin prompt
  so classification stays correct even with an older stored prompt — it
  now classifies kind as shift|job|talent and extracts the contact phone
  and talent details.
- Ingestion publish prefers the AI's tags (kind/role/city/facility/phone +
  talent fields) over the heuristic parser when present.
- Default prompt updated to describe the three kinds + new fields.

Phone extraction from websites (Medjobs / generic sites), where the
number sits behind a "تماس با این آگهی" reveal:
- HtmlUtil.HarvestPhones scans the full markup for tel: links, JSON-LD
  "telephone", data-*phone* attributes, and inline Iranian mobile/landline
  numbers (Persian digits folded), normalized (mobiles 09…, landlines 0…).
- Medjobs + Website sources append harvested numbers to the ad text so the
  parser/AI capture them; manual review then prefills the phone too.
- Parser phone extraction now also captures a landline as a fallback.

Note: if a site loads the number purely via XHR (not in HTML), a
per-source reveal endpoint would be a follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-08 08:11:14 +03:30
parent 4e5df73cf7
commit 213af9db48
7 changed files with 126 additions and 20 deletions
+15 -3
View File
@@ -154,9 +154,21 @@ public class HeuristicListingParser : IListingParser
if (p.FacilityName is not null) p.Notes.Add($"مرکز: {p.FacilityName}");
}
// --- Phone ---
var phone = Regex.Match(ToLatinDigits(text), @"0?9\d{9}");
if (phone.Success) p.Phone = phone.Value;
// --- Phone (mobile preferred, landline as fallback) ---
var latinPhone = ToLatinDigits(text);
var mobile = Regex.Match(latinPhone, @"(?:\+?98|0)?9\d{9}");
if (mobile.Success)
{
var d = Regex.Replace(mobile.Value, @"\D", "");
if (d.StartsWith("98")) d = "0" + d[2..];
if (d.Length == 10 && d.StartsWith("9")) d = "0" + d;
p.Phone = d;
}
else
{
var land = Regex.Match(latinPhone, @"0\d{2,3}[\s-]?\d{7,8}");
if (land.Success) p.Phone = Regex.Replace(land.Value, @"\D", "");
}
return p;
}