Talent lifecycle (21-day expiry) + noindex expired job/shift details
CI/CD / CI · dotnet build (push) Successful in 2m24s
CI/CD / Deploy · hamkadr (push) Successful in 2m47s

- Talent «آماده به کار» now has its own freshness window (21 days, vs 30
  for jobs) since availability goes stale fast; archiver, browse, and home
  use TalentCutoffUtc.
- Expired/filled job openings and past/filled shifts now emit
  robots noindex so Google drops dead listings instead of keeping
  soft-404 pages. (Talent details were already noindex.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-08 08:59:54 +03:30
parent f9d7c48d88
commit 490821a637
5 changed files with 13 additions and 3 deletions
+1 -1
View File
@@ -60,7 +60,7 @@ public class IndexModel : PageModel
LatestTalent = await _db.TalentListings
.Include(t => t.City).Include(t => t.District).Include(t => t.Role)
.Where(t => t.Status == ShiftStatus.Open
&& t.CreatedAt >= JobsMedical.Web.Services.Scraping.ListingPolicy.JobCutoffUtc)
&& t.CreatedAt >= JobsMedical.Web.Services.Scraping.ListingPolicy.TalentCutoffUtc)
.OrderByDescending(t => t.CreatedAt)
.Take(3)
.ToListAsync();
@@ -5,6 +5,8 @@
var f = j.Facility!;
ViewData["Title"] = j.Title;
ViewData["Description"] = $"{j.Title} در {f.Name}، {f.City?.Name}. موقعیت استخدامی برای {j.Role?.Name}.";
// Don't let Google index filled/expired openings (avoids dead "Job for jobs" results).
if (j.Status != JobsMedical.Web.Models.ShiftStatus.Open) ViewData["NoIndex"] = true;
string empLabel = j.EmploymentType switch
{
EmploymentType.FullTime => "تمام‌وقت",
@@ -5,6 +5,9 @@
var f = s.Facility!;
ViewData["Title"] = $"شیفت {s.SpecialtyRequired} - {f.Name}";
ViewData["Description"] = $"شیفت {s.SpecialtyRequired} در {f.Name}، {f.City?.Name}، تاریخ {JalaliDate.ToLongDate(s.Date)} از ساعت {JalaliDate.Time(s.StartTime)}.";
// Past/filled shifts shouldn't stay in the index as dead pages.
if (s.Status != JobsMedical.Web.Models.ShiftStatus.Open || s.Date < DateOnly.FromDateTime(DateTime.UtcNow))
ViewData["NoIndex"] = true;
var (badgeClass, typeLabel) = s.ShiftType switch
{
ShiftType.Day => ("badge-day", "شیفت صبح"),
@@ -34,7 +34,7 @@ public class IndexModel : PageModel
.Include(t => t.City)
.Include(t => t.District)
.Include(t => t.Role)
.Where(t => t.Status == ShiftStatus.Open && t.CreatedAt >= ListingPolicy.JobCutoffUtc);
.Where(t => t.Status == ShiftStatus.Open && t.CreatedAt >= ListingPolicy.TalentCutoffUtc);
if (CityId is not null) q = q.Where(t => t.CityId == CityId);
if (DistrictId is not null) q = q.Where(t => t.DistrictId == DistrictId);