diff --git a/backend/scheduler.py b/backend/scheduler.py
index d87ef3f..69bdbcc 100644
--- a/backend/scheduler.py
+++ b/backend/scheduler.py
@@ -650,6 +650,34 @@ async def _job_ki_health_report():
# ------------------------------------------------------------------
+def _action_items_html(metrics: dict) -> str:
+ items = [
+ ("jobs_pending", "Bewerbungen offen"),
+ ("breeder_pending", "Züchter-Anträge"),
+ ("reports_open", "Forum-Meldungen"),
+ ("fotos_pending", "Foto-Einreichungen"),
+ ("poi_edits_pending", "POI-Korrekturen"),
+ ]
+ open_items = [(label, metrics.get(key, 0)) for key, label in items if metrics.get(key, 0) > 0]
+
+ if not open_items:
+ body = '✅ Alles erledigt — nichts offen'
+ else:
+ pills = "".join(
+ f''
+ f'{label} {count}'
+ for label, count in open_items
+ )
+ body = f'
⚠️ {len(open_items)} Punkt{"e" if len(open_items)!=1 else ""} brauchen deine Aufmerksamkeit
{pills}'
+
+ link = ''
+ return f'' \
+ f'
Heute zu erledigen
' \
+ f'{body}{link}
'
+
+
# JOB: Status-Report per Mail (täglich 06:00 Uhr)
# ------------------------------------------------------------------
async def _job_status_report():
@@ -677,6 +705,7 @@ async def _job_status_report():
# Community
metrics["users"] = conn.execute("SELECT COUNT(*) FROM users").fetchone()[0]
+ metrics["users_today"] = conn.execute("SELECT COUNT(*) FROM users WHERE DATE(created_at)=DATE('now')").fetchone()[0]
metrics["dogs"] = conn.execute("SELECT COUNT(*) FROM dogs").fetchone()[0]
metrics["diary_entries"] = conn.execute("SELECT COUNT(*) FROM diary").fetchone()[0]
metrics["poison_active"] = conn.execute("SELECT COUNT(*) FROM poison WHERE geloest=0").fetchone()[0]
@@ -685,6 +714,28 @@ async def _job_status_report():
except Exception:
metrics["lost_active"] = 0
+ # Action Items
+ try:
+ metrics["jobs_pending"] = conn.execute("SELECT COUNT(*) FROM job_applications WHERE status IN ('pending','reviewing')").fetchone()[0]
+ except Exception:
+ metrics["jobs_pending"] = 0
+ try:
+ metrics["breeder_pending"] = conn.execute("SELECT COUNT(*) FROM users WHERE breeder_status='pending'").fetchone()[0]
+ except Exception:
+ metrics["breeder_pending"] = 0
+ try:
+ metrics["reports_open"] = conn.execute("SELECT COUNT(*) FROM forum_reports WHERE resolved=0").fetchone()[0]
+ except Exception:
+ metrics["reports_open"] = 0
+ try:
+ metrics["fotos_pending"] = conn.execute("SELECT COUNT(*) FROM wiki_foto_submissions WHERE status='pending'").fetchone()[0]
+ except Exception:
+ metrics["fotos_pending"] = 0
+ try:
+ metrics["poi_edits_pending"] = conn.execute("SELECT COUNT(*) FROM osm_poi_edits WHERE status='pending'").fetchone()[0]
+ except Exception:
+ metrics["poi_edits_pending"] = 0
+
# Wiki-Interesse
try:
metrics["interesse_hat"] = conn.execute("SELECT COUNT(*) FROM wiki_breed_interest WHERE typ='hat'").fetchone()[0]
@@ -736,6 +787,9 @@ async def _job_status_report():
{now_str} Uhr
+
+ {_action_items_html(metrics)}
+
Scheduler-Jobs
@@ -749,14 +803,14 @@ async def _job_status_report():
Community
{"".join(f'
' for k,v in [
- ("Nutzer",metrics["users"]),
+ ("Nutzer gesamt",metrics["users"]),
+ ("Neue Nutzer heute",metrics["users_today"]),
("Hunde",metrics["dogs"]),
("Tagebuch-Einträge",metrics["diary_entries"]),
("Aktive Giftköder",metrics["poison_active"]),
("Vermisste Hunde",metrics["lost_active"]),
("'So einen hab ich'",metrics["interesse_hat"]),
("'Interessiert mich'",metrics["interesse_will"]),
- ("Züchter (pending)",metrics["zuchter_pending"]),
])}
@@ -770,19 +824,28 @@ async def _job_status_report():