using System.ComponentModel.DataAnnotations; namespace JobsMedical.Web.Models; /// /// Staging area for shift listings aggregated from Telegram / Bale / Divar channels. /// An admin reviews and normalizes these into real records. /// This is how we beat the cold-start problem. /// public class RawListing { public int Id { get; set; } [MaxLength(200)] public string SourceChannel { get; set; } = ""; // نام کانال/منبع [Required] public string RawText { get; set; } = ""; // متن خام آگهی public string? ParsedJson { get; set; } // نتیجه‌ی تجزیه‌ی خودکار (در صورت وجود) public RawListingStatus Status { get; set; } = RawListingStatus.New; public int? LinkedShiftId { get; set; } // شیفت ساخته‌شده از این آگهی public Shift? LinkedShift { get; set; } public int? LinkedTalentId { get; set; } // آگهی «آماده به کار» ساخته‌شده از این متن public TalentListing? LinkedTalent { get; set; } [MaxLength(500)] public string? SourceUrl { get; set; } /// Approximate coordinates harvested from the source (e.g. Divar's fuzzed map center). /// Carried through the review queue so a manual publish can still place the facility on the map. public double? Lat { get; set; } public double? Lng { get; set; } /// SHA-256 of the normalized text — used to dedupe across ingestion runs. [MaxLength(64)] public string? ContentHash { get; set; } /// Parser+validator confidence 0–100 (how complete/usable the listing looks). public int Confidence { get; set; } /// Human-readable validation findings (missing fields, spam flags, etc.). [MaxLength(1000)] public string? ValidationNotes { get; set; } public DateTime FetchedAt { get; set; } = DateTime.UtcNow; }