#47 Fix: Highlighting retroaktiv für alle bestehenden Assessments
Problem: Alle Assessments in der Prod-DB haben Pre-#47-URLs
(/static/referenzen/X.pdf#page=N). Die _chunk_pdf_url-Änderung wirkt
nur auf NEUE Analysen, die noch nicht stattgefunden haben.
Fix (zwei Seiten):
1. Endpoint /api/wahlprogramm-cite akzeptiert jetzt auch pdf=<filename>
als Alternative zu pid=<programm_id>. Reverse-Lookup über PROGRAMME-
Registry: pdf-Filename → programm_id. Damit können die statischen
URLs aus Pre-#47-Assessments trotzdem an den Cite-Endpoint geleitet
werden.
2. Frontend: neue JS-Funktion makeCiteUrl(z) die JEDE Zitat-URL on-the-
fly umschreibt:
- /static/referenzen/X.pdf#page=N + z.text
→ /api/wahlprogramm-cite?pdf=X.pdf&seite=N&q=<urlencoded text>
- /api/wahlprogramm-cite?... → durchreichen (schon Cite-URL)
- Fallback: URL unverändert
Funktioniert retroaktiv für ALLE ~31 Assessments in der DB, ohne
Re-Analyse. Sobald ein User auf ein Zitat klickt, wird die Seite
des Wahlprogramms mit gelber Markierung gerendert.
Tests: 194/194 grün.
Refs: #47
This commit is contained in:
parent
2b2a363127
commit
47897e13cd
13
app/main.py
13
app/main.py
@ -596,7 +596,7 @@ async def quellen_page(request: Request):
|
||||
|
||||
|
||||
@app.get("/api/wahlprogramm-cite")
|
||||
async def wahlprogramm_cite(pid: str, seite: int, q: str = ""):
|
||||
async def wahlprogramm_cite(pid: str = "", pdf: str = "", seite: int = 1, q: str = ""):
|
||||
"""Render eine Wahlprogramm-Seite mit gelb hervorgehobener Zitat-Stelle.
|
||||
|
||||
Issue #47: Klick auf eine Zitat-Quelle im Report soll direkt zur
|
||||
@ -606,11 +606,22 @@ async def wahlprogramm_cite(pid: str, seite: int, q: str = ""):
|
||||
1-Seiten-PDF mit ``add_highlight_annot``-Annotation auf den per
|
||||
``page.search_for`` gefundenen Bounding-Boxes.
|
||||
|
||||
Akzeptiert ``pid`` (PROGRAMME-Key) ODER ``pdf`` (Dateiname wie
|
||||
``spd-grundsatzprogramm.pdf``). Letzterer ermöglicht die retroaktive
|
||||
Nutzung von Pre-#47-URLs im Frontend, wo nur der statische Pfad
|
||||
``/static/referenzen/<pdf>#page=<N>`` gespeichert ist.
|
||||
|
||||
Security: ``pid`` muss ein registrierter PROGRAMME-Key sein —
|
||||
verhindert Path-Traversal und arbiträren File-Read aus dem
|
||||
referenzen-Verzeichnis. ``seite`` wird per Pydantic-Coercion
|
||||
auf int gezwungen. ``q`` ist auf 200 Zeichen begrenzt im Renderer.
|
||||
"""
|
||||
# Reverse-Lookup: pdf-Filename → programm_id, falls nur pdf angegeben.
|
||||
if not pid and pdf:
|
||||
for p, info in PROGRAMME.items():
|
||||
if info.get("pdf") == pdf:
|
||||
pid = p
|
||||
break
|
||||
if pid not in PROGRAMME:
|
||||
raise HTTPException(status_code=404, detail="Unbekanntes Wahlprogramm")
|
||||
if seite < 1 or seite > 2000:
|
||||
|
||||
@ -1498,12 +1498,31 @@
|
||||
</div>
|
||||
`}).join('');
|
||||
|
||||
// Issue #47: Zitat-URLs zu Cite-Endpoint umschreiben für gelbes
|
||||
// Highlighting. Funktioniert retroaktiv für Pre-#47-Assessments
|
||||
// (statische /static/referenzen/X.pdf#page=N) und nativ für
|
||||
// Post-#47 (die schon /api/wahlprogramm-cite enthalten).
|
||||
function makeCiteUrl(z) {
|
||||
if (!z || !z.url) return '#';
|
||||
// Schon eine Cite-URL? Durchreichen.
|
||||
if (z.url.includes('/api/wahlprogramm-cite')) return z.url;
|
||||
// Statische URL umschreiben: /static/referenzen/X.pdf#page=N
|
||||
const m = z.url.match(/\/static\/referenzen\/(.+\.pdf)#page=(\d+)/);
|
||||
if (m && z.text) {
|
||||
const pdf = m[1];
|
||||
const page = m[2];
|
||||
const q = encodeURIComponent((z.text || '').substring(0, 200));
|
||||
return `/api/wahlprogramm-cite?pdf=${encodeURIComponent(pdf)}&seite=${page}&q=${q}`;
|
||||
}
|
||||
return z.url;
|
||||
}
|
||||
|
||||
const wahlprogrammHtml = (item.wahlprogrammScores || []).map(wp => {
|
||||
// Zitate formatieren mit klickbaren Links
|
||||
// Zitate formatieren mit klickbaren Links + Highlighting
|
||||
const zitateHtml = (wp.wahlprogramm?.zitate || []).map(z => `
|
||||
<div style="margin: 0.5rem 0; padding: 0.5rem; background: #f8f9fa; border-left: 3px solid #889e33; font-size: 0.85rem;">
|
||||
<em>"${z.text}"</em><br>
|
||||
<a href="${z.url || '#'}" target="_blank" style="color: #009da5; font-size: 0.8rem;">
|
||||
<a href="${makeCiteUrl(z)}" target="_blank" style="color: #009da5; font-size: 0.8rem;">
|
||||
📄 ${z.quelle}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user