From f512b7ea9e055e00481a2978e0c7effa0d97ae99 Mon Sep 17 00:00:00 2001 From: Maurice Date: Mon, 25 May 2026 00:59:28 +0200 Subject: [PATCH] fix(atlas): count cities when the address contains a postal code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The visited-cities counter took the comma part right before the country, which is the postal code in addresses like "Bucharest, 010071, Romania" — stripping the digits left an empty string, so the city was never counted. Walk back from the country and use the first part that still has letters after stripping the postal noise. Closes #940 --- server/src/services/atlasService.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/server/src/services/atlasService.ts b/server/src/services/atlasService.ts index 4d26a7d5..ddb1c074 100644 --- a/server/src/services/atlasService.ts +++ b/server/src/services/atlasService.ts @@ -376,11 +376,17 @@ export async function getStats(userId: number) { for (const place of places) { if (place.address) { const parts = place.address.split(',').map((s: string) => s.trim()).filter(Boolean); - let raw = parts.length >= 2 ? parts[parts.length - 2] : parts[0]; - if (raw) { - const city = raw.replace(/[\d\-\u2212\u3012]+/g, '').trim().toLowerCase(); - if (city) citySet.add(city); + // The last part is the country; the city is usually right before it, but a + // full formatted address can have a postal code sitting between them + // (e.g. "Bucharest, 010071, Romania"). Walk back from the country and take + // the first part that still has letters once digits/postal noise is stripped. + const candidates = parts.length >= 2 ? parts.slice(0, -1) : parts; + let city = ''; + for (let i = candidates.length - 1; i >= 0; i--) { + const cleaned = candidates[i].replace(/[\d\-\u2212\u3012]+/g, '').trim(); + if (cleaned) { city = cleaned.toLowerCase(); break; } } + if (city) citySet.add(city); } } const totalCities = citySet.size;