fix(symbolConverter): do not register colliding outcome slugs - #199
JulienKervarrec wants to merge 4 commits into
Conversation
Templated outcome markets share their question, outcome and side names, so several distinct markets slugify to the same string and the last one loaded silently won the lookup. Collect outcome slugs first and register only the unique ones, so getAssetId returns undefined for an ambiguous slug instead of the wrong market. Closes nktkas#196 Signed-off-by: Julien Kervarrec <114134889+JulienKervarrec@users.noreply.github.com>
Adds an offline fixture with two templated markets that slugify identically and asserts that the ambiguous slug is not registered while unique ones still are. Closes nktkas#196 Signed-off-by: Julien Kervarrec <114134889+JulienKervarrec@users.noreply.github.com>
|
Update: I've now run the offline tests for this file. jsr.io is still unreachable from my environment, so for this run the JSR imports resolved to their npm builds. CI stays the reference once the workflows are approved. |
…he loop Same behaviour as before: a slug produced by more than one outcome side is left unregistered. Registration now stays as on main and the ambiguous slugs are removed afterwards, so the szDecimals lines touched by nktkas#195 are left alone and the two changes merge cleanly in either order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Julien Kervarrec <114134889+JulienKervarrec@users.noreply.github.com>
The collision test only needs to know that a unique slug is still registered. Checking for a numeric szDecimals instead of 5 keeps it valid if nktkas#195 changes that value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Julien Kervarrec <114134889+JulienKervarrec@users.noreply.github.com>
|
Small rework, same behaviour: ambiguous slugs are now unregistered after the loop instead of being filtered before registration (93f025b), and the unique-slug test checks for a numeric The point is #195: the |
Closes #196.
Problem
_processOutcomeMarketswrites every outcome side straight into_nameToAssetId:Templated markets carry the template id as their display name (
template:binaryPrice, sidetemplate:Yes) and keep the real values indescription._outcomeSlugonly slugifies the question, outcome and side names, so every market built from the same template produces the same slug and eachsetoverwrites the previous one.The result is the worst failure mode for this kind of lookup:
getAssetId("templatebinaryprice-templateyes")returns a valid id for the wrong market — whichever happened to load last — and the other markets sharing that slug cannot be reached at all. A caller has no way to tell that apart from a correct answer.Change
Record each outcome slug as it is registered, note the ones produced more than once, and unregister those after the loop. An ambiguous slug is simply absent, so
getAssetId/getSzDecimalsreturnundefined— the same result callers already handle for an unknown symbol.This deliberately does not try to invent a better slug. As #196 notes, doing that properly means rendering the template from
outcomeTemplatesinto the display name, and there is no public source for what the resulting URL slug should be. Refusing to answer is the part that can be fixed correctly today; a real slug for templated markets can follow once the naming is known.Behaviour change
A lookup on an ambiguous templated slug now returns
undefinedinstead of an id. That id was wrong for every one of those markets except one, so nothing that was correct stops working.Verification
Added
SymbolConverter templated outcome marketstotests/utils/symbolConverter.test.ts, using the existing offline fixture transport, so it runs underdeno test -A -- --offlinein CI. It covers both halves: the ambiguous slug is absent, and a uniquely named market in the same payload still resolves.I also replayed the old and the new algorithm over the existing
OUTCOME_METAfixture outside the SDK: both produce the same 14 entries with the same ids, so the recurring-price, sports and categorical slugs asserted by the current tests are untouched. On the templated fixture the old algorithm mapstemplatebinaryprice-templateyesto100003010— outcome 301, having silently replaced outcome 300 — while the new one leaves it unmapped.deno fmt --checkanddeno lint(repository rules, without the.devplugin) pass on both files, anddeno test -A tests/utils/symbolConverter.test.ts -- --offlinepasses.jsr.iois unreachable from my machine, so for that run the JSR imports were mapped to local equivalents; CI remains the reference.Note on #195
#195 changes the
szDecimalsvalue for outcome markets in this same method. This PR leaves those lines untouched, and the new test only checks that a unique slug has a numericszDecimals, not its value, so the two PRs merge cleanly in either order. I checked both orders locally: no conflict, and the test file passes after each.