Export: Executive Summary → Zusammenfassung, Deckblatt-Farben druckfähig

- Alle sichtbaren "Executive Summary"-Bezeichnungen durch "Zusammenfassung" ersetzt
  (PDF/DOCX-Überschrift, Dateiname, Fallback-Texte)
- Deckblatt-Farben von #888/#aaa auf Navy #0a1832 geändert für
  bessere Lesbarkeit beim Druck (PDF-Template + DOCX)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-04-12 00:42:55 +00:00
Ursprung 4358020c83
Commit 96463824a7
3 geänderte Dateien mit 12 neuen und 12 gelöschten Zeilen

Datei anzeigen

@@ -224,7 +224,7 @@ def _extract_zusammenfassung(summary_text: str) -> tuple[str, str]:
async def generate_executive_summary(summary_text: str) -> str: async def generate_executive_summary(summary_text: str) -> str:
"""KI-verdichtetes Executive Summary aus dem Lagebild.""" """KI-verdichtetes Executive Summary aus dem Lagebild."""
if not summary_text or len(summary_text.strip()) < 50: if not summary_text or len(summary_text.strip()) < 50:
return "<ul><li>Kein Lagebild verfügbar. Executive Summary kann nicht erstellt werden.</li></ul>" return "<ul><li>Kein Lagebild verfügbar. Zusammenfassung kann nicht erstellt werden.</li></ul>"
from agents.claude_client import call_claude from agents.claude_client import call_claude
@@ -290,7 +290,7 @@ LAGEBILD:
return html return html
except Exception as e: except Exception as e:
logger.error(f"Executive Summary Generierung fehlgeschlagen: {e}") logger.error(f"Executive Summary Generierung fehlgeschlagen: {e}")
return "<ul><li>Executive Summary konnte nicht generiert werden.</li></ul>" return "<ul><li>Zusammenfassung konnte nicht generiert werden.</li></ul>"
async def generate_pdf( async def generate_pdf(
@@ -312,7 +312,7 @@ async def generate_pdf(
is_research = incident.get("type") == "research" is_research = incident.get("type") == "research"
zusammenfassung_html = executive_summary_html zusammenfassung_html = executive_summary_html
bericht_summary = incident.get("summary", "") bericht_summary = incident.get("summary", "")
zusammenfassung_title = "Executive Summary" zusammenfassung_title = "Zusammenfassung"
if is_research and bericht_summary: if is_research and bericht_summary:
extracted_html, remaining = _extract_zusammenfassung(bericht_summary) extracted_html, remaining = _extract_zusammenfassung(bericht_summary)
@@ -382,7 +382,7 @@ async def generate_docx(
is_research = incident.get("type") == "research" is_research = incident.get("type") == "research"
zusammenfassung_text = executive_summary_text zusammenfassung_text = executive_summary_text
bericht_summary = incident.get("summary") or "Keine Zusammenfassung verfuegbar." bericht_summary = incident.get("summary") or "Keine Zusammenfassung verfuegbar."
zusammenfassung_title = "Executive Summary" zusammenfassung_title = "Zusammenfassung"
if is_research and bericht_summary: if is_research and bericht_summary:
extracted_html, remaining = _extract_zusammenfassung(bericht_summary) extracted_html, remaining = _extract_zusammenfassung(bericht_summary)
@@ -404,7 +404,7 @@ async def generate_docx(
title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = title_para.add_run("AegisSight Monitor") run = title_para.add_run("AegisSight Monitor")
run.font.size = Pt(12) run.font.size = Pt(12)
run.font.color.rgb = RGBColor(0x88, 0x88, 0x88) run.font.color.rgb = RGBColor(0x0a, 0x18, 0x32)
doc.add_paragraph() doc.add_paragraph()
@@ -413,7 +413,7 @@ async def generate_docx(
type_para.alignment = WD_ALIGN_PARAGRAPH.CENTER type_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = type_para.add_run(type_label) run = type_para.add_run(type_label)
run.font.size = Pt(10) run.font.size = Pt(10)
run.font.color.rgb = RGBColor(0x88, 0x88, 0x88) run.font.color.rgb = RGBColor(0x0a, 0x18, 0x32)
title_para2 = doc.add_paragraph() title_para2 = doc.add_paragraph()
title_para2.alignment = WD_ALIGN_PARAGRAPH.CENTER title_para2.alignment = WD_ALIGN_PARAGRAPH.CENTER
@@ -438,7 +438,7 @@ async def generate_docx(
meta_para.alignment = WD_ALIGN_PARAGRAPH.CENTER meta_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = meta_para.add_run(f"Stand: {now.strftime('%d.%m.%Y, %H:%M Uhr')}\nErstellt von: {creator}") run = meta_para.add_run(f"Stand: {now.strftime('%d.%m.%Y, %H:%M Uhr')}\nErstellt von: {creator}")
run.font.size = Pt(9) run.font.size = Pt(9)
run.font.color.rgb = RGBColor(0x88, 0x88, 0x88) run.font.color.rgb = RGBColor(0x0a, 0x18, 0x32)
doc.add_page_break() doc.add_page_break()

Datei anzeigen

@@ -12,10 +12,10 @@ body { font-family: -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-se
.cover-logo { width: 80px; height: auto; margin-bottom: 30px; } .cover-logo { width: 80px; height: auto; margin-bottom: 30px; }
.cover-title { font-size: 26pt; font-weight: 700; color: #0a1832; margin-bottom: 8px; } .cover-title { font-size: 26pt; font-weight: 700; color: #0a1832; margin-bottom: 8px; }
.cover-subtitle { font-size: 12pt; color: #666; margin-bottom: 40px; } .cover-subtitle { font-size: 12pt; color: #666; margin-bottom: 40px; }
.cover-type { font-size: 10pt; color: #888; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 6px; } .cover-type { font-size: 10pt; color: #0a1832; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 6px; }
.cover-meta { font-size: 9pt; color: #888; margin-top: 40px; } .cover-meta { font-size: 9pt; color: #0a1832; margin-top: 40px; }
.cover-meta div { margin-bottom: 3px; } .cover-meta div { margin-bottom: 3px; }
.cover-brand { font-size: 9pt; color: #aaa; margin-top: 50px; letter-spacing: 1px; } .cover-brand { font-size: 9pt; color: #0a1832; margin-top: 50px; letter-spacing: 1px; }
/* Classification Banner */ /* Classification Banner */

Datei anzeigen

@@ -773,11 +773,11 @@ async def export_incident(
date_str = datetime.now(TIMEZONE).strftime("%Y%m%d") date_str = datetime.now(TIMEZONE).strftime("%Y%m%d")
slug = _slugify(incident["title"]) slug = _slugify(incident["title"])
scope_labels = {"summary": "executive_summary", "report": "lagebericht", "full": "vollstaendig"} scope_labels = {"summary": "zusammenfassung", "report": "lagebericht", "full": "vollstaendig"}
# Wenn sections explizit angegeben, passenden Label waehlen # Wenn sections explizit angegeben, passenden Label waehlen
if sections_set: if sections_set:
if sections_set == {"zusammenfassung"}: if sections_set == {"zusammenfassung"}:
scope_labels_key = "executive_summary" scope_labels_key = "zusammenfassung"
elif "timeline" in sections_set: elif "timeline" in sections_set:
scope_labels_key = "vollstaendig" scope_labels_key = "vollstaendig"
else: else: