diff --git a/src/JobsMedical.Web/Services/Scraping/ListingValidator.cs b/src/JobsMedical.Web/Services/Scraping/ListingValidator.cs index e720954..422d783 100644 --- a/src/JobsMedical.Web/Services/Scraping/ListingValidator.cs +++ b/src/JobsMedical.Web/Services/Scraping/ListingValidator.cs @@ -71,16 +71,19 @@ public class ListingValidator // and a contact number are what matter. if (parsed.Kind == ListingKind.Talent) { + // Phone is OPTIONAL for applicants — when it can't be extracted (e.g. Divar hides it + // behind a login-gated reveal) we still publish and the detail page links back to the + // source so users can get the number there. So role + medical alone is enough. int ts = 0; - if (parsed.RoleName is not null) ts += 35; else issues.Add("نقش/رشته مشخص نیست"); - if (parsed.Phone is not null) ts += 30; else issues.Add("شماره تماس یافت نشد"); + if (parsed.RoleName is not null) ts += 40; else issues.Add("نقش/رشته مشخص نیست"); + if (parsed.Phone is not null) ts += 25; else issues.Add("شماره تماس یافت نشد (از منبع قابل پیگیری است)"); if (parsed.CityName is not null || parsed.DistrictName is not null || parsed.AreaNote is not null) ts += 15; if (parsed.YearsExperience is not null || parsed.IsLicensed) ts += 10; if (looksMedical) ts += 10; var tlen = text.Trim().Length; if (tlen < 20) { ts -= 20; issues.Add("متن خیلی کوتاه است"); } ts = Math.Clamp(ts, 0, 100); - bool tValid = !isSpam && looksMedical && ts >= 50; + bool tValid = !isSpam && looksMedical && ts >= 50; // role(40)+medical(10) passes w/o phone return new ValidationResult(tValid, isSpam, ts, issues); }