Zhu Jiajun (jz28583) Claude Opus 4.7 (1M context) commited on
Commit
18fe8a0
·
1 Parent(s): 769f2a4

Add POST /admin/delete for bypass-keyed leaderboard cleanup

Browse files

Body: {entries: [{task, agent}, ...]}; deletes all submissions matching
each pair. Same bypass-key gate as /submit's dry/unlimited mode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. server/api.py +32 -0
server/api.py CHANGED
@@ -399,6 +399,38 @@ def leaderboard_all():
399
  return jsonify({"tasks": tasks, "rows": out})
400
 
401
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
  @app.get("/healthz")
403
  def healthz():
404
  manifest = _manifest()
 
399
  return jsonify({"tasks": tasks, "rows": out})
400
 
401
 
402
+ @app.post("/admin/delete")
403
+ def admin_delete():
404
+ """Delete leaderboard entries by (task, agent). Bypass-key gated.
405
+
406
+ Body: JSON {"entries": [{"task": "...", "agent": "..."}, ...]}
407
+ Returns count deleted per pair + total.
408
+ """
409
+ sent_key = request.headers.get("X-Bypass-Key", "").strip()
410
+ if not (BYPASS_KEY and sent_key
411
+ and __import__("hmac").compare_digest(sent_key, BYPASS_KEY)):
412
+ return jsonify({"error": "bypass key required"}), 403
413
+ payload = request.get_json(silent=True) or {}
414
+ entries = payload.get("entries") or []
415
+ if not isinstance(entries, list) or not entries:
416
+ return jsonify({"error": "body must be {entries: [{task, agent}, ...]}"}), 400
417
+ conn = _db()
418
+ deleted = []
419
+ for e in entries:
420
+ t, a = e.get("task"), e.get("agent")
421
+ if not (t and a):
422
+ continue
423
+ cur = conn.execute(
424
+ "DELETE FROM submissions WHERE task = ? AND agent = ?", (t, a)
425
+ )
426
+ deleted.append({"task": t, "agent": a, "rows": cur.rowcount})
427
+ conn.commit()
428
+ return jsonify({
429
+ "deleted": deleted,
430
+ "total_rows": sum(d["rows"] for d in deleted),
431
+ })
432
+
433
+
434
  @app.get("/healthz")
435
  def healthz():
436
  manifest = _manifest()