fix(upstream): adopt PoracleNG 5.2.1's fort hook and availableLanguages - #833
Merged
Conversation
…ig call PoracleNG 5.2.1 adds `fort` to `disabledHooks` (jfberry/PoracleNG#197, filed as #195), so the separate `general.disable_fort_update` read from /api/config/values exists only for older servers now. `PoracleDisabledHookMap` gains the `fort` entry, and `UpstreamFeatureFlagService` makes the fort probe conditional. The discriminator is the presence of `availableLanguages` on the config response, not a version number: both fields arrived in the same release, PoracleNG serves no version endpoint, and an empty `disabledHooks` cannot tell "nothing is disabled" from "too old to say". Verified live -- absent on 5.1.0, present and null on 5.2.1. A config read that failed leaves the discriminator unanswered, so the probe is still made. Guessing "new" there would silently stop honouring the flag on every older server the moment Poracle hiccuped. Everything else still fails open. `pokestop` is dropped from the array upstream in the same release; the mapping stays deliberately empty for the older servers that still send it.
PoracleNG 5.2.1 publishes `availableLanguages` on /api/config/poracleWeb (jfberry/PoracleNG#197, filed as #194): the exact set of codes it will accept for a human's language, answering 422 to anything else. Until now the alert language menu offered all eleven regardless, so on a restricted server some rows were writes that could only fail. It governs the alert language, not the display language. `allowed_languages` is this site's own restriction on the display menu and stays independent -- the two answer to different owners, and neither substitutes for the other. Served to the SPA as `poracle_alert_languages`, a projection in the same shape as `poracle_locale`: refused by `Upsert` and declared in `PROJECTED_KEYS`, so a stored row cannot pin a list Poracle has stopped agreeing with. No row is served when Poracle restricts nothing -- absent, null and empty all mean unrestricted, which is what an unconfigured 5.2.1 and every 5.1.0 send, and both keep the full menu. The menu item hides itself when Poracle accepts nothing this UI has a flag row for, rather than opening on an empty list. `load()` still reconciles against every language shipped, so a stored value predating a restriction is reported rather than lost.
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.
Adopts two upstream fixes shipped in PoracleNG 5.2.1 (jfberry/PoracleNG#197). Both of our workarounds were still running against a server that no longer needs them. Both upstream issues — #194 and #195 — are now closed as completed.
1.
fortindisabledHooks, and one fewer call —fd2e46cPoracleDisabledHookMapgains["fort"] = DisableFeatureKeys.FortChanges, and the secondGET /api/config/valuesprobe forgeneral.disable_fort_updateis now made only when the server is too old to reportfort.Detection is the presence of the
availableLanguageskey, not a version number. It shipped in the same release asfort, and its presence is a yes-or-no with no third reading. The alternatives are worse:versionis a string needing semantic comparison, and an emptydisabledHooksis ambiguous — nothing disabled, or too old to say.One subtlety worth reading: a config read that failed leaves the question unanswered, so the probe is still made. Assuming "new" on a failure would stop honouring the flag on every 5.1.0 the moment Poracle hiccuped. Everything still fails open, per the rule in
CLAUDE.mdthat a Poracle outage must not disable every alarm type for everyone.The doc comments were rewritten rather than left. The
pokestopparagraph now says it was vestigial, is gone from the array as of 5.2.1, and stays unmapped for older servers that still send it; thedisable_fort_updateparagraph now describes the second call as an older-server fallback rather than a permanent necessity. Stale comments explaining a workaround that no longer applies are the lie the next reader believes.Correcting the upstream prediction
The issue said this "should let you drop that second
/api/config/valuescall entirely". It does not, quite:disable_showcaseis still absent fromdisabledHookson 5.2.1, and that endpoint is the only place to read it. Verified on both servers —disable_showcaseis present in/api/config/valueson 5.2.1 and absent on 5.1.0.Net effect on 5.2.1: three upstream calls per probe become two. Adding
showcaseto the array upstream would make it one.2.
availableLanguages—3736c32It governs the alert language, not the display language. Confirmed in PoracleNG's own code rather than assumed: both
HandleSetLanguage(v1) and the v2 route validate the submitted code againstavailable_languagescase-insensitively and answer 422 "language is not available".So it does not compose with our
allowed_languagessite setting, which restricts the display menu — they govern different things.AlertLanguageService.languageswas already deliberately built fromallLanguagesrather than the filtered list, and that stays. The only intersection applied is against the eleven languages this UI has a flag row for, since a code we cannot render is not offerable regardless.Semantics follow the upstream author's deliberate choice: key absent means an older server,
nullmeans unrestricted, a non-null array is the exact allow-list. Absent,nulland empty all collapse to "unrestricted", which is right for both an unconfigured 5.2.1 and every 5.1.0.poracle_alert_languagesis a projection, alongsideporacle_locale— one shared config read, one cache entry.Upsertrefuses it andPROJECTED_KEYScarries it, so it never reaches the admin page's "Other" catch-all as an editable box. Both halves are required: a stored row would win over the projected value permanently. See poracle_locale is editable in admin settings and one save pins it permanently #780 for the same mistake.load()still reconciles against all eleven, so a stored choice predating a restriction is reported rather than silently reverted.No new user-facing strings — the empty case hides a control rather than explaining itself — so the eleven locale files are untouched.
Verified against both live servers
disabledHooksis empty on both because this deployment disables nothing, so a non-empty array could not be observed — thefortmapping rests on the upstream author's statement plus upstream'shookTypesconstruction. Neither server's config was touched and production was not contacted.Tests
Backend 2595 (from 2582), frontend 119 suites / 1423 (from 1415), production build clean, ESLint and Prettier clean.
Every new test was watched red first, and each new-behaviour test is paired with a 5.1.0-still-works sibling —
ServerWithoutAvailableLanguagesIsStillAskedForTheFortFlag,GetAllServesNoAlertLanguagesRowForAServerTooOldToReportThem, "should offer all eleven on a Poracle too old to say", "restricts nothing when Poracle is too old to report an allow-list". The fallback is the whole point of the change, so it is the half that most needed pinning.CLAUDE.mdis updated in both the upstream-flags and projections sections, anddocs/features/internationalization.mdnow says whose list is whose.