Export: Zusammenfassung-Sektion, Checkbox-Auswahl, neue Reihenfolge
Research-Briefings: - Neue Sektion ZUSAMMENFASSUNG mit Bullet-Points als erstes Element - UEBERBLICK entfernt, durch ZUSAMMENFASSUNG ersetzt - Inkrementelles Briefing ebenfalls angepasst Export-System: - Zusammenfassung wird direkt aus dem Bericht extrahiert (kein separater KI-Aufruf mehr fuer Research-Lagen) - Reihenfolge: Zusammenfassung > Recherchebericht > Faktencheck > Quellen > Timeline - Sections-basiert statt scope-basiert (rueckwaertskompatibel) - Checkbox-Dialog statt Radio-Buttons im Frontend - Bereiche: Zusammenfassung, Recherchebericht, Faktencheck, Quellen, Timeline, Karte - PDF und DOCX Templates angepasst - Backend akzeptiert sections-Parameter (kommagetrennt)
Dieser Commit ist enthalten in:
@@ -713,12 +713,21 @@ async def export_incident(
|
||||
incident_id: int,
|
||||
format: str = Query("pdf", pattern="^(pdf|docx)$"),
|
||||
scope: str = Query("report", pattern="^(summary|report|full)$"),
|
||||
sections: str = Query(None),
|
||||
current_user: dict = Depends(get_current_user),
|
||||
db: aiosqlite.Connection = Depends(db_dependency),
|
||||
):
|
||||
"""Lage als PDF oder Word exportieren."""
|
||||
from report_generator import generate_pdf, generate_docx, generate_executive_summary
|
||||
|
||||
# Sections aus Komma-getrenntem String parsen
|
||||
VALID_SECTIONS = {"zusammenfassung", "bericht", "faktencheck", "quellen", "timeline", "karte"}
|
||||
sections_set = None
|
||||
if sections:
|
||||
sections_set = {s.strip() for s in sections.split(",") if s.strip() in VALID_SECTIONS}
|
||||
if not sections_set:
|
||||
sections_set = None
|
||||
|
||||
tenant_id = current_user.get("tenant_id")
|
||||
row = await _check_incident_access(db, incident_id, current_user["id"], tenant_id)
|
||||
incident = dict(row)
|
||||
@@ -765,18 +774,28 @@ async def export_incident(
|
||||
date_str = datetime.now(TIMEZONE).strftime("%Y%m%d")
|
||||
slug = _slugify(incident["title"])
|
||||
scope_labels = {"summary": "executive_summary", "report": "lagebericht", "full": "vollstaendig"}
|
||||
# Wenn sections explizit angegeben, passenden Label waehlen
|
||||
if sections_set:
|
||||
if sections_set == {"zusammenfassung"}:
|
||||
scope_labels_key = "executive_summary"
|
||||
elif "timeline" in sections_set:
|
||||
scope_labels_key = "vollstaendig"
|
||||
else:
|
||||
scope_labels_key = "lagebericht"
|
||||
else:
|
||||
scope_labels_key = scope_labels.get(scope, "lagebericht")
|
||||
|
||||
if format == "pdf":
|
||||
pdf_bytes = await generate_pdf(incident, articles, fact_checks, snapshots, scope, creator, exec_summary)
|
||||
filename = f"{slug}_{scope_labels[scope]}_{date_str}.pdf"
|
||||
pdf_bytes = await generate_pdf(incident, articles, fact_checks, snapshots, scope, creator, exec_summary, sections=sections_set)
|
||||
filename = f"{slug}_{scope_labels_key}_{date_str}.pdf"
|
||||
return StreamingResponse(
|
||||
io.BytesIO(pdf_bytes),
|
||||
media_type="application/pdf",
|
||||
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
|
||||
)
|
||||
else:
|
||||
docx_bytes = await generate_docx(incident, articles, fact_checks, snapshots, scope, creator, exec_summary)
|
||||
filename = f"{slug}_{scope_labels[scope]}_{date_str}.docx"
|
||||
docx_bytes = await generate_docx(incident, articles, fact_checks, snapshots, scope, creator, exec_summary, sections=sections_set)
|
||||
filename = f"{slug}_{scope_labels_key}_{date_str}.docx"
|
||||
return StreamingResponse(
|
||||
io.BytesIO(docx_bytes),
|
||||
media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren