API: POST /me/solving-times answers with the prediction that applied before the solve, and the parsed time_seconds - #201
Merged
Conversation
…before the solve, and the parsed time_seconds PR 4 of the API V1 expansion plan (docs/features/api/v1-expansion-plan.md §7). SolvingTimeResponse gains a trailing `prediction: null|TimePredictionResponse = null` (PUT keeps null). CreateSolvingTimeProcessor fills it after the dispatch, for a solo time (group_players empty) with a parsed time, when the token owner is a member who has not opted out of time predictions and the token may read results (PAT or results:read - plan §2's rule; the write scope alone does not read insights), from GetPlayerPrediction::forPuzzle(playerId, puzzleId, excludeTimeId: timeId) - the prediction that applied *before* this solve, what the added-time recap page shows: personal_solve_count is the count before the new time, last_time_seconds the previous solve. Everything else in the processor is untouched. time_seconds, always null in the create response until now, is the submitted time parsed with SolvingTime::fromUserInput - the same parser the handler stores from, so it equals the stored seconds_to_solve (no extra query). Query budgets (request only, PAT, CreateSolvingTimePredictionEndpointTest): the create's own write path is data-dependent - the PuzzleSolved event runs the statistics / intelligence recalculations, wishlist removal and notifications synchronously - measured with the prediction switched off: 29 (member, 500_01), 28 (member, 500_04), 35 (non-member, 500_02, repeat solves + subscriber), 21 (duo). The feature adds the owner profile (1) + the prediction query (4 personal / 2 statistical, ceiling 5) for an eligible request, the profile only (1) for a non-member / opted-out owner, nothing for a group time; ceilings pinned per scenario as write path + 1 + 5 / + 1 / + 0. Plan wrinkle, documented in §12: the synchronous recalculation rewrites the posted puzzle's puzzle_difficulty row inside the request, so a seeded difficulty does not survive the POST - the statistical-prediction test seeds four other players' first attempts so the puzzle is scored from real data. Docs: README POST section (response shape, semantics, gates, cost), OpenAPI summary/description on the operation, plan §7 corrected (results:read) and §12 ticked. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015uH2n4Y6gPLiYASEJwNr3H
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.
PR 4 of
docs/features/api/v1-expansion-plan.md.POST /api/v1/me/solving-timesnow answers withprediction— the forecast that applied before this solve (the new time is excluded, sopersonal_solve_count/predicted_attempt_numberare the pre-solve values), the same block the added-time recap page shows — for solo times of a member who has not opted out, with a PAT orresults:read(the write scope alone does not grant reading insights).nullotherwise; alwaysnullon PUT.time_secondsis now filled from the handler's own parser (was alwaysnull).PuzzleSolvedhandlers run sync).🤖 Generated with Claude Code
https://claude.ai/code/session_015uH2n4Y6gPLiYASEJwNr3H