Phase 7: KI-JSON-Import und Backup-Export/Import

Neues Modul js/import/ mit reiner Validierungslogik
(importValidator.js: parseAndValidate(), findDuplicate()). Jeder
Ausflugsziel-Eintrag im importierten KI-JSON wird einzeln bewertet statt
alles-oder-nichts: fehlender Name/Kategorie oder ungueltige Koordinaten
fuehren zur Ablehnung, weiche Probleme (unbekannte Kategorie, unsichere
website/image-URL, ungueltige Bewertung, falscher Feldtyp) erzeugen nur
eine Warnung. sanitizeEntry() setzt sicherheitskritische Felder vor der
Uebernahme zurueck (z.B. javascript:-URLs), da normalizePlace() selbst
keine Sicherheitspruefung vornimmt. findDuplicate() erkennt
wahrscheinliche Duplikate gegen den bestehenden Datenbestand.

UI (js/ui/import.js): Modal mit zwei Tabs - KI-Ausflugsziele importieren
(Text einfuegen oder Datei hochladen, Vorschau mit
gueltig/Warnung/abgelehnt, Duplikat-Toggle, Bestaetigen) und Backup
sichern/wiederherstellen (js/import/backup.js: Export als JSON-Datei,
Wiederherstellen mit Ersetzen/Ergaenzen-Wahl). Vorschau-Rendering
ausschliesslich ueber el()/textContent, da es sich um echte, ungepruefte
Fremddaten handelt.

Damit sind alle Kernfunktionen aus anforderung.md umgesetzt.
docs/plan.md entsprechend fortgeschrieben.
This commit is contained in:
2026-07-24 12:50:05 +02:00
parent b49b8f4f47
commit 39321d680f
9 changed files with 1236 additions and 6 deletions
+12
View File
@@ -10,6 +10,7 @@
initManualLocationForm,
initFilterPanel,
initPromptGenerator,
initImport,
} = EventMap.ui;
function showFatalError(message) {
@@ -93,6 +94,15 @@
});
}
function setupImportButton() {
const button = document.getElementById('open-import-btn');
if (!button) return;
button.addEventListener('click', () => {
EventMap.ui.openImport();
});
}
async function bootstrap() {
await initStore();
initMap('map');
@@ -102,10 +112,12 @@
initForm('place-form-modal');
initManualLocationForm('manual-location-modal');
initPromptGenerator('prompt-generator-modal');
initImport('import-modal');
setupGeolocationButton();
setupManualLocationButton();
setupAddPlaceButton();
setupPromptGeneratorButton();
setupImportButton();
}
setupStatusClose();