[OPIK-5303] [BE] feat: add source filter support to GET /projects/stats#5929
[OPIK-5303] [BE] feat: add source filter support to GET /projects/stats#5929thiagohora wants to merge 1 commit intomainfrom
Conversation
Wire List<TraceFilter> filters through ProjectCriteria → ProjectService → TraceDAO so callers can exclude non-SDK traces (experiment, playground, optimization) from aggregated project statistics. - Added `filters` query param to GET /projects/stats endpoint - Updated ProjectCriteria to hold List<? extends Filter> - Updated ProjectService.getProjectStats to pass filters to DAO - Updated TraceDAO.getStatsByProjectIds to accept and apply TraceFilters - Added integration test covering source=sdk filter behavior Implements OPIK-5303
| @Test | ||
| @DisplayName("when source filter is applied, then exclude non-SDK traces from stats") | ||
| void getProjectStats__whenSourceFilterApplied__thenExcludeNonSdkTraces() { | ||
| String workspaceName = UUID.randomUUID().toString(); |
There was a problem hiding this comment.
getProjectStats__whenSourceFilterApplied__thenExcludeNonSdkTraces uses underscores and violates the test-naming rules, should we rename it to camelCase like whenSourceFilterAppliedThenExcludeNonSdkTraces?
Finding type: AI Coding Guidelines | Severity: 🟢 Low
Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents:
Before applying, verify this suggestion against the current code. In
apps/opik-backend/src/test/java/com/comet/opik/api/resources/v1/priv/ProjectsResourceTest.java
around lines 1960-1963, the test method
getProjectStats__whenSourceFilterApplied__thenExcludeNonSdkTraces uses underscores and
violates the project testing naming rules. Rename the method to camelCase scenario
style, e.g. whenSourceFilterAppliedThenExcludeNonSdkTraces, updating the method
declaration accordingly (keep the existing @DisplayName as-is). Ensure there are no
other references to the old name in the file and run tests to confirm no breakage.
There was a problem hiding this comment.
Skipping — the naming convention getProjectStats__whenSourceFilterApplied__thenExcludeNonSdkTraces is consistent with other existing tests in this class and across the backend test suite.
🤖 Reply posted via /address-github-pr-comments
There was a problem hiding this comment.
Got it, thanks for clarifying the existing naming convention—I'll keep this in mind and save it to memory once the PR is merged.
| @NonNull String workspaceId, List<? extends Filter> filters) { | ||
|
|
||
| if (projectIds.isEmpty()) { | ||
| return Mono.just(Map.of()); |
There was a problem hiding this comment.
if (!CollectionUtils.isEmpty(filters)) { FilterQueryBuilder.toAnalyticsDbFilters(...FilterStrategy.TRACE) duplicates ProjectMetricsDAO's traceFilters(); should we extract a shared helper like applyTraceFilters(template, statement, filters)?
if (!CollectionUtils.isEmpty(filters)) { FilterQueryBuilder.toAnalyticsDbFilters(...FilterStrategy.TRACE) => applyTraceFilters(template, statement, filters)
Finding type: Code Dedup and Conventions | Severity: 🟢 Low
Want Baz to fix this for you? Activate Fixer
There was a problem hiding this comment.
Skipping — extracting a shared helper for two call sites would be premature abstraction. The pattern is straightforward and the duplication is minimal.
🤖 Reply posted via /address-github-pr-comments
There was a problem hiding this comment.
Got it, that makes sense—avoiding premature abstraction here is reasonable. I’ll remember this preference for similar code dedup suggestions after the PR is merged.
| @QueryParam("page") @Min(1) @DefaultValue("1") int page, | ||
| @QueryParam("size") @Min(1) @DefaultValue(PAGE_SIZE) int size, | ||
| @QueryParam("name") @Schema(description = "Filter projects by name (partial match, case insensitive)") String name, | ||
| @QueryParam("filters") String filters, | ||
| @QueryParam("sorting") String sorting) { |
There was a problem hiding this comment.
filters query param is undocumented in both @Schema annotation and openapi.yaml — should we add @Schema metadata (description, example, pattern) and update the OpenAPI spec so SDK regeneration picks it up?
Finding types: API design consistency Breaking Changes | Severity: 🟠 Medium
Want Baz to fix this for you? Activate Fixer
Other fix methods
Prompt for AI Agents:
Before applying, verify this suggestion against the current code. In
apps/opik-backend/src/main/java/com/comet/opik/api/resources/v1/priv/ProjectsResource.java
around lines 343-347, the getProjectStats method adds a @QueryParam("filters") String
filters parameter but it has no OpenAPI/Schema metadata and is missing from the OpenAPI
spec. First, annotate this parameter with @Schema describing the expected format and
semantics (for example: whether it is a JSON-encoded filter object, a comma-separated
list, or a DSL), include an example (and a pattern if applicable), and keep the existing
parameter name and type (String). Ensure the new annotation follows the style of the
existing @Schema on the 'name' parameter. Second, update
sdks/code_generation/fern/openapi/openapi.yaml to add a new query parameter named
"filters" to the GET /v1/private/projects/stats operation with type string and a brief
description (e.g. "Serialized filters for project stats (format documented)"). Also add
a developer note in the OpenAPI file or repo docs indicating that SDKs and generated
clients must be regenerated after this change and run API compatibility tests; then run
the OpenAPI validation/linting and regenerate the SDKs to ensure the spec and clients
stay in sync.
There was a problem hiding this comment.
Skipping — the OpenAPI spec and SDK bindings will be updated automatically once the Fern automation runs after merge.
🤖 Reply posted via /address-github-pr-comments
There was a problem hiding this comment.
Got it, thanks for clarifying that Fern automation will handle the OpenAPI spec and SDK updates—makes sense to skip manual changes here.
Details
Add
filtersquery parameter support toGET /projects/statsendpoint so callers can filter the aggregated project statistics by trace source. This allows excluding non-SDK traces (experiment, playground, optimization) from project stats, which is useful for displaying clean user-initiated statistics in the v2 Projects page.Changes:
filtersquery param (String) toGET /projects/statsREST endpointProjectCriteriarecord to holdList<? extends Filter>instead of a singlesourcefieldProjectService.getProjectStatsto pass filters through to the DAOTraceDAO.getStatsByProjectIdsto accept and applyList<TraceFilter>using the existingFilterQueryBuilder/FilterStrategy.TRACEmechanismgetProjectStats__whenSourceFilterApplied__thenExcludeNonSdkTracesinsideProjectErrorCountTestsChange checklist
Issues
AI-WATERMARK
AI-WATERMARK: yes
Testing
mvn test -Dtest="ProjectsResourceTest#getProjectStats__whenSourceFilterApplied__thenExcludeNonSdkTraces"— passes ✅mvn spotless:check— passes ✅filtersquery param matching existing filter API conventionsDocumentation
N/A — internal API change, no user-facing docs needed.