fix: always report broken internal links + show source pages

Previously, broken links that were part of the baseline ("known broken")
disappeared from the terminal output (score=0, no Klartext mention).

- differ.py: build reverse link index to record which pages link to
  each broken URL; "pages" field added to new_broken/known_broken entries
- plain.py: klartext_befunde() now includes known_broken_urls alongside
  new_broken_urls — broken links are always reported until fixed
- __main__.py: report shows "gefunden auf: <page>" for every broken entry,
  known entries labelled "[bekannt, noch nicht behoben]"
- 3 new tests (169 total)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-06-12 12:18:38 +02:00
commit b01344dcd8
5 changed files with 57 additions and 6 deletions

View file

@ -299,8 +299,12 @@ def _render_markdown(r: dict) -> str:
lines += ["", "## Kaputte Links", ""]
for entry in new_broken:
lines.append(f"- [NEU] HTTP {entry['status']} `{entry['url']}`")
for page in entry.get("pages", [])[:3]:
lines.append(f" - gefunden auf: {page}")
for entry in known_broken:
lines.append(f"- [bekannt] HTTP {entry['status']} `{entry['url']}`")
lines.append(f"- [bekannt, noch nicht behoben] HTTP {entry['status']} `{entry['url']}`")
for page in entry.get("pages", [])[:3]:
lines.append(f" - gefunden auf: {page}")
if d.get("unexpected_jsonld"):
lines += ["", "## Unerwartetes JSON-LD", ""]

View file

@ -216,12 +216,27 @@ def compare_snapshots(baseline_pages: dict, current_pages: dict, cfg: dict) -> d
if p.get("status", 0) >= 400
}
current_broken = set(current_broken_map)
# Reverse index: broken_url → pages that contain a link to it
link_sources: dict[str, list[str]] = {}
for page_url, page in current_pages.items():
for link_list in page.get("links", {}).values():
if not isinstance(link_list, list):
continue
for link in link_list:
if isinstance(link, dict):
href = link.get("url", "")
if href:
link_sources.setdefault(href, []).append(page_url)
new_broken = [
{"url": url, "status": current_broken_map[url]}
{"url": url, "status": current_broken_map[url],
"pages": sorted(set(link_sources.get(url, [])))}
for url in sorted(current_broken - baseline_broken)
]
known_broken = [
{"url": url, "status": current_broken_map[url]}
{"url": url, "status": current_broken_map[url],
"pages": sorted(set(link_sources.get(url, [])))}
for url in sorted(current_broken & baseline_broken)
]

View file

@ -144,11 +144,14 @@ def klartext_befunde(
"Nach einem geplanten Update ist das normal — sonst bitte prüfen lassen."
)
# --- Kaputte Links (rein informativ) ---
# --- Kaputte Links (immer melden, bis behoben) ---
neue_kaputt = diff.get("new_broken_urls", [])
if neue_kaputt:
bekannte_kaputt = diff.get("known_broken_urls", [])
alle_kaputt = len(neue_kaputt) + len(bekannte_kaputt)
if alle_kaputt:
saetze.append(
f"{len(neue_kaputt)} interne Link(s) führen ins Leere (Seite nicht gefunden)."
f"{alle_kaputt} interne Link(s) führen ins Leere (Seite nicht gefunden). "
"Bitte prüfen und den Verweis auf der betroffenen Seite korrigieren."
)
if ext_links and ext_links.get("broken"):
saetze.append(