fix(search): type search score as double - #889
Conversation
The exact-search handler now scores a hit by confidence rather than returning a constant, emitting fractional bands (1 certain, 0.75 strong, 0.25 deep) so clients can rank an unambiguous match above fuzzy results and hold the deep catalog tail below them. `score` was annotated `int64`, which is correct for the fuzzy pass (a Typesense `text_match` magnitude) but cannot represent those bands. A generated consumer takes the annotation literally: the Kotlin client decodes the field as `kotlin.Long`, so a fractional score is not representable there at all. Widen to `format: double`, which still covers the fuzzy magnitudes at the precision JSON already limits them to. Adds a `double` helper alongside `float`/`int64`, and corrects the `int64` doc comment, which described itself as a double.
|
Closing this - trakt/trakt-workers#1325 fixed it from the other end, and better. I widened the contract to fit fractional bands. #1325 made the bands whole numbers instead ( Merging this would have loosened the exact validation #1325 depends on. Client PRs updated to match: trakt/trakt-android#309 dropped its spec mirror and now compiles against One thing worth a separate look, unrelated to the band values: |
Why
The exact-search handler now scores a hit by confidence instead of returning a constant, emitting fractional bands so clients can rank an unambiguous match above fuzzy results and hold the deep catalog tail below them:
certain1strong0.75deep0.25scorewas annotatedint64. That is correct for the fuzzy pass, where the value is a Typesensetext_matchmagnitude at ~1e17 scale, but it cannot represent the bands above.Generated consumers take the annotation literally. The Kotlin client decoded the field as
kotlin.Long, and kotlinx throws on any fractional value:Verified by running that decode against the generated model, not inferred.
Change
scoreon all four search response shapes (movie, show, person, list) moves fromint64(z.number().int())todouble(z.number()).format: doublestill covers the fuzzy magnitudes at the precision JSON already limits them to.Adds a
doublehelper next tofloat/int64, and corrects theint64doc comment, which described itself as a double.int64stays in use for genuine int64 ids (scrobble, trending).Verification
deno checkon the search contract cleandeno task openapi:generate+openapi:validateclean; regenerated spec emits{"type":"number","format":"double"}forscoreon/search/{type},/search/{type}/exactand/search/{id_type}/{id}val score: kotlin.Doubleand decodes0.75/0.25/1deno lintreports 500 pre-existing problems repo-wide (no-explicit-anyand friends); none in the touched filesNotes
scoreasDouble?).searchResultResponseSchemais az.union([...]), whichschemas.mdcalls out as the thing to avoid because codegen turnsoneOfinto a model with every member's fields required. That is exactly what the Kotlin client shows today. Worth a separate pass.