发布

  • [OPIK-7584] [BE] Narrow the experiment aggregation-branch counts to the requested project (#7654)

    frostbyte_neo 发布于 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

    下载附件