feat(#170): sparsame **fett**-Hervorhebungen + Smoke-Tests fuer Histogram/Stand
PM-Prompt erlaubt nun max. eine Markdown-Bold-Markierung pro Absatz (Schluessel-Zahl/Effekt). Force-Regen-Test bestaetigt: qwen-max liefert **30 %** wie im Beispiel; renderPmBody im Frontend rendert das als <strong>. Smoketests gegen die neuen Endpoints (score-histogram x4, admin/stand x2 Auth-Walls) absichern Regressionen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d30fcb132a
commit
b6b0ce752a
@ -124,6 +124,14 @@ als Paragraph-Trenner verwenden. Beispiel:
|
|||||||
Im JSON: `\\n` als Escape-Sequenz (zwei Zeichen: Backslash + n).
|
Im JSON: `\\n` als Escape-Sequenz (zwei Zeichen: Backslash + n).
|
||||||
NICHT: rohe Newline-Bytes im String, NICHT: `"`-Zeichen als Trenner.
|
NICHT: rohe Newline-Bytes im String, NICHT: `"`-Zeichen als Trenner.
|
||||||
|
|
||||||
|
## Hervorhebungen (sparsam)
|
||||||
|
|
||||||
|
Du darfst pro Absatz **maximal eine** Schlüssel-Zahl oder den
|
||||||
|
zentralen Effekt mit Markdown-`**fett**` markieren — z.B. die
|
||||||
|
Abbrecherquote, eine Mehrkostensumme, eine Anzahl betroffener
|
||||||
|
Personen. Mehr als eine Markierung pro Absatz wirkt unruhig.
|
||||||
|
Niemals ganze Sätze fett, niemals Zwischenüberschriften.
|
||||||
|
|
||||||
## BEISPIELE für den Stil
|
## BEISPIELE für den Stil
|
||||||
|
|
||||||
**SCHLECHT** (verboten):
|
**SCHLECHT** (verboten):
|
||||||
@ -133,7 +141,7 @@ NICHT: rohe Newline-Bytes im String, NICHT: `"`-Zeichen als Trenner.
|
|||||||
|
|
||||||
**GUT** (gewünscht):
|
**GUT** (gewünscht):
|
||||||
> Auszubildende in der Pflege brechen ihre Ausbildung heute zu rund
|
> Auszubildende in der Pflege brechen ihre Ausbildung heute zu rund
|
||||||
> 30 % ab — meist wegen Überlastung oder fehlender Lernunterstützung.
|
> **30 %** ab — meist wegen Überlastung oder fehlender Lernunterstützung.
|
||||||
> Die in Drucksache 8/310 vorgeschlagene sozialpädagogische Begleitung
|
> Die in Drucksache 8/310 vorgeschlagene sozialpädagogische Begleitung
|
||||||
> würde diese Lücke schließen. Konkret: zwei Stunden Einzelberatung
|
> würde diese Lücke schließen. Konkret: zwei Stunden Einzelberatung
|
||||||
> pro Auszubildender pro Woche. Für Familien, deren Kinder einen
|
> pro Auszubildender pro Woche. Für Familien, deren Kinder einen
|
||||||
|
|||||||
@ -188,3 +188,49 @@ class TestAktuelleThemenEndpoints:
|
|||||||
data = resp.json()
|
data = resp.json()
|
||||||
assert "versions" in data
|
assert "versions" in data
|
||||||
assert isinstance(data["versions"], list)
|
assert isinstance(data["versions"], list)
|
||||||
|
|
||||||
|
|
||||||
|
class TestScoreHistogramEndpoint:
|
||||||
|
"""GET /api/auswertungen/score-histogram (öffentlich)."""
|
||||||
|
|
||||||
|
def test_returns_11_buckets(self):
|
||||||
|
resp = client.get("/api/auswertungen/score-histogram")
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
# 11 Buckets: 0–1, 1–2, ..., 10–11
|
||||||
|
assert len(data["buckets"]) == 11
|
||||||
|
for b in data["buckets"]:
|
||||||
|
assert "score_min" in b
|
||||||
|
assert "score_max" in b
|
||||||
|
assert "count" in b
|
||||||
|
assert b["count"] >= 0
|
||||||
|
|
||||||
|
def test_total_matches_sum_of_buckets(self):
|
||||||
|
resp = client.get("/api/auswertungen/score-histogram")
|
||||||
|
data = resp.json()
|
||||||
|
total_sum = sum(b["count"] for b in data["buckets"])
|
||||||
|
assert data["total"] == total_sum
|
||||||
|
|
||||||
|
def test_filter_bundesland(self):
|
||||||
|
resp = client.get("/api/auswertungen/score-histogram?bundesland=NRW")
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["filter"]["bundesland"] == "NRW"
|
||||||
|
|
||||||
|
def test_filter_wahlperiode(self):
|
||||||
|
resp = client.get("/api/auswertungen/score-histogram?wahlperiode=NRW-WP18")
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["filter"]["wahlperiode"] == "NRW-WP18"
|
||||||
|
|
||||||
|
|
||||||
|
class TestAdminStandAuth:
|
||||||
|
"""/v2/admin/stand + /api/admin/stand erfordern Admin."""
|
||||||
|
|
||||||
|
def test_page_unauthenticated_rejected(self):
|
||||||
|
resp = client.get("/v2/admin/stand")
|
||||||
|
assert resp.status_code in (401, 403, 307, 302)
|
||||||
|
|
||||||
|
def test_api_unauthenticated_rejected(self):
|
||||||
|
resp = client.get("/api/admin/stand")
|
||||||
|
assert resp.status_code in (401, 403, 307, 302)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user