feat(tracking): write eight more alarm types through PoracleNG's /api/v2 - #828
Merged
Conversation
Raid, egg, quest, nest, gym, max battle, fort change and lure join pokemon on the uid-addressed PUT. Invasion deliberately does not: a v2 read of a named-grunt rule carries no targeting field, and PoracleWeb.NET holds only the grunt name, which live data fills with values it cannot reverse. Taking the v2 branch skips the whole v1 repair path as a unit, which is the point. Lure loses NaturalKeyTrackingUpdate's delete-create-restore dance and max battle loses its delete-then-create window; the other seven skip the reconcile of the duplicate a v1 create leaves behind. The pre-write guards stay -- v2's POST still merges and its 409 covers only an exact duplicate. TrackingV2Translator becomes table-driven, one table per type, because V2PokemonRule declares 28 integer filters and V2FortRule declares one, and additionalProperties:false turns a leaked field into a 422 the fallback silently papers over. TrackingV2TypeTranslationTests asserts each table against the schema's property list in both directions. Verified against the live 5.2.1 instance rather than the Go source, per CLAUDE.md. Every translated body was POSTed and PUT at it and the v1 read diffed: byte-identical but for the rotated uid. Three traps came out of that, all now handled -- egg level is required with minimum 1, fort has no clean/edit/summary at all, and fort include_empty defaults TRUE on v2 where v1 defaults FALSE, so omitting it flipped a stored 0 to 1. Sentinels turn out to store exactly as v1 stores them despite the migration guide, so they are sent verbatim rather than omitted. Two prerequisites landed with it. PoracleServerProfileService.GetAsync is single-flighted behind a static gate -- it is registered transient, a cold cache costs a /health GET plus a schema_migrations SELECT, and a dashboard load now sends several version-gated writes at once. The absent-route flag is keyed per type, so one gin 404 cannot drop the other eight, and for incident (whose only surface is v2) a shared flag would mean the type vanishing. Eight alarm lists gain a stable content order. They rendered PoracleNG's insertion order, so an edited card would have jumped to the end of the grid now that an edit rotates the uid.
Pokestop events are the eleventh tracking type and the one this workstream missed. That type has only ever had PoracleNG's v2 write surface, so a replace has re-keyed the rule on every edit since it shipped -- the same card-jumps-to-the-end defect the eight moved types were just given orderAlarms for. Order on the event type, the field the card is titled by. The rendering test asserted PoracleNG's insertion order, so it was defending the defect; it now asserts the content order, and a named regression test drives the uid-rotation case.
The squash merges each appended their own heading rather than joining the existing one, so the section carried duplicates again. Bullets are untouched; only the headings are merged, into Keep a Changelog's order.
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.
Merge after #827. Moves eight more alarm types onto PoracleNG's uid-addressed v2 PUT: lure, raid, egg, quest, gym, maxbattle, nest and fort. Pokemon was the pilot in #814; this makes nine of eleven.
Per-type field translators generated from 5.2.1's
openapi.golden.json, one commit each.ITrackedUidRemapperandUserOwnedOverrideAreaProxywired for every moved type.Two prerequisites that had to land first
Single-flight around
PoracleServerProfileService.GetAsync. Nine types probing the server profile concurrently on a cold cache is nine identical calls.A per-type
V2AbsentCacheKey. Without it, one gin404 page not foundon any single route dropped all nine types back to v1 at once. That is the kind of failure that looks like "v2 doesn't work" and is really one missing route.Code the migration deleted
The lure
NaturalKeyTrackingUpdatedelete-create-restore dance, and maxbattle's delete-and-recreate. Both existed only because v1 had no addressed update.Verified against the live 5.2.1 server, not just its source
Sentinels confirmed stored verbatim.
fort.include_emptyconfirmed to defaulttrueon v2 andfalseon v1 — the migration guide flags it and it is real, so the translator sends it explicitly rather than letting the default flip what existing rules match. All nine v2-write types observed rotating uids on the wire.The caveat that matters, and it is not a regression
TrackingUpdateReconciler.EnsureNoMergeIntoAnotherAlarmAsyncstill runs above the v2 branch on all eight types, and it encodes v1's merge rule. v2's PUT is a full replace that refuses only exact duplicates.So on 5.2.1 PoracleWeb.NET now refuses edits the server would happily store — a rule differing from another by exactly one updatable field such as
template— and pays an extraGetByUserAsyncround-trip per edit to do it.Behaviour is preserved rather than broken, and keeping the guard was the safe call for one change. But it is dead weight on the v2 path, and the inline comment claiming "none of the v1 repair below applies" sits directly above a v1-shaped guard that does. Worth a follow-up to strip it per-type once each is proven on v2.
A missed eleventh type, caught in review
The Pokéstop Events list never had
orderAlarmsapplied, so every edit made the saved card jump to the end of the grid — and its spec was asserting that broken order. Both fixed. That is the "fix one of eleven" pattern, found because this branch had to touch all of them.What is still on v1 here
Every read. Deliberately — see #828's note on the snapshot measurement. Invasion moved nothing in either direction and cannot until upstream fixes its read.
Verification
Backend 2531, frontend 1398, production Angular build clean.