Refactor resolveEventPlaceIdFromHeader in worshipController.js: Enhance location matching logic by introducing a scoring system for place names, improving accuracy in event place identification, and updating fallback mechanisms for known locations.
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s

This commit is contained in:
Torsten Schulz (local)
2026-04-29 19:24:34 +02:00
parent 9626fc90cc
commit 7835c2da1a

View File

@@ -497,22 +497,62 @@ function resolveEventPlaceIdFromHeader(eventPlaces, headerCell) {
if (!raw) return null;
const nameOnly = normalizeText(raw.split('(')[0]);
const normalized = nameOnly.toLowerCase();
const places = eventPlaces || [];
// Prefer exact name match.
const exact = (eventPlaces || []).find((p) => normalizeText(p.name).toLowerCase() === normalized);
// 1) Schnellpfad: exakter Name.
const exact = places.find((p) => normalizeText(p.name).toLowerCase() === normalized);
if (exact) return exact.id;
// Fallback: contains.
const contains = (eventPlaces || []).find((p) => normalizeText(p.name).toLowerCase().includes(normalized));
if (contains) return contains.id;
// 2) DB-basierter Score statt harter Sonderfalllisten.
const tokens = normalized
.replace(/[^a-z0-9äöüß\- ]/gi, ' ')
.split(/\s+/)
.filter((t) => t.length >= 3);
// Hardcoded fallbacks for known CSV headers.
const scorePlace = (placeName) => {
const n = normalizeText(placeName).toLowerCase();
let score = 0;
// Starker Treffer für ganze Header-Zeile im Ortsnamen.
if (n.includes(normalized)) score += 120;
// Token-Überlappung (Ortsteile etc.).
for (const t of tokens) {
if (n.includes(t)) score += 20;
}
// Für Gottesdienst-Orte: Kirche bevorzugen, Gemeinde* leicht abwerten.
if (/\bkirche\b/.test(n)) score += 40;
if (/\bevangelisch/.test(n)) score += 15;
if (/\bgemeindeb[uü]ro\b/.test(n)) score -= 25;
if (/\bgemeindehaus\b/.test(n)) score -= 20;
if (/\bgemeindezentrum\b/.test(n)) score -= 20;
return score;
};
let best = null;
let bestScore = -Infinity;
for (const place of places) {
const s = scorePlace(place.name || '');
if (s > bestScore) {
bestScore = s;
best = place;
}
}
// Mindestschwelle: verhindert Zufallstreffer ohne Ortsbezug.
if (best && bestScore >= 25) {
return best.id;
}
// 3) Kleiner, defensiver Fallback für bekannte Ortsnamen.
if (/am b[üu]gel/i.test(raw)) return 12;
if (/bonames/i.test(raw)) return 7;
if (/kalbach/i.test(raw)) return 2;
if (/nieder-eschbach/i.test(raw)) return 14;
if (/harheim/i.test(raw)) return 15;
if (/nieder-erlenbach/i.test(raw)) return 13;
if (/harheim/i.test(raw)) return 15;
if (/kalbach/i.test(raw)) return 11;
if (/bonames/i.test(raw)) return 1;
return null;
}