-
[OPIK-4935] [BE] feat(api): add project_name scoping to experiment stream endpoints (#5748)
发布于
2026-03-20 10:25:28 +00:00 - [OPIK-4935] [BE] feat(api): add project_name and project_id scoping to prompt version endpoints
Add project_name and project_id fields to POST /v1/private/prompts/versions/retrieve
and POST /v1/private/prompts/versions, allowing callers to scope prompt lookups
and creation to a specific project.- PromptVersionRetrieve: add optional project_name (filters lookup to given project)
- CreatePromptVersion: add optional project_id (takes precedence) and project_name
- PromptService: extract resolveProjectId() helper; use strict DAO lookup in
retrievePromptVersion to prevent fallback to workspace-level when project_name
is explicitly provided; validate project_id existence when supplied - PromptResourceTest: update all PromptVersionRetrieve call sites to use builder,
add project_name scoping and validation tests
Implements OPIK-4935
-
fix(prompts): throw NotFoundException when project_name is provided but not found in retrieve
-
fix(prompt): restore workspace-level fallback in retrievePromptVersion
Use the private findByName helper (which already handles the
project → workspace fallback) instead of calling promptDAO.findByName
directly, so retrieval behaves consistently with the creation path.- test(prompt): update retrieve fallback test to match workspace-wide fallback design
When the project-level lookup misses, retrievePromptVersion falls back
to a workspace-wide search. Updated the test to assert 200 (found via
fallback) instead of 404.- test(prompt): add missing retrieve scenarios for project-scope fallback
- workspace-level prompt found when projectName is specified (fallback)
- 404 when projectName does not exist in the workspace
- [OPIK-4981] [BE] Fall back to workspace-wide in retrievePromptVersion when project not found
When projectName is provided but does not resolve to an existing project,
pass null as projectId so the lookup falls through to workspace-wide search
instead of throwing 404.- [OPIK-4935] [BE] feat(api): add project_name scoping to experiment stream endpoints
Add project_name filtering support to POST /experiments/stream and
POST /experiments/items/stream, allowing callers to scope results to
a specific project. When project_name is provided and the project does
not exist, an empty stream is returned. When absent, the endpoints
continue to return workspace-wide results.- ExperimentStreamRequest: add projectName field
- ExperimentService: resolve projectName → projectId and pass to DAO filter
- ExperimentItemStreamRequest: add projectName field
- ExperimentItemSearchCriteria: add projectId field
- ExperimentItemService: resolve projectName → projectId via reactive
Mono.deferContextual; short-circuit to empty Flux when project not found - ExperimentItemDAO: add <if(project_id)> conditional to STREAM SQL for
both experiment_items_ids and experiment_item_aggregates_final CTEs - ExperimentsResource: wire projectName through to service/criteria
- ExperimentsResourceTest: add 4 new tests covering project-scoped and
cross-project isolation for both stream endpoints
Implements OPIK-4935
- fix(experiment-items): eliminate duplicate project DB lookup and extract shared resolver
- Add ProjectService.resolveProjectId(projectName) reactive helper to centralize
project name resolution across services - Fix ExperimentItemService.getExperimentItems: pass resolved projectId into criteria
instead of ignoring the result of resolveProjectId (was causing a second DB call) - Fix ExperimentItemService.findExperimentIdsAndGetItems: use criteria.projectId()
with the new ExperimentService.findByName(name, UUID) overload, eliminating the
duplicate findProjectIdByName call - Simplify ExperimentService.getProjectByName to delegate to the shared helper
- Add ExperimentService.findByName(String name, UUID projectId) overload for direct
UUID-based filtering without triggering an additional project lookup
- fix(test): create experiments with projectId to match FIND_BY_NAME filter
The test streamByExperimentNameAndProjectName_whenProjectExists_thenReturnOnlyItemsForThatProject
was creating experiments without a project_id, which defaults to '' in ClickHouse.
The FIND_BY_NAME query filters by experiments.project_id, so experiments with '' would
never match the resolved projectId UUID, returning empty results.Fix: set projectId on each experiment at creation time so the column is populated correctly.
下载附件