Candidate rename hardening (Codex): pending-only + length cap

Two small server-side tweaks so the endpoint matches the UI policy:
- Rename is refused (409) for promoted/rejected candidates — they're settled
  history; the UI already hides Rename for them, now the server enforces it too.
- Name is capped at 160 chars before save, so an accidental pasted paragraph
  can't wreck the queue layout.

Tests extended: 300-char name truncates to 160; renaming a promoted candidate
→ 409. 225 pytest + 11 vitest green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jay
2026-06-11 21:55:38 -04:00
parent 070b40584e
commit c4ea329f9b
2 changed files with 14 additions and 3 deletions
+8 -3
View File
@@ -1205,10 +1205,15 @@ def create_app() -> FastAPI:
def admin_candidate_rename(cid: int, body: CandidateRenameBody, request: Request) -> dict:
with get_conn() as conn:
_require_admin(conn, request)
try:
row = sources.rename_candidate(conn, cid, (body.name or "").strip() or None)
except ValueError:
cand = conn.execute("SELECT status FROM source_candidates WHERE id = ?", (cid,)).fetchone()
if not cand:
raise HTTPException(status_code=404, detail="candidate not found")
# Match the UI policy server-side: a promoted/rejected candidate is
# settled history — rename only while it's pending review.
if cand["status"] in ("promoted", "rejected"):
raise HTTPException(status_code=409, detail=f"Can't rename a {cand['status']} candidate.")
name = (body.name or "").strip()[:160] or None # cap so a pasted paragraph can't wreck the queue
row = sources.rename_candidate(conn, cid, name)
return _candidate_dict(row)
@app.post("/api/admin/candidates/{cid}/promote")