fix(gauges): absorb five spec drifts from the contract bc3 serves
Merged
JE
2mo ago+574+574+012345678901234567890123456789-175-175-012345678901234567890123456789
Summary
Five drifts between the gauges spec and the contract bc3 serves at the pinned revision, all read off the jbuilder/controller source and doc/api/sections/gauges.md, fixed in the spec (and the one Go hand-written wrapper) and regenerated into all six SDKs:
GaugeNeedle.comment_count—_needle.json.jbuilderemits the singular key unconditionally, next to the envelope's pluralcomments_count. Modeled@required, with the same doc noteSearchResult.comment_countcarries. GoGaugeNeedle.CommentCount, SwiftcommentCount; the dict-shaped SDKs already passed it through.spec/fixtures/gauges/needle_get.jsonnow carries it and the manifest's KNOWN INCOMPLETE note is gone.UpdateGaugeNeedleInput.gauge_needleis@required, and so is itsdescription—needle_paramsopens withparams.require(:gauge_needle), which rejects a missing wrapper and an empty one alike, anddescriptionis the only member the update accepts (needle_params.except(:color, :position)). So the wrapper-less and empty-wrapper bodies every SDK permitted were a 400, never a no-op. MatchesCreateGaugeNeedle. Go's wrapper keepsDescription *stringand refusesnilbefore the wire as a usage error.notifydoc string — nameseveryone,default,custom, which is exactly whatSubscribers#find_subscribersaccepts; the previousworking_onwas invented and silently notified nobody. Surfaced in generated docs in all six SDKs.Gauge.previous_needle_positionis nullable — JSONnullfor a gauge's first needle (gauges.mdshows it).nullable: truelayered inenhance-openapi-go-types.shlike the other nullable-when-present members; Go's wrapper field becomes*int32so the null is distinguishable from a genuine move from 0. A second fixture,gauges/get_first_needle.json, pins the null against the schema.ToggleGaugedeclaresNotFoundError—ProjectScopedraisesRecordNotFoundfor an unknown project, asListGaugeNeedleson the same label already declared.
The three "noted, not proposed" items in the issue (.json suffix asymmetry, maxPageSize: 50, comma-joined bucket_ids) are left as they are.
Red-proof, from the literal wire bodies
- Go:
TestGaugeNeedle_DecodesTheSingularCommentCount(comment_count: 5next tocomments_count: 2— the field did not exist before) andTestGauge_PreviousNeedlePositionNullIsNotZero(null→ nil, wire0→ non-nil 0; the value type decoded both to 0). - Swift:
GaugeNeedleis typed, so the test fixture gainedcomment_countand the decode test assertscommentCount— before the spec change the field was discarded. - Kotlin: the "omits the wrapper when no attributes are given" test is replaced by one pinning that the wrapper always goes on the wire, since bc3 requires it.
- Fixtures:
make check-fixture-coveragevalidatesneedle_get.jsonagainst the now-required member andget_first_needle.json's null against the now-nullable one.
Breaking
Labelled breaking; the # Unreleased section in MIGRATING.md covers both:
gauge_needleand itsdescriptionbecome required onUpdateGaugeNeedlein TypeScript, Python, Ruby, Kotlin and Swift (a call that omitted them stops compiling or raises before the wire — it always got a 400; an explicitNone/nilin Python/Ruby still compacts to an empty body and gets the 400).GaugeNeedle.comment_countis required, so Swift's public initializer and the TypeScript/Python model types gain a required member.- Go
Gauge.PreviousNeedlePositionis*int32(apidiff flags the type change).
Fixes #731