Skip to content

[AI-FSSDK] [FSSDK-12813] Normalize decision event campaign_id, variation_id, and entity_id#634

Open
jaeopt wants to merge 4 commits into
masterfrom
ai/jaeopt/FSSDK-12813-holdout-event
Open

[AI-FSSDK] [FSSDK-12813] Normalize decision event campaign_id, variation_id, and entity_id#634
jaeopt wants to merge 4 commits into
masterfrom
ai/jaeopt/FSSDK-12813-holdout-event

Conversation

@jaeopt

@jaeopt jaeopt commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Normalize three decision-event identifier fields uniformly across every decision type (experiment, feature test, rollout, holdout) in the event-builder layer. decisions[].campaign_id and impression events[].entity_id fall back to experiment_id only when null or "" (any non-empty string passes through unchanged, since IDs may be opaque, e.g. "default-12345" or "layer_abc"); decisions[].variation_id falls back to null when null, empty, whitespace, or non-numeric. The path never logs, throws, or blocks event dispatch.

Changes

  • Added core-api/.../event/internal/EventIdNormalizer with four pure helpers (isNonEmptyString, isNumericString, normalizeCampaignId, normalizeVariationId). normalizeCampaignId accepts any non-empty string as-is and falls back to experiment_id only on null / empty input; normalizeVariationId keeps the strict numeric-string-only contract and falls back to null for anything else.
  • Wired the normalizer into EventFactory.createVisitor(ImpressionEvent) on the single impression path so the same rules apply to all decision types. Impression entity_id mirrors the normalized campaign_id byte-for-byte; conversion entity_id is unchanged.
  • Audited existing event-builder tests per FR-011 — OptimizelyTest and OptimizelyUserContextTest expectations updated to normalized values with inline FSSDK-12813 references; added unit and integration coverage for the new helpers and the full impression payload.

Jira Ticket

FSSDK-12813

jaeopt added 4 commits June 25, 2026 08:42
…ing per updated spec

Per the updated FSSDK-12813 spec, decision-event campaign_id and impression
entity_id only require a non-empty string (IDs may be opaque, e.g.
"default-12345" or "layer_abc"). Fallback to experiment_id now fires only
when the value is null or "". variation_id retains the stricter
numeric-string-only contract.

- EventIdNormalizer: add isNonEmptyString predicate and route
  normalizeCampaignId through it; isNumericString and normalizeVariationId
  unchanged.
- EventIdNormalizerTest: add isNonEmptyString coverage; flip
  normalizeCampaignId tests so non-numeric/whitespace inputs assert
  passthrough; variation_id assertions unchanged.
- EventFactoryNormalizationTest: flip whitespace and non-numeric
  campaign_id tests to passthrough; split the uniform-across-rule-types
  test into opaque-passthrough and null-fallback variants; update
  entity_id-mirrors-campaign_id and event-never-dropped tests to use
  null/empty for the campaign_id fallback path and a non-numeric value
  only for the variation_id null path.
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.

1 participant