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
|
|
@ -45,11 +45,20 @@ async def mod_stats(user=Depends(require_moderator)):
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
pending_poi_edits = 0
|
||||
try:
|
||||
pending_poi_edits = conn.execute(
|
||||
"SELECT COUNT(*) FROM osm_poi_edits WHERE status='pending'"
|
||||
).fetchone()[0]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return {
|
||||
"open_reports": open_reports,
|
||||
"pending_fotos": pending_fotos,
|
||||
"banned_users": banned_users,
|
||||
"pending_zuchter": pending_zuchter,
|
||||
"open_reports": open_reports,
|
||||
"pending_fotos": pending_fotos,
|
||||
"banned_users": banned_users,
|
||||
"pending_zuchter": pending_zuchter,
|
||||
"pending_poi_edits": pending_poi_edits,
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -207,3 +216,56 @@ async def mod_foto_action(foto_id: int, data: dict, user=Depends(require_moderat
|
|||
reject_reason=data.get("reject_reason", ""),
|
||||
)
|
||||
return await review_submission(foto_id, model, user)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# GET /api/moderation/poi-edits — ausstehende POI-Korrekturen
|
||||
# ------------------------------------------------------------------
|
||||
@router.get("/poi-edits")
|
||||
async def mod_poi_edits(user=Depends(require_moderator)):
|
||||
with db() as conn:
|
||||
rows = conn.execute("""
|
||||
SELECT e.id, e.osm_id, e.poi_name, e.field,
|
||||
e.old_value, e.new_value, e.status,
|
||||
e.created_at, e.resolved_at,
|
||||
u.name AS einreicher_name
|
||||
FROM osm_poi_edits e
|
||||
JOIN users u ON u.id = e.user_id
|
||||
ORDER BY e.status ASC, e.created_at DESC
|
||||
LIMIT 100
|
||||
""").fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# PATCH /api/moderation/poi-edits/{id} — approve / reject
|
||||
# ------------------------------------------------------------------
|
||||
@router.patch("/poi-edits/{edit_id}")
|
||||
async def mod_poi_edit_action(edit_id: int, data: dict,
|
||||
user=Depends(require_moderator)):
|
||||
action = data.get("action")
|
||||
if action not in ("approve", "reject"):
|
||||
raise HTTPException(400, "action muss 'approve' oder 'reject' sein.")
|
||||
|
||||
with db() as conn:
|
||||
edit = conn.execute(
|
||||
"SELECT * FROM osm_poi_edits WHERE id=?", (edit_id,)
|
||||
).fetchone()
|
||||
if not edit:
|
||||
raise HTTPException(404, "Korrektur nicht gefunden.")
|
||||
if edit["status"] != "pending":
|
||||
raise HTTPException(409, "Korrektur wurde bereits bearbeitet.")
|
||||
|
||||
if action == "approve":
|
||||
conn.execute(
|
||||
f"UPDATE osm_pois SET {edit['field']}=?, user_edited=1 WHERE osm_id=?",
|
||||
(edit["new_value"], edit["osm_id"])
|
||||
)
|
||||
|
||||
conn.execute(
|
||||
"""UPDATE osm_poi_edits SET status=?, mod_id=?, resolved_at=datetime('now')
|
||||
WHERE id=?""",
|
||||
(action + "d", user["id"], edit_id)
|
||||
)
|
||||
|
||||
return {"status": action + "d"}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue