Ops endpoint to backfill game-night LLM recaps for the last N nights - #135
Merged
Conversation
POST /api/backfill_game_night_summaries?days=N&max_to_update=K fills in missing recaps for the last N closed game nights, newest first. Ops-admin gated on the cookie session_router, alongside the single-night trigger. Every night written is a billed LLM call, so the spend is bounded separately from the search: `days` says how far back to look, `max_to_update` how many calls one run may spend (default 1, per the backfill endpoint pattern). It never overwrites an existing row, never touches the night still being played, and skips nights below the floor the nightly job uses. A provider error stops the run rather than burning the rest of the budget. The report lists every night considered with its outcome, so a default run doubles as a dry run of the next one. MIN_MATCHES_FOR_SUMMARY moves to commentary/night_summary.py now that the job and the backfill both have to refuse the same nights; schedule.py re-exports it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RQ4vgARjcMsiLg3Gk9bnLS
Adds the two billed triggers to the control panel: the backfill (days to look back, max calls to spend) and the single-night generator. Both set confirmWord, so the button arms only once the operator has typed the confirmation - SPEND for the backfill, the night's own date for the single one, which makes a mis-typed date impossible to confirm. The warning chip was hard-coded to "destructive", which is the wrong warning for a task that spends money without destroying anything, so a task now says which kind it is via confirmLabel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RQ4vgARjcMsiLg3Gk9bnLS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
POST /api/backfill_game_night_summaries?days=N&max_to_update=K— fills in missing LLM game-night recaps for the last N closed nights, newest first. Ops-admin gated on the cookiesession_router, alongside the existing single-night trigger.Why the two knobs
Every night this writes is a real, billed LLM call, so the spend is bounded separately from the search:
days— how far back to look (game-night keys back from tonight's key).max_to_update— how many calls one run may spend (default 1, per the repo's backfill-endpoint pattern). Re-run to continue.Guards
already_summarized) —generate_game_night_summary/{night}?force=trueis still the way to rewrite one deliberately.queries.closed_nights_within, same 5am-Eastern rollover reasoning aslatest_closed_night), because a stored recap is permanent.MIN_MATCHES_FOR_SUMMARYare skipped.days < 1,max_to_update < 1, a heldgeneration_lock(409), or no provider configured (503).failedand stops the run rather than burning the rest of the budget; the partial report is still returned.The response lists every night considered with an outcome (
generated/already_summarized/too_few_games/not_attempted/failed) plusgeneratedandremainingcounts — so a default-budget run doubles as a dry run of the next one.Also
queries.closed_nights_within(all_games, days)— the window selection, inqueries/where corpus selection belongs.GameNightBackfill/GameNightBackfillNight/GameNightBackfillOutcome; TS client regenerated with./gen_client.sh.MIN_MATCHES_FOR_SUMMARYmoved tocommentary/night_summary.pynow that the nightly job and the backfill must refuse the same nights;schedule.pyre-exports it.Testing
make format/lint/typecheckclean,npm run typecheckclean, full pytest 918 passed (3 new tests covering the window boundaries, the live-night exclusion, and the shared floor). The route is present in the running server's OpenAPI spec. The endpoint itself was not called — doing so spends money.🤖 Generated with Claude Code
https://claude.ai/code/session_01RQ4vgARjcMsiLg3Gk9bnLS