From f7b5703db3e8c53749d090a63e9b32bcf1cebb84 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Wed, 4 Mar 2026 22:34:06 +0100 Subject: [PATCH] Fix: Magic-Link URL, Sidebar-Ladereihenfolge, Archiv-Standard + Geoparse-Button - Magic-Link URL korrigiert: /auth/verify -> / (Login-Seite mit Token-Param) - Sidebar: loadIncidents() vor NotificationCenter.init() verschoben - NotificationCenter.init() in try/catch gewrappt - Archiv-Sektion default geschlossen (display:none im HTML) - Neuer Endpunkt POST /incidents/{id}/geoparse fuer bestehende Artikel - "Orte erkennen"-Button in Karten-Kachel Co-Authored-By: Claude Opus 4.6 --- src/routers/auth.py | 2 +- src/routers/incidents.py | 44 +++++++++++++++++++++++++++++++++++++++ src/static/dashboard.html | 15 ++++++------- src/static/js/api.js | 4 ++++ src/static/js/app.js | 35 +++++++++++++++++++++++-------- 5 files changed, 83 insertions(+), 17 deletions(-) diff --git a/src/routers/auth.py b/src/routers/auth.py index 66e81d8..9d1dee6 100644 --- a/src/routers/auth.py +++ b/src/routers/auth.py @@ -95,7 +95,7 @@ async def request_magic_link( await db.commit() # E-Mail senden - link = f"{MAGIC_LINK_BASE_URL}/auth/verify?token={token}" + link = f"{MAGIC_LINK_BASE_URL}/?token={token}" subject, html = magic_link_login_email(user["username"], code, link) await send_email(email, subject, html) diff --git a/src/routers/incidents.py b/src/routers/incidents.py index e1a17c6..52770e5 100644 --- a/src/routers/incidents.py +++ b/src/routers/incidents.py @@ -320,6 +320,50 @@ async def get_locations( return list(loc_map.values()) +@router.post("/{incident_id}/geoparse") +async def trigger_geoparse( + incident_id: int, + current_user: dict = Depends(get_current_user), + db: aiosqlite.Connection = Depends(db_dependency), +): + """Geoparsing fuer alle Artikel einer Lage nachholen (bestehende Orte werden uebersprungen).""" + tenant_id = current_user.get("tenant_id") + await _check_incident_access(db, incident_id, current_user["id"], tenant_id) + + # Artikel laden, die noch keine Locations haben + cursor = await db.execute( + """SELECT a.* FROM articles a + WHERE a.incident_id = ? + AND a.id NOT IN (SELECT DISTINCT article_id FROM article_locations WHERE incident_id = ?)""", + (incident_id, incident_id), + ) + articles = [dict(row) for row in await cursor.fetchall()] + + if not articles: + return {"message": "Alle Artikel wurden bereits geoparsed", "new_locations": 0} + + try: + from agents.geoparsing import geoparse_articles + geo_results = await geoparse_articles(articles) + geo_count = 0 + for art_id, locations in geo_results.items(): + for loc in locations: + await db.execute( + """INSERT INTO article_locations + (article_id, incident_id, location_name, location_name_normalized, + country_code, latitude, longitude, confidence, source_text, tenant_id) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", + (art_id, incident_id, loc["location_name"], loc["location_name_normalized"], + loc["country_code"], loc["lat"], loc["lon"], loc["confidence"], + loc.get("source_text", ""), tenant_id), + ) + geo_count += 1 + await db.commit() + return {"message": f"{geo_count} Orte aus {len(geo_results)} Artikeln extrahiert", "new_locations": geo_count} + except Exception as e: + raise HTTPException(status_code=500, detail=f"Geoparsing fehlgeschlagen: {str(e)}") + + @router.get("/{incident_id}/refresh-log") async def get_refresh_log( incident_id: int, diff --git a/src/static/dashboard.html b/src/static/dashboard.html index 6e17913..f37f117 100644 --- a/src/static/dashboard.html +++ b/src/static/dashboard.html @@ -16,7 +16,7 @@ - + @@ -76,7 +76,7 @@ Archiv -
+