Small joys: Codex audit #2 fixes (route resolution, noindex, sense/tone, exclude-current re-pick)
- Admin joy item route moved to /api/admin/joys/{kind}/items/{item_id} so the
/add and /repick verbs resolve to their own routes instead of 422-ing as a
non-int item id (the launch blocker). Frontend mutate URL updated to match.
- Re-pick now excludes the currently-shown item: the endpoint reads today's
daily pool_id and passes it as `avoid`, so "Re-pick today" yields a different
item. Added `avoid` to pick_daily/_candidates across wotd/quote/onthisday.
- WOTD sense selection: the LLM now proposes word + intended part of speech, and
_lookup prefers that sense (fixes "serene" returning the archaic noun).
- On This Day tone prompt tightened to favor genuinely uplifting events and
exclude merely procedural/political-administrative ones.
- Caddy @hidden now also noindexes /word /quote /onthisday /admin (+ .html).
- Regression tests: add/repick resolve (401 not 422), add/feature/block/delete,
re-pick excludes current; WOTD pos-preference + proposal parsing units.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+7
-2
@@ -2358,6 +2358,7 @@ def create_app() -> FastAPI:
|
||||
|
||||
# --- Small-joys admin: manage the WOTD / QOTD / On-This-Day pools ----------------
|
||||
_JOY_TABLES = {"onthisday": "onthisday_pool", "quote": "quote_pool", "word": "wotd_pool"}
|
||||
_JOY_DAILY = {"onthisday": "daily_onthisday", "quote": "daily_quote", "word": "daily_wotd"}
|
||||
_JOY_MODULES = {"onthisday": onthisday, "quote": quote, "word": wotd}
|
||||
_JOY_EDITABLE = { # whitelist of editable columns
|
||||
"onthisday": {"text", "summary", "year"},
|
||||
@@ -2375,7 +2376,7 @@ def create_app() -> FastAPI:
|
||||
rows = conn.execute(f"SELECT * FROM {table} ORDER BY featured DESC, id DESC LIMIT ?", (limit,)).fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
@app.post("/api/admin/joys/{kind}/{item_id}")
|
||||
@app.post("/api/admin/joys/{kind}/items/{item_id}") # /items/ so 'add'/'repick' don't parse as an id
|
||||
def admin_joys_mutate(kind: str, item_id: int, body: JoyAction, request: Request) -> dict:
|
||||
table = _JOY_TABLES.get(kind)
|
||||
if not table:
|
||||
@@ -2438,7 +2439,11 @@ def create_app() -> FastAPI:
|
||||
raise HTTPException(status_code=404, detail="Unknown joy.")
|
||||
with get_conn() as conn:
|
||||
_require_admin(conn, request)
|
||||
picked = mod.pick_daily(conn, force=True)
|
||||
cur = conn.execute(
|
||||
f"SELECT pool_id FROM {_JOY_DAILY[kind]} WHERE feature_date=?", (local_today(),)
|
||||
).fetchone()
|
||||
avoid = cur["pool_id"] if cur else None # force a DIFFERENT item, not the same one
|
||||
picked = mod.pick_daily(conn, force=True, avoid=avoid)
|
||||
return {"ok": True, "picked": bool(picked)}
|
||||
|
||||
@app.get("/api/replacement", response_model=Article | None)
|
||||
|
||||
Reference in New Issue
Block a user