Expose predicted-time as an API: GET /me and /players/{id} routes - #186
Open
puzzlerushse wants to merge 1 commit into
Open
Expose predicted-time as an API: GET /me and /players/{id} routes#186puzzlerushse wants to merge 1 commit into
puzzlerushse wants to merge 1 commit into
Conversation
Wraps GetPlayerPrediction (already live, already used on the website's
puzzle detail page) behind two new read endpoints:
GET /v1/me/puzzles/{id}/predicted-time
GET /v1/players/{id}/puzzles/{id}/predicted-time
Both share PredictedTimeResponseFactory, which applies the same two
gates the website does - the requesting token must belong to an active
member, and the target player's time_predictions_opted_out flag is
always respected regardless of who's asking. For the /players/{id}
variant, a private target's prediction is only returned to the player
themselves, matching every other /players/{id}/* endpoint's privacy
rule (zeroed data, not 403).
The response also includes difficulty_score/difficulty_level/
difficulty_confidence for the puzzle inline, fetched independently of
the prediction (GetPlayerPrediction's personalized branch doesn't
compute a real difficulty value, so it can't be read off the
prediction result) - there's no separate GET /v1/puzzles/{id}, so a
consumer wanting to show the difficulty a prediction was derived from
doesn't need a second round-trip.
Adds two rows to the public for-developers API docs page and to
docs/features/api/README.md.
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
Wraps
GetPlayerPrediction(already live, already used on the website's puzzle detail page) behind two new read endpoints:GET /v1/me/puzzles/{id}/predicted-timeGET /v1/players/{id}/puzzles/{id}/predicted-timeBoth share
PredictedTimeResponseFactory, which applies the same two gates the website does:time_predictions_opted_outflag is always respected, regardless of who is askingFor the
/players/{id}variant, a private target's prediction is only returned to the player themselves, matching every other/players/{id}/*endpoint's privacy rule (zeroed data, not 403).The response also includes
difficulty_score/difficulty_level/difficulty_confidencefor the puzzle inline, fetched independently of the prediction (GetPlayerPrediction's personalized branch doesn't compute a real difficulty value, so it can't be read off the prediction result). There's no separateGET /v1/puzzles/{id}in this PR — a consumer wanting to show the difficulty a prediction was derived from doesn't need a second round-trip.Adds two rows to the public
for-developersAPI docs page and todocs/features/api/README.md.Test plan
PredictedTimeEndpointTestcovers: no active membership → null prediction, active membership + history → personalized prediction (with presence-only assertions on the new difficulty fields, since there's nopuzzle_difficultyfixture yet for any test puzzle), non-existent puzzle → 404, missing scope → 403, privacy respected for/players/{id}, non-existent player → 404difficulty_score/difficulty_level/difficulty_confidencepopulate correctly against real data (no fixture exists to assert exact values in CI yet)