-
[OPIK-7584] [BE] Narrow the experiment aggregation-branch counts to the requested project (#7654)
发布于
2026-07-29 07:51:41 +00:00 - [OPIK-7584] [BE] Narrow the experiment aggregation-branch counts to the requested project
The aggregated/non-aggregated counts decide which branches of the experiment FIND
query are rendered, but they were computed workspace-wide. A single non-aggregated
experiment anywhere in a workspace therefore kept the raw fallback branch alive for
every request in that workspace, including projects whose experiments are fully
aggregated.Pass the requested project into AggregationBranchCountsCriteria and restrict the
non-aggregated count to experiments reachable from that project. Reachability
follows both the experiment's own project_id and the projects of the traces its
items reference, since either can bind an experiment to a project in the raw
branch; counting only one side would drop the branch and silently omit rows.The trace lookup is restricted to trace ids present in experiment_items. A project
can hold tens of millions of traces while a workspace holds under a million
experiment items, so driving it from the project alone builds an enormous set and
can cost more than the branch it removes.Other callers leave projectId unset and render an unconditional scope, so their
behaviour is unchanged.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
- [OPIK-7584] [BE] Compare whole experiments in the project-scope tests
The new project-scope tests asserted only on experiment ids, which would pass even
if a dropped branch returned the right rows with wrong field values. Compare the
returned experiments field for field against a find by experiment ids, a path whose
branch decision is unaffected by the project narrowing, so any divergence in the
data - not just in which rows come back - fails the test.Centralize the duplicated unordered-collection field lists, which appeared in four
spellings across eight comparisons, deriving the content-prefixed variant from the
same names.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
- [OPIK-7584] [BE] Drop the now-inconsistent total from the branch counts query
Scoping the non-aggregated count to the requested project left total counting the
whole workspace, so total no longer equalled aggregated + not_aggregated. Nothing
reads it - the mapper takes only the two counts - so remove it rather than leave a
column whose meaning silently changed.Also record why the project restriction applies to the non-aggregated count alone
and must not be hoisted into the outer filter: the two branches decide project
membership differently, and aggregated experiments exist whose stored project is no
longer reachable from their traces, so filtering every row by the raw branch's
notion of reachability would drop them from the aggregated count.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
- [OPIK-7584] [BE] Build AggregatedExperimentCounts through a builder
The record had no @Builder(toBuilder = true) and every call site constructed it
positionally. Both components are long, so swapping them would compile silently and
invert hasAggregated/hasRaw - dropping the wrong query branch. The riskiest site was
the DAO mapper, which feeds two same-typed values straight from row lookups into the
constructor.Add the annotation and convert all call sites, per the records-and-DTOs convention in
.agents/skills/opik-backend/SKILL.md.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
- [OPIK-7584] [BE] Compare experiment results in the order the API returns them
The helper sorted both lists by id before comparing, which was unnecessary and
weakened the assertion. Both finds render the same ORDER BY id DESC, so the order is
already deterministic and identical; re-sorting discarded it and would have hidden a
change in result ordering - the recursive comparison is order-sensitive at the top
level, so keeping the API order makes ordering part of what the tests guard.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
- [OPIK-7584] [BE] Clarify the ordering Javadoc on assertSameExperiments
"Both finds render" left the referenced operations unnamed. Link the two helpers
directly and state why the order matters: the recursive comparison is order-sensitive
at the top level, which is what makes an ordering change fail rather than pass.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
Co-authored-by: Claude Opus 5 (1M context) noreply@anthropic.com
下载附件