Approximate-location map on aggregated listings (Divar coords)
CI/CD / CI · dotnet build (push) Successful in 1m59s
CI/CD / Deploy · hamkadr (push) Successful in 1m49s

We captured Divar's privacy-fuzzed coords on RawListing but discarded them for
the listings that need them: unnamed-facility shifts/jobs dropped them (to avoid
piling on the shared placeholder) and applicants had no coordinate field at all.

- Add Lat/Lng to Shift, JobOpening, TalentListing (migration ListingApproxCoords).
- Publish stores the source ad's approx coords on each aggregated listing.
- Detail pages render the map from the listing's own coords (fallback: facility),
  and aggregated coords show as a shaded «محدودهٔ تقریبی» circle (not a precise
  pin) via _NeshanMap data-approx, with a disclaimer. Applicants get a map card
  (they had none) + the page now loads the Neshan key.

Only Divar provides coords; the map needs NeshanMapKey set in admin settings.
Existing rows get coords once reprocessed (RawListing already has them).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-20 15:10:05 +03:30
parent 704b68be16
commit 4ab6ce29c9
12 changed files with 1820 additions and 15 deletions
+4
View File
@@ -40,6 +40,10 @@ public class JobOpening
[MaxLength(500)]
public string? SourceUrl { get; set; }
// APPROXIMATE coords from the source ad (Divar) for aggregated openings without a facility address.
public double? Lat { get; set; }
public double? Lng { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
/// <summary>Contact channels harvested from the source ad (aggregated openings). When empty, the
+5
View File
@@ -40,6 +40,11 @@ public class Shift
[MaxLength(500)]
public string? SourceUrl { get; set; } // لینک منبع در صورت جمع‌آوری از کانال
// APPROXIMATE coords from the source ad (Divar's privacy-fuzzed center) for aggregated shifts
// whose facility has no address. Shown as a «محدودهٔ تقریبی» circle, never a precise pin.
public double? Lat { get; set; }
public double? Lng { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public ICollection<Application> Applications { get; set; } = new List<Application>();
@@ -59,6 +59,11 @@ public class TalentListing
[MaxLength(500)]
public string? SourceUrl { get; set; }
// APPROXIMATE coords from the source ad (Divar) — an applicant has no facility, so this is the
// only location we have. Shown as a «محدودهٔ تقریبی» circle (the area they're available in).
public double? Lat { get; set; }
public double? Lng { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
// Transient: distance (km) when "near me" is active. Not persisted.