Implement GrowthBook validator, adapter, and reconstructed experiment API endpoints

What?

  1. Extract GrowthBook-specific logic from experimentConfigurationService into:
  • validation/growthBookExperimentValidator.js - validates individual experiments and performs batch validation
  • service/growthBookExperimentAdapter.js - transforms valid experiments into canonical Experiment instances
  • util/growthBookUtil.js - builds savedGroupsById from saved groups
  • util/targetingConditionParser.js - parses wiki targeting from phase conditions
  • util/experimentValidationRules.js - pure validation rules for GrowthBook experiments
  1. Validation covers:
  • trackingKey/owner presence
  • slug uniqueness against TK and GB experiments
  • deployment-day dates (Mon–Fri)
  • wiki count (1–100) with canonical ID checks
  • variation and group allocation checks
  • stream name validation
  • TK experiments with risk_level are excluded
  1. Invalid experiments are skipped with a structured warning rather than failing the poll cycle.
  2. Introduce service adapters and a consumer formatter that routes each consumer format to its dedicated adapter (Varnish, Analytics, default)
  • Route consumer formats through a dispatcher (service/consumerFormatters.js) to dedicated adapters in service/apiAdapters/
  • MediaWiki consumer format is removed — unused, and the base format serves the same shape.
  1. Simplify experiment service:
  • findAllExperiments doesn't hold formatting logic - only used by Analytics consumer format
  • fetchExperimentsFromCache returns combined experiments - used by Varnish and default consumer formats
  1. Varnish and default consumer formats read from experiments_cache table (combined TK-registered and GB-sourced experiments)
  2. Analytics consumer format continues to read experiments from the instruments table (TK-registered experiments only)
  3. Fix experiments storage:
  • Preserve rows on transient saved-groups failure
  • Clean up rows when experiments end or are turned off.
  1. traffic_split preserves per-wiki rates so multiple sample_rates are not overwritten
  2. Disable /api/v1/experiments endpoints integration tests temporarily with TODO - updated test fixtures coming in a follow up MR.

Why?

The experimentConfigurationService.js file accumulated too much responsibility — validation, adaptation, data fetching, and persistence all in one place. This refactor separates concerns so each component has a single, well-defined purpose, making the code easier to test, reason about, and extend.

The validation work requires GrowthBook experiments to be validated before reaching the API with structured rejection reasons logged for diagnostics.

The experiments endpoints should serve experiment configurations produced by the backend service (including stitched results), rather than assembling responses directly from the database queries.

By introducing dedicated adapters and a consumer formatter, we can add different kinds of consumer formats more readily in the future.

Testing Instructions:

  • In config.local.yaml
    • set run_poller to true
    • set the api_url to https://growthbook-api-next.wikimedia.org/api/v1/experiments
    • set the saved_groups_url to http://growthbook-api-next.wikimedia.org/api/v1/saved-groups
    • add your api key from staging in the growthbook config block
  • Run make run-dev in local dev environment
  • Check the experiments_cache table in your local docker database to see both TK-originated and GB-originated experiments - you should see test-experiment and sample-experiment as the GB-originated experiments in the table alongside TK experiments.
  • Check the experiments endpoints:

Bug: T421800
Bug: T421803
Bug: T421804

Edited by Clare Ming

Merge request reports

Loading