Add group dimension and filter to DuoWorkflows engine
What does this MR do and why?
Adds a group dimension and a groupId filter to the Analytics::AggregationEngines::DuoWorkflows ClickHouse aggregation engine, which backs the duoWorkflows GraphQL field.
The group dimension takes a depth argument. Depth 1, the default, buckets by top-level group, depth 2 by subgroup, and so on. It reads the engine's existing organization-scoped traversal_path column and resolves to a Group record. The association uses a finder of Group.id_in(ids).with_route together with Preloaders::GroupPolicyPreloader, so resolving it does not run a route or policy query per row.
The groupId filter accepts one or more Group Global IDs. A flow matches if it belongs to the group or to any of its descendants, subgroup or project. It renders OR-ed startsWith conditions on traversal_path. The table's sort key is (traversal_path, created_at, id), so those conditions get granule pruning.
Both reuse framework classes instead of adding engine-specific SQL. There is no ClickHouse migration and no GraphQL resolver change.
Why
The Group snapshot section of the DAP Impact Dashboard v1 needs flows per group and credits per group, and the dashboard needs a group and project scope selector. Today per-group numbers take one request per group, capped at 20 groups. One request now covers any number of groups.
Testing
14 examples added to ee/spec/models/analytics/aggregation_engines/duo_workflows_spec.rb. For the dimension: default depth, a requested depth, a depth past the hierarchy, the project-namespace bucket, credits summed per group, combined with the created_at date bucket, the group association request form, and a depth validation error. For the filter: a single group with its descendants, a subgroup subtree, multiple groups, combined with the dimension, no match, and non-Group Global IDs dropped.
3 examples added to ee/spec/requests/api/graphql/analytics/duo_workflows_spec.rb covering the field end to end, including a query-count example that guards the preloader.
All examples across both files pass locally and RuboCop is clean. doc/api/graphql/reference/_index.md and public/-/graphql/introspection_result.json are regenerated.
No Changelog trailer: duoWorkflows is behind the dap_impact_v1 feature flag and marked experiment: { milestone: '19.4' }, so nothing user-facing changes yet.
References
Screenshots or screen recordings
Backend and GraphQL only, so there are none.
How to set up and validate locally
bundle exec rspec ee/spec/models/analytics/aggregation_engines/duo_workflows_spec.rb --tag click_house
bundle exec rspec ee/spec/requests/api/graphql/analytics/duo_workflows_spec.rb --tag click_house- Enable ClickHouse for analytics in GDK.
- Enable the
dap_impact_v1feature flag. - Create some flows in a project inside a subgroup.
- Open the GraphQL explorer at
http://gdk.test:3000/-/graphql-explorer. - Run the query below, replacing
<subgroup-id>with the ID of a subgroup ofgitlab-org.
query {
group(fullPath: "gitlab-org") {
analytics {
duoWorkflows(groupId: ["gid://gitlab/Group/<subgroup-id>"]) {
aggregated {
nodes {
dimensions { group(depth: 2) { id fullPath } }
totalCount
creditsUsed { sum }
}
}
}
}
}
}Flows from the subgroup's descendant projects are counted under the subgroup, and flows outside that subtree are excluded.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.