Repository navigation
feat(golbat): discover instance capabilities from /api/status - #1258
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12e3acca32
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if ( | ||
| this.now() - instance.lastFetchAt < | ||
| GolbatCapabilities.RECHECK_DEBOUNCE_MS | ||
| ) { | ||
| return |
There was a problem hiding this comment.
Allow the unsupported verdict to force a status recheck
When Golbat is upgraded within 30 seconds of the startup or periodic status fetch, Pokestop.getAvailable() receives the new payload without showcase_focus_filter and calls recheck(), but lastFetchAt was just set by the preceding fetch, so this branch returns without requesting the updated status. The availability call consequently throws instead of recovering on the same pass, leaving the previous or empty filter drawer until the next scheduled availability refresh. The unsupported-capability path needs a forced retry or debounce logic that still permits this first corrective recheck.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 4e0dbae. Confirmed the scenario: recheck() shared its 30 s floor with the periodic status fetch, so an upgrade landing inside that window left the pass throwing until the next availability refresh. The availability path now calls refresh() (still single-flight, no debounce); it is already throttled by the availability refresh window, so it cannot hammer Golbat. The debounce stays on the hot-path recheck triggered by 4xx scanner responses. The test for this path now drives the real registry with a fake transport, with the upgrade landing 10 s after discovery.
|
Focused tests and changed-file lint/format checks passed, but targeted reproductions confirmed credential-isolation, timeout-handling, retry-throttling, and endpoint-prefix defects in the new capability discovery paths. Full review comments:
|
Add a GolbatCapabilities service that reads GET /api/status from every
configured Golbat endpoint and keeps { features, limits, filters } per
instance, keyed by the endpoint base url. Discovery runs from
DbManager.getDbContext (startup and config reload), refreshes every five
minutes, and rechecks an instance immediately, debounced to once per
30 s, when a scanner call answers 400/422 — the first sign of a
downgrade. A 404 or non-JSON body means an older Golbat with no
capabilities; any other failure keeps the last good result.
Pokestop.getAvailable now decides showcase focus support from
supportsFilter(mem, 'showcase_focus') when the status route advertises
filters, and only falls back to the deprecated per-response
showcase_focus_filter flag for a build that does not. The hard error on
an unsupported build is unchanged; only the source of truth moves. The
header builder shared by the evaluator and the service is extracted
into scannerHeaders.js.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016611GTrQ2W8WcznKrLQnMv
The unsupported showcase-focus verdict in Pokestop.getAvailable called the debounced recheck(), which shares its 30 s floor with the periodic status fetch. A Golbat upgrade landing inside that window left the availability pass throwing until the next one. Use refresh() there: it is still single-flight, and the path is already throttled by the availability refresh window. The debounce stays on the hot-path recheck triggered by 4xx scanner responses. The replaced test now drives the real registry with a fake transport so it exercises the debounce instead of a mocked method. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016611GTrQ2W8WcznKrLQnMv
- Keep every distinct credential set configured for a shared endpoint url and fall through to the next on 401/403, remembering the set that works. - Read the status body outside the JSON parse guard so a stalled or reset body keeps the last good capabilities instead of recording a legacy result. - Force at most one status refresh per availability payload when showcase focus is unsupported, so failing session inits no longer re-read the status on every page load. - Resolve rechecks against the registered endpoint url instead of splitting at the first /api/, so endpoints configured with a path still recheck. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4e0dbae to
fe537cb
Compare
|
@Mygod all four points are confirmed and fixed in fe537cb. The branch is also rebased onto current
Testing: |
There was a problem hiding this comment.
🟢 Approval recommended
No blocking issues were identified in the reviewed implementation or regression tests; tests were not executed during this review.
No open issues 🎉
What changed in this PR
Adds per-instance Golbat capability discovery so ReactMap can use advertised showcase-focus support while remaining compatible with older builds.
Changes:
- Adds authenticated status discovery, periodic refreshes, and cached capabilities.
- Integrates discovery with startup, reloads, and scanner rejection handling.
- Updates showcase availability checks, shared types, logging, and regression tests.
| File | Description |
|---|---|
| server/test/showcaseEndpointAvailability.test.js | Tests capability-based availability and legacy compatibility. |
| server/test/scannerCapabilityRecheck.test.js | Tests rechecks after scanner validation failures. |
| server/test/golbatCapabilities.test.js | Tests discovery, caching, authentication, and recovery. |
| server/src/utils/scannerHeaders.js | Extracts shared request headers. |
| server/src/utils/evalScannerQuery.js | Triggers capability rechecks on 400/422 responses. |
| server/src/services/GolbatCapabilities.js | Implements the capability registry. |
| server/src/services/DbManager.js | Awaits discovery during context initialization. |
| server/src/models/pokestopAvailableMapper.js | Documents the optional legacy flag. |
| server/src/models/Pokestop.js | Uses discovered showcase-focus capabilities. |
| packages/types/lib/server.d.ts | Adds registry types and deprecates the legacy flag. |
| packages/logger/lib/tags.js | Adds the Golbat logging tag. |
Review effort: Balanced
# [1.54.0](v1.53.2...v1.54.0) (2026-10-20) ### Features * **golbat:** discover instance capabilities from /api/status ([#1258](#1258)) ([c83f93f](c83f93f))
|
🎉 This PR is included in version 1.54.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
…port The own /api/status fetch every 5 minutes is replaced by the capability registry of WatWowMap#1258 (`supportsFilter(mem, 'annotate_for')`). A Golbat that refuses personal scans (e.g. its rates aren't loaded) is still skipped for a minute, and its status is now re-read right away in case it was downgraded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scope
Adds a Golbat capability registry so ReactMap can learn what each configured Golbat instance supports from
GET /api/status, with showcase focus as the first consumer. This lets Golbat drop the deprecated per-responseshowcase_focus_filterflag once builds without afiltersblock are gone (Golbat PR #404 adds the block).server/src/services/GolbatCapabilities.js(new). Reads/api/statusfor every configured endpoint using the existingX-Golbat-Secret/ basic-auth headers and theapi.fetchTimeoutMstimeout. Stores{ features, limits, filters }per instance, keyed by the endpoint base url (mem). A 404 or a non-JSON body records a legacy result (older Golbat,filters: null); any other failure (401, 5xx, network error, timeout) keeps the last good result. Refreshes every 5 minutes on an unreferenced timer, single-flight per instance.recheck(mem)re-reads immediately, at most once per 30 s per instance. Consumer API:get(mem),advertisesFilters(mem),supportsFilter(mem, key). Logs each instance's advertised filters/features/limits at info only when they change.DbManager.getDbContextawaits discovery alongside the schema checks, so the registry is populated before the first availability refresh at startup and on config reload.evalScannerQuerytriggers a recheck of the calling instance when Golbat answers 400 or 422 (the first sign of a downgrade). The header builder it shared with the new service moves toserver/src/utils/scannerHeaders.js.Pokestop.getAvailabledecides showcase focus support fromsupportsFilter(mem, 'showcase_focus')when the instance advertises filters, and falls back to the legacyshowcase_focus_filterresponse key only when the status route reported no filters block. An unsupported verdict re-reads the status (single-flightrefresh, not the debouncedrecheck, since this path is already throttled by the availability refresh window) before throwing, so an upgrade that drops the legacy flag recovers on the same pass even seconds after a periodic status fetch. The hard error (no SQL masquerade) is unchanged.GolbatStatus/GolbatInstanceadded topackages/types/lib/server.d.ts;showcase_focus_filtermarked@deprecatedand optional there and in the mapper's JSDoc.golbatlogger tag added.Out of scope, as briefed: no change to which filters ReactMap sends, no new consumer beyond showcase focus, no Golbat changes.
limitsare stored for a later clamp consumer but nothing reads them yet.Testing
yarn test: 103 server tests pass (14 new for the service, 2 new for the evaluator fast path, showcase availability tests rewritten per Golbat generation).yarn lintclean on all touched files; Prettier clean;tsc --noEmit -p jsconfig.jsonreports no new errors (the 21 pre-existing errors inPokestop.jsare unchanged).config/local.json). Suggested manual checks on a dev stack: start ReactMap against a PR Restrict areas without auth #404 Golbat and confirm the[GOLBAT]info line listsshowcase_focus; point it at a current-main Golbat and confirm the line saysno filters block (older Golbat)while showcase availability still loads via the legacy flag; stop Golbat and confirm a[GOLBAT] … keeping the last known capabilitieswarning without the drawer changing.🤖 Generated with Claude Code
https://claude.ai/code/session_016611GTrQ2W8WcznKrLQnMv