Add «آماده به کار» (talent) listing type — workers offering themselves
Adds a third listing kind alongside Shift/Job for healthcare staff who advertise their own availability (very common in Iranian medical channels, e.g. "دندانپزشک آماده همکاری… ۵۰٪ تسویه"). These have no facility; the contact phone is the key field. - Model: TalentListing (role, person name, years, licensed, city/district, area note, availability, gender, comp, phone) + ListingKind.Talent + RawListing.LinkedTalentId + DbSet/relations/indexes + EF migration. - Parser: detect آمادهبهکار/جویای کار → Kind=Talent; extract person name, years of experience, licensed flag, area («منطقه ۱»), phone. Facility name extraction now skipped for talent. - Validator: talent path scores role + phone + medical (no facility/pay required). - Ingestion auto-publish: creates a TalentListing for talent kind. - Review (manual publish): Talent option + talent fields; publishes a TalentListing without a facility. Shift/Job facility now falls back to a shared «نامشخص / ثبت نشده» record when the ad names none — publishing never fails on a missing facility. - Browse /Talent (indexable, filters: city/district/role/gender), details /Talent/Details (noindex — personal contact, tel: call button), _TalentCard, badge-talent, nav link, home section. - Sitemap includes /Talent; robots disallows /Talent/Details. Archiver expires stale talent listings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,23 @@ public class ListingValidator
|
||||
bool looksMedical = MedicalMarkers.Any(text.Contains);
|
||||
if (!looksMedical) issues.Add("نشانهای از حوزه درمان یافت نشد");
|
||||
|
||||
// «آماده به کار»: a worker offering themselves. No facility/shift-date expected; the role
|
||||
// and a contact number are what matter.
|
||||
if (parsed.Kind == ListingKind.Talent)
|
||||
{
|
||||
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.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;
|
||||
return new ValidationResult(tValid, isSpam, ts, issues);
|
||||
}
|
||||
|
||||
int score = 0;
|
||||
if (parsed.RoleName is not null) score += 30; else issues.Add("نقش مشخص نیست");
|
||||
if (parsed.CityName is not null || parsed.DistrictName is not null) score += 20;
|
||||
|
||||
Reference in New Issue
Block a user