Skip to content

fix: override convertToSnakeCase encoding for ContextAttributes#96

Merged
sameerank merged 6 commits intomainfrom
sameerank/FFL-1808-Override-convertToSnakeCase-encoding-for-context-attributes
Feb 11, 2026
Merged

fix: override convertToSnakeCase encoding for ContextAttributes#96
sameerank merged 6 commits intomainfrom
sameerank/FFL-1808-Override-convertToSnakeCase-encoding-for-context-attributes

Conversation

@sameerank
Copy link
Copy Markdown
Contributor

@sameerank sameerank commented Feb 9, 2026

🎟️ Fixes issue
📜 Design Doc: link if applicable

Motivation and Context

Description

Two fixes:

  1. The endpoint expects camelCase attributes: categorical_attributescategoricalAttributes, numeric_attributesnumericAttributes
  2. Ignore fetchedAt. This field is generated in the configuration wire for offline initialization, but not currently used by any of the SDKs, so it shouldn't be "expected" by the SDK's config data model

How has this been documented?

How has this been tested?

decoder.dateDecodingStrategy = .iso8601

do {
let configuration = try decoder.decode(PrecomputedConfiguration.self, from: data)
Copy link
Copy Markdown
Contributor Author

@sameerank sameerank Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In local testing, I saw that this causes issues

Image

Looks like fetchedAt is mainly generated for the wire format used for offline initialization: https://github.com/Eppo-exp/js-sdk-common/blob/16e822d77cfe66d450b075152ea0016333432f3f/src/configuration-wire/configuration-wire-types.ts#L217

The Android and JS SDKs aren't otherwise tracking fetchedAt at all, e.g. in logs, so I took it out to match

request.setValue("application/json", forHTTPHeaderField: "Content-Type")

let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed with local testing: removing this preserves the camelCase

And then we can override the camelCase-auto-encoding with CodingKeys to set snake_case where expected

Image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry that API is messy; I don't like the mix of camel and snake case. Could I augment it to accept both to resolve this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be nice if they could all be snake_case, though I'd say it's not immediately necessary. I caught one more issue in local testing with the fetchedAt so I'll still need to release a patch

Comment on lines +156 to +157
XCTAssertTrue(json.contains("\"numericAttributes\""), "JSON was: \(json)")
XCTAssertTrue(json.contains("\"categoricalAttributes\""), "JSON was: \(json)")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sameerank sameerank force-pushed the sameerank/FFL-1808-Override-convertToSnakeCase-encoding-for-context-attributes branch 4 times, most recently from b7440ff to b8960e9 Compare February 9, 2026 20:43
@sameerank sameerank marked this pull request as ready for review February 9, 2026 21:04
@sameerank sameerank force-pushed the sameerank/FFL-1808-Override-convertToSnakeCase-encoding-for-context-attributes branch from b8960e9 to 67ca519 Compare February 9, 2026 21:07
@leoromanovsky leoromanovsky requested a review from Copilot February 9, 2026 21:24
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates precomputed flag request/response encoding/decoding to match the server’s expected key casing and removes fetchedAt from the SDK configuration model.

Changes:

  • Encode request payload with snake_case top-level keys while keeping nested ContextAttributes keys in camelCase.
  • Decode server responses into a dedicated PrecomputedServerResponse and build PrecomputedConfiguration locally (not expecting subject/fetchedAt from the server).
  • Remove fetchedAt from PrecomputedConfiguration and update affected tests/fixtures; bump SDK version.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Tests/eppo/precomputed/PrecomputedRequestorTests.swift Adds coverage for top-level snake_case + nested camelCase payload encoding.
Tests/eppo/precomputed/PrecomputedConfigurationTests.swift Removes fetchedAt usage from initialization/encoding/fixture expectations.
Tests/eppo/precomputed/PrecomputedConfigurationStoreTests.swift Updates store tests to align with PrecomputedConfiguration without fetchedAt.
Tests/eppo/precomputed/EppoPrecomputedClientTests.swift Updates client tests for new configuration shape (no fetchedAt).
Tests/eppo/precomputed/EppoPrecomputedClientPollingTests.swift Removes fetchedAt from polling test configurations.
Tests/eppo/precomputed/EppoPrecomputedClientPerformanceTests.swift Updates performance tests for config model without fetchedAt.
Tests/eppo/precomputed/EppoPrecomputedClientInitializationTests.swift Updates initialization tests to remove fetchedAt.
Tests/eppo/precomputed/EppoPrecomputedClientErrorTests.swift Adjusts error/concurrency test setup to match new server response decoding path.
Tests/eppo/precomputed/EppoPrecomputedClientAssignmentTests.swift Removes fetchedAt from assignment test configuration setup.
Sources/eppo/precomputed/PrecomputedRequestor.swift Implements custom payload coding keys and decodes PrecomputedServerResponse to construct PrecomputedConfiguration.
Sources/eppo/precomputed/PrecomputedConfiguration.swift Removes fetchedAt from the model and wire-format decoding/encoding.
Sources/eppo/precomputed/EppoPrecomputedClient.swift Simplifies client to store the configuration returned by the requestor (now includes subject).
Sources/eppo/Constants.swift Bumps sdkVersion to 5.3.3.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Sources/eppo/precomputed/PrecomputedRequestor.swift Outdated
Comment thread Tests/eppo/precomputed/EppoPrecomputedClientErrorTests.swift Outdated
Comment thread Tests/eppo/precomputed/PrecomputedRequestorTests.swift Outdated
Comment thread Sources/eppo/precomputed/PrecomputedRequestor.swift
Copy link
Copy Markdown
Member

@leoromanovsky leoromanovsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry that the json serialization gave you so much trouble in swift; kudos for jettisoning the fetchedAt instead of chasing after completeness there.

@sameerank sameerank merged commit 18aae66 into main Feb 11, 2026
2 checks passed
@sameerank sameerank deleted the sameerank/FFL-1808-Override-convertToSnakeCase-encoding-for-context-attributes branch February 11, 2026 23:16
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.

3 participants