Skip to content

feat(multivariate): thread variant key into the environment document#7699

Draft
gagantrivedi wants to merge 1 commit into
feat/multivariate-option-keyfrom
feat/multivariate-key-engine-document
Draft

feat(multivariate): thread variant key into the environment document#7699
gagantrivedi wants to merge 1 commit into
feat/multivariate-option-keyfrom
feat/multivariate-key-engine-document

Conversation

@gagantrivedi
Copy link
Copy Markdown
Member

@gagantrivedi gagantrivedi commented Jun 3, 2026

WIP / draft. Stacked on #7698 (feat/multivariate-option-key) — review that first; the diff here will look standalone once #7698 merges and this retargets to main. Second backend slice of "give every multivariate value a stable key so we know which variant a user was exposed to".

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature. (deferred — the key isn't surfaced to SDK consumers yet; docs land with the SDK/experimentation slices.)
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Contributes to

Threads the per-variant key (added to MultivariateFeatureOption in #7698) into the environment document so it's available to anything that reads that document.

  • Engine model (util/engine_models/features/models.py): add key: Optional[str] = None to MultivariateFeatureOptionModel — same shape as the existing id field.
  • Mapper (util/mappers/engine.py): map_mv_option_to_engine now passes key=mv_option.key. Both the SDK local-eval document (map_environment_to_sdk_document) and the DynamoDB/edge document model_dump() the whole EnvironmentModel, so the field propagates to both with no per-mapper change.

Runtime variant selection (_get_multivariate_value) is unchanged — it still returns the value. Surfacing the key in SDK/identify responses is a later slice.

Backward/forward compatibility (DynamoDB + Edge API)

Adding this field is safe in both directions, verified rather than assumed:

  • In-repo engine models set no extra='forbid' → pydantic 2.x defaults to extra='ignore'.
  • The flagsmith-flag-engine package is entirely TypedDict → no runtime validation, unknown keys are inert.
  • This repo already parses documents back into these models (edge_api/identities/models.py, util/mappers/dynamodb.py); all tolerate extra fields.
  • Old doc → new code: key defaults to None. New doc → lagging/old code (e.g. Edge API mid-deploy): unknown field ignored, no error.
  • DynamoDB is schemaless; adding an attribute is a no-op at the storage layer.

How did you test this code?

Automated, TDD-first (Given/When/Then):

  • test_map_mv_option_to_engine__option_with_key__includes_key — key propagates into the engine model.
  • test_map_feature_state_to_engine__mv_option_with_key__key_in_serialised_document — key appears in the serialised document (model_dump), i.e. what's written to Dynamo / sent to SDKs.
  • test_multivariate_feature_option_model__document_without_key__defaults_to_none — an older document (no key) parses with key defaulting to None.

Existing edge_api integration tests assert the exact identity document written to DynamoDB; their snapshots (the shared identity_document fixture + one inline expected) were updated to include the new key field.

Verification run locally:

  • Mapper suite: passing.
  • Regression sweep across document consumers (edge_api, environments, util, feature serializers, import/export): passing.
  • ruff check, ruff format, mypy (strict): clean.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Preview Jun 3, 2026 12:37pm
flagsmith-frontend-preview Ignored Ignored Preview Jun 3, 2026 12:37pm
flagsmith-frontend-staging Ignored Ignored Preview Jun 3, 2026 12:37pm

Request Review

@github-actions github-actions Bot added api Issue related to the REST API feature New feature or request labels Jun 3, 2026
@gagantrivedi gagantrivedi force-pushed the feat/multivariate-key-engine-document branch from 21137cc to 3fb6448 Compare June 3, 2026 12:20
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 3, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.52%. Comparing base (df85009) to head (768a723).

Additional details and impacted files
@@                      Coverage Diff                      @@
##           feat/multivariate-option-key    #7699   +/-   ##
=============================================================
  Coverage                         98.52%   98.52%           
=============================================================
  Files                              1445     1445           
  Lines                             55021    55043   +22     
=============================================================
+ Hits                              54211    54233   +22     
  Misses                              810      810           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add `key` to the engine `MultivariateFeatureOptionModel` and map it through
in `map_mv_option_to_engine`, so the per-variant key flows into both the SDK
local-evaluation document and the DynamoDB/edge document.

The field is optional (defaults to None), mirroring the existing `id` field on
the same model. Adding it is backward- and forward-compatible: consumers parse
these documents with pydantic's default `extra='ignore'`, so a lagging Edge API
reading a newer document silently ignores the unknown field, and new code
reading an older document defaults `key` to None. Two regression tests lock in
this round-trip guarantee.
@gagantrivedi gagantrivedi force-pushed the feat/multivariate-key-engine-document branch from 3fb6448 to 768a723 Compare June 3, 2026 12:37
@github-actions github-actions Bot added feature New feature or request and removed feature New feature or request labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Issue related to the REST API feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant