dotCMS / dotCMS/core

Experiments API gaps for the standalone portlet: archive/restore, PATCH side effects, goal operators, variant cap

Open
#36,988 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

dotCMS : Experiments Team : Falcon Type : Task
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

The new Experiments portlet (#36987) turns /experiments/new into a routed, autosaving Configure screen and adds list actions the current backend cannot support. Four API gaps stand in the way — all other mutations already exist (create, PATCH, start, end, cancel, archive, delete, variants, promote, results).

1. Archive from DRAFT + restore/unarchive

Today archive is only allowed from ENDED, and no unarchive/restore method exists at all. The approved design archives from DRAFT and ENDED, and restores an ARCHIVED experiment back to DRAFT. Add both transitions to ExperimentsAPIImpl + ExperimentsResource.

Frontend gating note: the matrix AllowedActionsByExperimentStatus (core-web/libs/dotcms-models/src/lib/dot-experiments-constants.ts:256-287) is read by the existing UVE list menu. Do not widen the existing archive: [ENDED] key — the new transitions get new keys (archiveDraft, restore) so the old UI's menu cannot change.

2. PATCH side effects (autosave blocker)

Every PATCH /api/v1/experiments/{id} currently overwrites targetingConditions with []: ExperimentForm defaults it to a non-null empty list, so the resource's != null guard always fires, creating an empty Rule + ConditionGroup on every call. The new screen autosaves on edit, so this would create one Rule per keystroke pause. Fix so an absent targetingConditions leaves the stored value untouched.

Related, document-only: trafficAllocation can never be PATCHed to 0 (if (getTrafficAllocation() > 0)) — harmless, the design's minimum is 1.

3. Goal operators: validate, then extend

The Operator enum has only EQUALS / CONTAINS / EXISTS, and operators are never validated: an unsupported operator is silently accepted and then silently ignored, producing a goal that never converts with no error anywhere. Validate on write (400 on unsupported). Then extend with the operators the design offers — STARTS_WITH, ENDS_WITH, REGEX — wired through the metric/query layer so they actually evaluate. If extending is too large for this issue, validation+reject still lands here (it is the bug) and the new operators split out; the UI then trims to the supported set.

4. Variant cap enforcement

VARIANTS_NUMBER_MAX = 3 (ExperimentsAPIImpl.java:105) is only enforced in calcBayesian (:1344) — not in addVariant (:964). A user can build 5 variants, run for two weeks, and discover the failure when opening Results. Enforce the cap in addVariant with a clear error. Open question: the design says "Up to 5 Variants" — raising the cap requires validating the Bayesian implementation for 5 arms; decide before implementing (the UI ships with whatever cap this issue lands).

Acceptance Criteria

  • Archive succeeds from DRAFT and ENDED.
  • A restore/unarchive endpoint moves ARCHIVEDDRAFT.
  • AllowedActionsByExperimentStatus gains archiveDraft and restore keys; existing keys byte-identical.
  • A PATCH without targetingConditions does not create a Rule/ConditionGroup and leaves stored targeting untouched (integration test proving no new Rule rows).
  • An unsupported goal operator is rejected with a 400 (today: silently ignored).
  • addVariant rejects the variant that would exceed VARIANTS_NUMBER_MAX.
  • Integration tests for all of the above; openapi.yaml regenerated (./mvnw compile -pl :dotcms-core -DskipTests) and committed with the annotation changes.

Priority

High — the PATCH fix blocks the Create/Update screen of #36987 (autosave is the creation mechanism).

Additional Context

  • No dependency on #36823 — parallel work.
  • Out of scope: pagination/permissions/enriched rows/counts (#36823); any frontend change beyond the two additive matrix keys.
  • Testing: ./mvnw test -pl :dotcms-core -Dtest=ExperimentsAPIImplTest · ./mvnw verify -pl :dotcms-integration -Dcoreit.test.skip=false -Dit.test=ExperimentAPIImpIntegrationTest

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ExperimentsAPIImpl and ExperimentsResource, then inspect AllowedActionsByExperimentStatus in core-web/libs/dotcms-models/src/lib/dot-experiments-constants.ts. Run ExperimentsAPIImplTest and ExperimentAPIImpIntegrationTest before changing the archive, PATCH, operator, and variant paths. Done means all acceptance criteria pass, including unchanged existing action keys and regenerated openapi.yaml.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, typescript
Domain
backend-api-design, frontend, testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.