feat: Pokemon availability indicators from Golbat#154
Merged
Conversation
Add "currently spawning" indicators to the Pokemon selector, powered by Golbat's availability API. When Golbat is configured, the selector shows a "Live > Spawning" filter toggle, green dot indicators on available Pokemon, and available-first sorting. Backend: - IGolbatApiProxy / GolbatApiProxy HttpClient service (X-Golbat-Secret auth) - IPokemonAvailabilityService with 5-min IMemoryCache + stale fallback - PokemonAvailabilityController with nullable DI for feature-flag gating - Conditional registration (only when GOLBAT_API_ADDRESS is set) - GolbatSettings config class, env var bridge in Program.cs Frontend: - PokemonAvailabilityService (signal-based, 5-min auto-refresh) - Pokemon selector: spawning filter, availability dots, pulse animation - Graceful degradation when Golbat is unavailable Tests: 8 backend (xUnit), 9 frontend (Jest) Docs: config reference, architecture, features, troubleshooting
hokiepokedad2
commented
Apr 7, 2026
Contributor
Author
hokiepokedad2
left a comment
There was a problem hiding this comment.
Code Review Report
Executive Summary
| Metric | Rating |
|---|---|
| Overall Grade | A |
| Code Quality | Excellent |
| Requirements Satisfied | 100% (all 7 requirements from #133) |
| Architecture Fit | Excellent — follows all existing patterns exactly |
| Risk Level | Low (purely additive, read-only, no breaking changes) |
Requirements Traceability
| Requirement | Status |
|---|---|
| Golbat API proxy (IGolbatApiProxy / GolbatApiProxy) | Done |
| Cache availability data (5-min IMemoryCache + stale fallback) | Done |
| Pokemon selector indicators (green dots, tiles, autocomplete) | Done |
| Currently spawning filter toggle with animated pulse | Done |
| Feature flag gated on Golbat connection (conditional DI) | Done |
| Defensive response parsing (flat array + object array) | Done |
| Graceful degradation (backend + frontend) | Done |
Pattern Compliance
Every new component follows an existing codebase pattern exactly:
- GolbatApiProxy → matches PoracleApiProxy (primary constructor, CreateRequest(), per-request secret header)
- Conditional DI → matches Scanner DB registration pattern
- Nullable controller injection → matches ScannerController pattern
- PokemonAvailabilityService signals → matches SettingsService / MasterDataService
- IMemoryCache caching → matches KojiService (5-min absolute TTL)
- Env var bridge → matches existing MapEnvVar() calls
- Structured logging → uses [LoggerMessage] source generator
Test Coverage
- Backend: 8 new tests (3 controller + 5 service), 721 total pass
- Frontend: 9 new tests (availability service), 509 total pass
- Build: dotnet build 0 errors, ng build --production 0 errors
- Lint: ESLint + Prettier + dotnet format all clean
Minor Observations (non-blocking)
- Empty proxy response not cached (PokemonAvailabilityService.cs:27) — if Golbat returns 0 spawns, every request hits the proxy. Unlikely edge case.
- 5-min setInterval runs globally (pokemon-availability.service.ts:39) — acceptable since payload is tiny. Could optimize later with visibility-based refresh.
- Sort after slice (pokemon-selector.component.ts:84) — available Pokemon beyond position 200 won't float to top. Pre-existing design constraint.
Risk Assessment
| Risk | Level |
|---|---|
| Breaking Change | None — purely additive |
| Data Integrity | None — read-only feature |
| Performance | Negligible — cached, O(1) lookups |
| Security | Low — per-request auth, JWT-protected |
| Rollback | Trivial — remove GOLBAT_API_ADDRESS |
Verdict: APPROVED
Post-merge: Add GOLBAT_API_ADDRESS and GOLBAT_API_SECRET to production .env, verify the Live > Spawning row appears, monitor logs for Golbat connectivity warnings.
hokiepokedad2
added a commit
that referenced
this pull request
Apr 7, 2026
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
GET /api/pokemon/availableendpointGOLBAT_API_ADDRESSis configured, hidden when notBackend
IGolbatApiProxy/GolbatApiProxy— HttpClient proxy withX-Golbat-Secretper-request auth, handles both flat array and object array response formatsIPokemonAvailabilityService/PokemonAvailabilityService— 5-minIMemoryCachecaching with_lastKnownGoodstale fallback when Golbat is downPokemonAvailabilityController—GET /api/pokemon-availabilityreturns{ available: int[], enabled: bool }, nullable DI for feature-flag gatingGolbatSettingsconfig class, env var bridge in Program.cs, docker-compose.yml passthroughFrontend
PokemonAvailabilityService— singleton, signal-basedSet<number>for O(1) lookups, 5-min auto-refreshPokemonSelectorComponentenhanced with spawning filter toggle, availability dots, available-first sortingDocumentation
Test plan
dotnet build— 0 errors, 0 warningsng build --production— 0 errorsdotnet formatappliedhttp://10.0.1.39:9001)Closes #133