feat: Add providerMode to get-and-persist player#308
Merged
Conversation
Add a providerMode parameter ("always", "fallback", "never") to
GetAndPersistPlayerWithCache to control whether we query the Hypixel
provider. This lets us serve players from our own stats DB and cut down
on Hypixel API usage, which bot traffic has been exhausting.
- always: query the provider for fresh data and persist it (original
behaviour).
- fallback: return the most recent stored stats when we have them, only
querying the provider when we have no stored stats. Since the
stats DB does not store usernames, the displayname is resolved
separately from our account store, falling back to a fetch
when it isn't stored.
- never: never query the provider; if the player isn't stored the
request fails (500).
The mode is validated on receipt and an invalid value is reported and
errors out. A new PlayerRepository.GetPlayer returns the most recent
stored PlayerPIT (or ErrPlayerNotFound). All callers currently pass
"fallback".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a providerMode parameter to the get-and-persist player flow so callers can prefer serving player stats from the local stats DB (and only hit external providers when needed), reducing Hypixel API usage and rate-limit pressure.
Changes:
- Add
ProviderMode(always/fallback/never) toGetAndPersistPlayerWithCache, including validation, metrics labeling, and mode-specific cache keys. - Add
PlayerRepository.GetPlayer(ctx, uuid)to retrieve the most recently storedPlayerPIT(ordomain.ErrPlayerNotFound) with Postgres + stub implementations and tests. - Update wiring and callers to pass
fallback, and add/adjust tests to cover new behavior.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| main.go | Reorders wiring so GetAndPersistPlayerWithCache can use account lookups for DB-first username resolution. |
| internal/ports/player_data.go | Updates handler to call GetAndPersistPlayerWithCache with ProviderModeFallback. |
| internal/ports/player_data_test.go | Updates port tests for new providerMode parameter. |
| internal/app/milestone.go | Uses ProviderModeFallback for milestone flow to reduce provider calls. |
| internal/app/milestone_test.go | Updates tests to assert ProviderModeFallback is passed through. |
| internal/app/get_and_persist.go | Implements provider-mode behavior, mode-specific cache keys, and DB-first displayname resolution. |
| internal/app/get_and_persist_test.go | Adds new tests covering all provider modes and invalid mode handling. |
| internal/adapters/playerrepository/repository.go | Adds Postgres + stub GetPlayer implementation selecting most recent stats row. |
| internal/adapters/playerrepository/repository_test.go | Adds Postgres GetPlayer tests (most-recent, not-found, invalid uuid). |
| internal/adapters/playerrepository/interface.go | Extends repository interface with GetPlayer contract documentation. |
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.
Why
We're seeing a lot of bot traffic on the playerdata endpoints, which is burning through our Hypixel API rate limit. This adds a
providerModeto the get-and-persist player flow so we can serve players from our own stats DB instead of always hitting Hypixel.What
Adds a
providerModeparameter toGetAndPersistPlayerWithCachewith three allowed values. The value is validated on receipt — an invalid value is reported (Sentry) and returns an error.always— query the provider (Hypixel) for fresh data and persist it. Original behaviour.fallback— return the most recent stored stats when we have them, only querying the provider when we have no stored stats for the player. The stats DB does not store usernames, so the displayname is resolved separately: we check our own account store first and only fetch (Mojang) when it isn't stored.never— never query the provider. If the player isn't stored, the request fails with a 500 (a generic error, notErrPlayerNotFound, so it does not map to 404).Supporting changes:
PlayerRepository.GetPlayer(ctx, uuid)returning the most recently storedPlayerPIT, ordomain.ErrPlayerNotFound. Implemented for the Postgres repo and the stub.BuildGetAndPersistPlayerWithCachenow takes the account repo +GetAccountByUUIDuse case for db-first username resolution;main.gowiring reordered accordingly.provider_modeattribute.All callers currently pass
fallback(playerdata port, milestone/prestiges, and theupdatePlayerInIntervalpath used by history/sessions/session-at/wrapped), as requested for the initial rollout.Tests
GetPlayertests (most-recent selection,ErrPlayerNotFound, un-normalized UUID).golangci-lintpass.🤖 Generated with Claude Code