feat(emails): zweisprachige E-Mail-Templates + Notification-Texte org-relativ
- email_utils/templates.magic_link_login_email + incident_notification_email nehmen jetzt lang Parameter (de | en). - routers/auth.request_magic_link zieht Sprache aus der Org des Users und uebergibt sie ans Template. - agents/orchestrator._send_email_notifications_for_incident lokalisiert ebenfalls und gibt lang an incident_notification_email durch. - DB-Notification-Texte (refresh_summary, new_articles) sind in der Pipeline org-sprach-relativ (englische Variante: "3 new articles", etc.). Status-Change-Notifications: Codes (confirmed/contradicted) bleiben, FE uebersetzt sie in Phase 6. Phase 5 von 8 (eng_demo / Org-Sprache).
Dieser Commit ist enthalten in:
@@ -341,6 +341,10 @@ async def _send_email_notifications_for_incident(
|
||||
from email_utils.sender import send_email
|
||||
from email_utils.templates import incident_notification_email
|
||||
from config import MAGIC_LINK_BASE_URL
|
||||
from services.org_settings import get_org_language
|
||||
|
||||
# Sprache der Org bestimmen (die Lage gehoert genau einer Org)
|
||||
org_lang_iso = await get_org_language(db, tenant_id) if tenant_id else "de"
|
||||
|
||||
# Alle Nutzer mit aktiven Abos fuer diese Lage laden
|
||||
cursor = await db.execute(
|
||||
@@ -386,6 +390,7 @@ async def _send_email_notifications_for_incident(
|
||||
notifications=filtered_notifications,
|
||||
dashboard_url=dashboard_url,
|
||||
incident_type=incident_type,
|
||||
lang=org_lang_iso,
|
||||
)
|
||||
try:
|
||||
await send_email(prefs["email"], subject, html)
|
||||
@@ -1753,27 +1758,41 @@ class AgentOrchestrator:
|
||||
},
|
||||
}, visibility, created_by, tenant_id)
|
||||
|
||||
# DB-Notifications erzeugen
|
||||
# DB-Notifications erzeugen (Texte org-sprach-relativ)
|
||||
is_en = output_language_iso == "en"
|
||||
parts = []
|
||||
if new_count > 0:
|
||||
parts.append(f"{new_count} neue Meldung{'en' if new_count != 1 else ''}")
|
||||
if confirmed_count > 0:
|
||||
parts.append(f"{confirmed_count} bestätigt")
|
||||
if contradicted_count > 0:
|
||||
parts.append(f"{contradicted_count} widersprochen")
|
||||
summary_text = ", ".join(parts) if parts else "Keine neuen Entwicklungen"
|
||||
if is_en:
|
||||
if new_count > 0:
|
||||
parts.append(f"{new_count} new article{'s' if new_count != 1 else ''}")
|
||||
if confirmed_count > 0:
|
||||
parts.append(f"{confirmed_count} confirmed")
|
||||
if contradicted_count > 0:
|
||||
parts.append(f"{contradicted_count} contradicted")
|
||||
summary_text = ", ".join(parts) if parts else "No new developments"
|
||||
research_prefix = "Research"
|
||||
new_articles_msg = f"{new_count} new article{'s' if new_count != 1 else ''} found"
|
||||
else:
|
||||
if new_count > 0:
|
||||
parts.append(f"{new_count} neue Meldung{'en' if new_count != 1 else ''}")
|
||||
if confirmed_count > 0:
|
||||
parts.append(f"{confirmed_count} bestätigt")
|
||||
if contradicted_count > 0:
|
||||
parts.append(f"{contradicted_count} widersprochen")
|
||||
summary_text = ", ".join(parts) if parts else "Keine neuen Entwicklungen"
|
||||
research_prefix = "Recherche"
|
||||
new_articles_msg = f"{new_count} neue Meldung{'en' if new_count != 1 else ''} gefunden"
|
||||
|
||||
db_notifications = [{
|
||||
"type": "refresh_summary",
|
||||
"title": title,
|
||||
"text": f"Recherche: {summary_text}",
|
||||
"text": f"{research_prefix}: {summary_text}",
|
||||
"icon": "warning" if contradicted_count > 0 else "success",
|
||||
}]
|
||||
if new_count > 0:
|
||||
db_notifications.append({
|
||||
"type": "new_articles",
|
||||
"title": title,
|
||||
"text": f"{new_count} neue Meldung{'en' if new_count != 1 else ''} gefunden",
|
||||
"text": new_articles_msg,
|
||||
"icon": "info",
|
||||
})
|
||||
for sc in status_changes:
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren