Sprint 15: Zeitzone-Fix, Gewichts-Sync, Öffnungszeiten, KI-Bericht, POI-Moderation — SW by-v432, APP_VER 411
- client_time: Browser-Lokalzeit bei allen Creates mitschicken (Tagebuch, Notizen, Forum, Verlorener Hund, Routen) — kein UTC-Versatz mehr bei Einträgen - Gewicht-Sync: health typ=gewicht schreibt dogs.gewicht_kg, einmalige Migration - Praxen: opening_hours + lat/lon/osm_id in tieraerzte-Tabelle, OSM-Nearby-Lookup, Öffnungszeiten in Karte und Detailansicht - KI-Gesundheitsbericht: alle 2 Wochen automatisch, ki_health_reports-Tabelle, Frontend-Banner mit Archiv (letzten 5 Berichte) - POI-Korrekturen: User schlägt Öffnungszeiten-Änderung vor, Moderatoren-Tab genehmigt/lehnt ab, user_edited-Flag schützt vor Overpass-Überschreibung - timeutils.py: safe_client_time() zentral für alle Routen
This commit is contained in:
parent
679dbdd862
commit
06bd8525ed
21 changed files with 724 additions and 75 deletions
|
|
@ -100,6 +100,14 @@ def start():
|
|||
replace_existing=True,
|
||||
misfire_grace_time=1800,
|
||||
)
|
||||
# Jeden Montag 07:00 — KI-Gesundheitsberichte (alle 2 Wochen)
|
||||
_scheduler.add_job(
|
||||
_job_ki_health_report,
|
||||
CronTrigger(day_of_week='mon', hour=7, minute=0),
|
||||
id="ki_health_report",
|
||||
replace_existing=True,
|
||||
misfire_grace_time=3600,
|
||||
)
|
||||
_scheduler.start()
|
||||
logger.info("Scheduler gestartet — Health-Reminder 08:00, Giftköder-Archiv 03:00, Wetter-Alert 07:30, Meilenstein-Check 00:05, Event-Import So 02:00, Rassen-Seed beim Start. OSM-Cache: on-demand (kein Prewarm).")
|
||||
|
||||
|
|
@ -745,6 +753,76 @@ async def _job_weekly_praise():
|
|||
_log_job("weekly_praise", "ok", f"{generated} Lob-Texte f\u00fcr KW {d[1]}")
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# JOB: KI-Gesundheitsberichte (alle 2 Wochen, jeden Montag 07:00)
|
||||
# ------------------------------------------------------------------
|
||||
async def _job_ki_health_report():
|
||||
"""
|
||||
Erstellt für jeden Hund, der seit mehr als 13 Tagen keinen KI-Gesundheitsbericht
|
||||
hat (oder noch keinen hatte), einen neuen Bericht via ki.health_summary() und
|
||||
schickt eine Push-Notification an den Besitzer. Maximal 20 Hunde pro Lauf.
|
||||
"""
|
||||
import ki as KI
|
||||
|
||||
with db() as conn:
|
||||
dogs = conn.execute("""
|
||||
SELECT d.id AS dog_id, d.name, d.rasse, d.geburtstag, d.gewicht_kg, d.user_id
|
||||
FROM dogs d
|
||||
WHERE d.id NOT IN (
|
||||
SELECT dog_id FROM ki_health_reports
|
||||
WHERE erstellt_at >= datetime('now', '-13 days')
|
||||
)
|
||||
ORDER BY d.id
|
||||
LIMIT 20
|
||||
""").fetchall()
|
||||
|
||||
dogs = [dict(d) for d in dogs]
|
||||
if not dogs:
|
||||
logger.info("KI-Gesundheitsbericht: Keine fälligen Hunde.")
|
||||
_log_job("ki_health_report", "ok", "0 Berichte erstellt")
|
||||
return
|
||||
|
||||
count = 0
|
||||
for dog in dogs:
|
||||
try:
|
||||
with db() as conn:
|
||||
health_rows = conn.execute(
|
||||
"SELECT * FROM health WHERE dog_id=? ORDER BY datum DESC",
|
||||
(dog["dog_id"],)
|
||||
).fetchall()
|
||||
health_data = [dict(r) for r in health_rows]
|
||||
|
||||
dog_info = {
|
||||
"name": dog["name"],
|
||||
"rasse": dog.get("rasse"),
|
||||
"geburtstag": dog.get("geburtstag"),
|
||||
"gewicht_kg": dog.get("gewicht_kg"),
|
||||
}
|
||||
|
||||
bericht = await KI.health_summary(health_data=health_data, dog_info=dog_info)
|
||||
|
||||
with db() as conn:
|
||||
conn.execute(
|
||||
"INSERT INTO ki_health_reports (dog_id, user_id, bericht) VALUES (?, ?, ?)",
|
||||
(dog["dog_id"], dog["user_id"], bericht)
|
||||
)
|
||||
|
||||
send_push_to_user(dog["user_id"], {
|
||||
"type": "ki_health_report",
|
||||
"title": f"Gesundheitsbericht für {dog['name']}",
|
||||
"body": "Dein KI-Assistent hat einen neuen Bericht erstellt.",
|
||||
"data": {"page": "health"},
|
||||
})
|
||||
|
||||
count += 1
|
||||
logger.info(f"KI-Gesundheitsbericht: Bericht für Hund {dog['dog_id']} ({dog['name']}) erstellt.")
|
||||
except Exception as e:
|
||||
logger.error(f"KI-Gesundheitsbericht: Fehler für Hund {dog['dog_id']} ({dog['name']}): {e}")
|
||||
|
||||
logger.info(f"KI-Gesundheitsbericht Job fertig — {count}/{len(dogs)} Berichte erstellt.")
|
||||
_log_job("ki_health_report", "ok", f"{count} Berichte erstellt")
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# JOB: Status-Report per Mail (4× täglich)
|
||||
# ------------------------------------------------------------------
|
||||
|
|
@ -801,6 +879,7 @@ async def _job_status_report():
|
|||
"seed_breeds_startup": "Rassen-Seed (TheDogAPI)",
|
||||
"seed_wikidata_startup":"Rassen-Seed (Wikidata)",
|
||||
"weekly_praise": "Wöchentlicher Lober (Mo 09:00)",
|
||||
"ki_health_report": "KI-Gesundheitsberichte",
|
||||
}
|
||||
job_rows_html = ""
|
||||
job_rows_txt = ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue