Sprint 16: Chat-Fotos/Online/Read-Receipts, Gesundheit-Dokumente löschen, Bugfixes

- Chat: Foto-Versand (POST /api/chat/conversations/{id}/upload, media_url/media_type)
- Chat: Online-Indikator (last_seen Heartbeat, grüner Dot, 3min-Fenster)
- Chat: Read Receipts (read_at, Einzel-/Doppelhaken-Icons)
- Gesundheit: Dokument löschen (DELETE .../dokument, Datei + DB-Eintrag)
- Bug: events.user_id NOT NULL → nullable (Table-Recreation-Migration)
- Bug: scheduler INSERT user_id 0 → NULL
- Bug: Wikidata Rate-Limit: sleep 0.3s→1.0s, retries 2→4, exponentielles Backoff
- SW: by-v146, APP_VER 119
This commit is contained in:
rene 2026-04-17 22:38:33 +02:00
parent 34f29f9d0a
commit a7753c9cf5
15 changed files with 375 additions and 43 deletions

View file

@ -174,6 +174,34 @@ async def delete_health(dog_id: int, entry_id: int, user=Depends(get_current_use
return None
# ------------------------------------------------------------------
# DELETE /api/dogs/{dog_id}/health/{id}/dokument — Datei löschen
# ------------------------------------------------------------------
@router.delete("/{dog_id}/health/{entry_id}/dokument")
async def delete_dokument(dog_id: int, entry_id: int, user=Depends(get_current_user)):
with db() as conn:
_check_dog_owner(conn, dog_id, user["id"])
entry = conn.execute(
"SELECT datei_url FROM health WHERE id=? AND dog_id=?", (entry_id, dog_id)
).fetchone()
if not entry:
raise HTTPException(404, "Eintrag nicht gefunden.")
datei_url = entry["datei_url"]
if datei_url:
# datei_url z.B. "/media/health/health_42_abc12345.pdf"
filename = datei_url.lstrip("/media/")
path = os.path.join(MEDIA_DIR, filename)
if os.path.isfile(path):
os.remove(path)
conn.execute(
"UPDATE health SET datei_url=NULL, datei_typ=NULL WHERE id=?", (entry_id,)
)
return {"ok": True}
# ------------------------------------------------------------------
# POST /api/dogs/{dog_id}/health/{id}/dokument — Datei-Upload
# ------------------------------------------------------------------