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
All checks were successful
Deploy miriamgemeinde / deploy (push) Successful in 6s
This commit is contained in:
@@ -497,22 +497,62 @@ function resolveEventPlaceIdFromHeader(eventPlaces, headerCell) {
|
|||||||
if (!raw) return null;
|
if (!raw) return null;
|
||||||
const nameOnly = normalizeText(raw.split('(')[0]);
|
const nameOnly = normalizeText(raw.split('(')[0]);
|
||||||
const normalized = nameOnly.toLowerCase();
|
const normalized = nameOnly.toLowerCase();
|
||||||
|
const places = eventPlaces || [];
|
||||||
|
|
||||||
// Prefer exact name match.
|
// 1) Schnellpfad: exakter Name.
|
||||||
const exact = (eventPlaces || []).find((p) => normalizeText(p.name).toLowerCase() === normalized);
|
const exact = places.find((p) => normalizeText(p.name).toLowerCase() === normalized);
|
||||||
if (exact) return exact.id;
|
if (exact) return exact.id;
|
||||||
|
|
||||||
// Fallback: contains.
|
// 2) DB-basierter Score statt harter Sonderfalllisten.
|
||||||
const contains = (eventPlaces || []).find((p) => normalizeText(p.name).toLowerCase().includes(normalized));
|
const tokens = normalized
|
||||||
if (contains) return contains.id;
|
.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 (/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 (/nieder-eschbach/i.test(raw)) return 14;
|
||||||
if (/harheim/i.test(raw)) return 15;
|
|
||||||
if (/nieder-erlenbach/i.test(raw)) return 13;
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user