"""AA-045-F3 Patch fuer content_briefing.py (korrigierte Anker)."""
p = "/opt/struktur/social-media-radar/content_briefing.py"
s = open(p).read()
old_run = '''def run(limit: int = 500, action_filter: str = "pruefen"):
conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
ensure_columns(conn)
rows = conn.execute(
"SELECT * FROM signals WHERE director_action = ? ORDER BY director_score DESC LIMIT ?",
(action_filter, limit)
).fetchall()'''
new_run = '''def run(limit: int = 500, action_filter: str = ""):
"""AA-045-F3: Befuellt Briefings fuer alle postbaren Signale ohne Briefing.
Auswahl (idempotent, ueberschreibt keine vorhandenen Briefings):
- status nicht ignoriert/veroeffentlicht
- mallorca_relevance > 0 (fachliche Grundrelevanz)
- briefing_winkel leer (noch nie gebrieft)
ODER action_filter explizit gesetzt (altes Verhalten fuer Speziallaeufe).
"""
conn = sqlite3.connect(str(DB_PATH))
conn.row_factory = sqlite3.Row
ensure_columns(conn)
if action_filter:
rows = conn.execute(
"SELECT * FROM signals WHERE director_action = ? ORDER BY director_score DESC LIMIT ?",
(action_filter, limit)
).fetchall()
else:
rows = conn.execute(
"""
SELECT * FROM signals
WHERE status NOT IN ('ignoriert', 'veroeffentlicht')
AND COALESCE(mallorca_relevance, 0) > 0
AND COALESCE(briefing_winkel, '') = ''
ORDER BY radar_score DESC LIMIT ?
""",
(limit,)
).fetchall()'''
assert old_run in s, "run-anchor fehlt"
s = s.replace(old_run, new_run)
# Loop-Kopf mit Fehlerbehandlung
old_loop = ''' freigabe_dist = {}
for sig in rows:
result = compute_briefing(dict(sig))
conn.execute("""
UPDATE signals SET'''
new_loop = ''' freigabe_dist = {}
errors = 0
for sig in rows:
try:
result = compute_briefing(dict(sig))
except Exception as exc:
errors += 1
try:
conn.execute(
"UPDATE signals SET briefing_error = ? WHERE signal_id = ?",
(f"briefing-failed: {exc}"[:400], sig["signal_id"])
)
conn.commit()
except Exception:
pass
continue
try:
conn.execute("UPDATE signals SET briefing_error = '' WHERE signal_id = ?",
(sig["signal_id"],))
conn.execute("""
UPDATE signals SET
briefing_winkel = ?,
briefing_nutzen = ?,
briefing_zielgruppe = ?,
briefing_post_typ = ?,
briefing_fb_fit = ?,
briefing_fb_reason = ?,
briefing_li_fit = ?,
briefing_li_reason = ?,
briefing_material = ?,
briefing_risiko = ?,
briefing_freigabe = ?
WHERE signal_id = ?
""", (
result["briefing_winkel"],
result["briefing_nutzen"],
result["briefing_zielgruppe"],
result["briefing_post_typ"],
result["briefing_fb_fit"],
result["briefing_fb_reason"],
result["briefing_li_fit"],
result["briefing_li_reason"],
result["briefing_material"],
result["briefing_risiko"],
result["briefing_freigabe"],
sig["signal_id"],
))
freigabe_dist[result["briefing_freigabe"]] = freigabe_dist.get(result["briefing_freigabe"], 0) + 1
# SOL-006 REGEL-02: Briefing-Freigabe neutralisiert Director
if result["briefing_freigabe"] in ("zurueckstellen", "verwerfen"):
conn.execute(
"UPDATE signals SET director_action = 'beobachten' "
"WHERE signal_id = ? AND director_action IN ('pruefen', 'veroeffentlichen')",
(sig["signal_id"],)
)
except Exception as exc:
errors += 1
try:
conn.execute(
"UPDATE signals SET briefing_error = ? WHERE signal_id = ?",
(f"briefing-write-failed: {exc}"[:400], sig["signal_id"])
)
conn.commit()
except Exception:
pass'''
assert old_loop in s, "loop-anchor fehlt"
s = s.replace(old_loop, new_loop)
# Alten Update-Body + alten REGEL-02-Block entfernen (jetzt im new_loop enthalten)
old_body = ''' UPDATE signals SET
briefing_winkel = ?,
briefing_nutzen = ?,
briefing_zielgruppe = ?,
briefing_post_typ = ?,
briefing_fb_fit = ?,
briefing_fb_reason = ?,
briefing_li_fit = ?,
briefing_li_reason = ?,
briefing_material = ?,
briefing_risiko = ?,
briefing_freigabe = ?
WHERE signal_id = ?
""", (
result["briefing_winkel"],
result["briefing_nutzen"],
result["briefing_zielgruppe"],
result["briefing_post_typ"],
result["briefing_fb_fit"],
result["briefing_fb_reason"],
result["briefing_li_fit"],
result["briefing_li_reason"],
result["briefing_material"],
result["briefing_risiko"],
result["briefing_freigabe"],
sig["signal_id"],
))
freigabe_dist[result["briefing_freigabe"]] = freigabe_dist.get(result["briefing_freigabe"], 0) + 1
# SOL-006 REGEL-02: Briefing-Freigabe neutralisiert Director
# Wenn Briefing zurueckstellt oder verwirft, darf Director nicht aktiv entscheiden.
# director_action wird auf 'beobachten' gesetzt — nur wenn aktuell aktiv (pruefen/veroeffentlichen).
if result["briefing_freigabe"] in ("zurueckstellen", "verwerfen"):
conn.execute(
"UPDATE signals SET director_action = 'beobachten' "
"WHERE signal_id = ? AND director_action IN ('pruefen', 'veroeffentlichen')",
(sig["signal_id"],)
)
conn.commit()'''
new_body = '''
conn.commit()'''
assert old_body in s, "body-anchor fehlt"
s = s.replace(old_body, new_body)
# Zusammenfassung um errors ergaenzen
old_summary = ''' print(f"\\n[CONTENT-BRIEFING] Fertig.")'''
new_summary = ''' print(f"\\n[CONTENT-BRIEFING] Fertig. fehler={errors}")'''
assert old_summary in s, "summary-anchor fehlt"
s = s.replace(old_summary, new_summary)
open(p, "w").write(s)
print("content_briefing.py gepatcht")