From 8ce0b3e3e8f967adfab399d162d2233618d25bec Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Mon, 1 Jun 2026 22:00:14 +0330 Subject: [PATCH] =?UTF-8?q?feat(discover):=20seed=20showcase=20caf=C3=A9?= =?UTF-8?q?=20coordinates=20so=20the=20map=20shows=20blinking=20lights?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Showcase cafés (dev/staging only) now get Latitude/Longitude scattered around their real city (Tehran/Karaj) with a deterministic per-id offset, so the homepage Iran map renders a realistic cluster of blinking merchant lights. Backfills existing rows where coords are null. Production cafés get coordinates when owners set their location in dashboard Settings. Co-Authored-By: Claude Opus 4.8 --- .../Data/DiscoverShowcaseSeeder.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/Meezi.Infrastructure/Data/DiscoverShowcaseSeeder.cs b/src/Meezi.Infrastructure/Data/DiscoverShowcaseSeeder.cs index 2a413e9..51a4de1 100644 --- a/src/Meezi.Infrastructure/Data/DiscoverShowcaseSeeder.cs +++ b/src/Meezi.Infrastructure/Data/DiscoverShowcaseSeeder.cs @@ -11,6 +11,28 @@ namespace Meezi.Infrastructure.Data; /// Seeds 30 Persian showcase cafés for public discover (development only). public static class DiscoverShowcaseSeeder { + // Approximate city centres. Each café is scattered around its city with a + // small deterministic offset (derived from its id) so the marketing map + // shows a realistic cluster of blinking lights instead of one stacked dot. + private static readonly Dictionary CityGeo = new() + { + ["تهران"] = (35.70, 51.39, 0.13), + ["کرج"] = (35.83, 50.99, 0.07), + }; + + private static (double Lat, double Lng) GeoFor(string id, string city) + { + var (lat, lng, spread) = CityGeo.TryGetValue(city, out var g) ? g : (35.70, 51.39, 0.13); + unchecked + { + var h = 17; + foreach (var ch in id) h = (h * 31) + ch; + var ox = (((h & 0xFFFF) / 65535.0) - 0.5) * 2 * spread; + var oy = ((((h >> 16) & 0xFFFF) / 65535.0) - 0.5) * 2 * spread; + return (Math.Round(lat + oy, 5), Math.Round(lng + ox, 5)); + } + } + private static readonly string[] ReviewAuthors = ["سارا", "علی", "مینا", "رضا", "نازنین"]; private static readonly string[] ReviewComments = [ @@ -27,6 +49,7 @@ public static class DiscoverShowcaseSeeder foreach (var spec in DiscoverShowcaseCatalog.Cafes) { var cafe = await db.Cafes.FirstOrDefaultAsync(c => c.Id == spec.Id); + var (geoLat, geoLng) = GeoFor(spec.Id, spec.City); if (cafe is null) { cafe = new Cafe @@ -37,6 +60,8 @@ public static class DiscoverShowcaseSeeder Slug = spec.Slug, City = spec.City, Address = spec.Address, + Latitude = geoLat, + Longitude = geoLng, Description = spec.Description, PlanTier = spec.PlanTier, PreferredLanguage = "fa", @@ -100,6 +125,12 @@ public static class DiscoverShowcaseSeeder cafe.IsVerified = true; changed = true; } + if (cafe.Latitude is null || cafe.Longitude is null) + { + cafe.Latitude = geoLat; + cafe.Longitude = geoLng; + changed = true; + } if (changed) await db.SaveChangesAsync(); }