Skip to content

canonicalize datastream wire payloads to camelCase#130

Merged
bpapillon merged 3 commits into
mainfrom
datastream-serializer-canonicalization
Jun 3, 2026
Merged

canonicalize datastream wire payloads to camelCase#130
bpapillon merged 3 commits into
mainfrom
datastream-serializer-canonicalization

Conversation

@bpapillon
Copy link
Copy Markdown
Contributor

@bpapillon bpapillon commented Jun 3, 2026

Run incoming DataStream company/user/flag payloads through the Fern serializers (parseOrThrow) on ingest instead of casting the raw wire object, so the cache holds a single canonical camelCase shape. Unknown keys use passthrough so a server running ahead of the pinned SDK keeps its entity (known fields canonicalized, unknown fields retained) rather than being dropped. merge.ts is simplified accordingly: partial updates write camelCase fields directly, dropping the dual camel/snake getProp reads, and nested objects arriving in partials (metrics, entitlements) are canonicalized on merge.

Canonicalization surfaced a casing bug in the entitlement sync: syncEntitlementDerivedFields wrote snake_case credit_remaining next to the canonicalized creditRemaining, and the WASM rules engine rejects an object carrying both casings of one field ("duplicate field") — so a single partial credit-balance update made every subsequent flag check for that company fall back to its default value. The sync now writes the camelCase field.

The wire format from the API is snake_case (rulesengine v0.1.16 json tags) and the WASM engine (rulesengine/v0.2.0) accepts either casing per field via serde aliases, so both the old snake cache and the new camelCase cache evaluate correctly — only mixed-casing objects break. New wasm-datastream.test.ts exercises the full wire → canonicalize → merge → evaluate path against the real engine in CI, including the partial-metrics flag flip and the credit-balance regression.

bpapillon added 2 commits June 3, 2026 09:29
…jects

The WASM rules engine accepts either casing per field via serde aliases,
but rejects an object carrying both casings of the same field ("duplicate
field"). syncEntitlementDerivedFields wrote snake_case credit_remaining
next to the canonicalized creditRemaining, so one partial credit_balances
update made every subsequent flag check for that company fall back to its
default value.

Write the camelCase field instead, and canonicalize incoming partial
metrics/entitlements via the Fern serializers so merged entities keep a
single shape. Adds wasm-datastream.test.ts, which exercises the full
wire -> canonicalize -> merge -> evaluate path against the real engine.
@bpapillon bpapillon marked this pull request as ready for review June 3, 2026 17:43
@bpapillon bpapillon requested a review from a team as a code owner June 3, 2026 17:43
Comment thread tests/unit/wasm-datastream.test.ts
@bpapillon bpapillon merged commit c0641a9 into main Jun 3, 2026
5 checks passed
@bpapillon bpapillon deleted the datastream-serializer-canonicalization branch June 3, 2026 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants