From fed95ecadd02dc1fcd4107866fa78167d68dfeaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Tue, 30 Jun 2026 16:25:21 +0200 Subject: [PATCH 01/11] feat(issue): add facets to IssueConnection Introduces facets for the team issues query, following the SQL-aggregate pattern used by the activity log. Facets provide distribution counts across four dimensions to help narrow down results: - environments - severities - resourceTypes - issueTypes A new FacetsForIssues SQL query computes counts grouped by (severity, resource_type, env, issue_type) using a FILTER WHERE clause so that all possible values are seeded (with count 0 if unmatched) and the filtered counts reflect the current active filter. --- internal/issue/facets.go | 103 +++++++++++++++++++++++++++ internal/issue/facets_test.go | 101 ++++++++++++++++++++++++++ internal/issue/issuesql/issue.sql.go | 98 +++++++++++++++++++++++++ internal/issue/issuesql/querier.go | 1 + internal/issue/model.go | 35 ++++++++- internal/issue/queries.go | 13 +++- internal/issue/queries/issue.sql | 46 ++++++++++++ 7 files changed, 393 insertions(+), 4 deletions(-) create mode 100644 internal/issue/facets.go create mode 100644 internal/issue/facets_test.go diff --git a/internal/issue/facets.go b/internal/issue/facets.go new file mode 100644 index 000000000..5f969f526 --- /dev/null +++ b/internal/issue/facets.go @@ -0,0 +1,103 @@ +package issue + +import ( + "context" + "slices" + "strings" + + "github.com/nais/api/internal/graph/model" + "github.com/nais/api/internal/issue/issuesql" + "github.com/nais/api/internal/slug" +) + +func ComputeFacets(ctx context.Context, teamSlug slug.Slug, filter *IssueFilter) (*IssueFacets, error) { + params := issuesql.FacetsForIssuesParams{ + Team: teamSlug.String(), + } + + if filter != nil { + params.Env = filter.Environments + params.ResourceType = (*string)(filter.ResourceType) + params.IssueType = (*string)(filter.IssueType) + params.ResourceName = filter.ResourceName + if filter.Severity != nil { + params.Severity = new(issuesql.SeverityLevel(*filter.Severity)) + } + } + + rows, err := db(ctx).FacetsForIssues(ctx, params) + if err != nil { + return nil, err + } + + return buildFacets(rows), nil +} + +func buildFacets(rows []*issuesql.FacetsForIssuesRow) *IssueFacets { + severityCounts := map[Severity]int{} + resourceTypeCounts := map[ResourceType]int{} + environmentCounts := map[string]int{} + issueTypeCounts := map[IssueType]int{} + + for _, row := range rows { + sev := Severity(row.Severity) + rt := ResourceType(row.ResourceType) + it := IssueType(row.IssueType) + + if _, ok := severityCounts[sev]; !ok { + severityCounts[sev] = 0 + } + if _, ok := resourceTypeCounts[rt]; !ok { + resourceTypeCounts[rt] = 0 + } + if _, ok := environmentCounts[row.Env]; !ok { + environmentCounts[row.Env] = 0 + } + if _, ok := issueTypeCounts[it]; !ok { + issueTypeCounts[it] = 0 + } + + filtered := int(row.FilteredCount) + severityCounts[sev] += filtered + resourceTypeCounts[rt] += filtered + environmentCounts[row.Env] += filtered + issueTypeCounts[it] += filtered + } + + severities := make([]SeverityFacetItem, 0, len(severityCounts)) + for sev, count := range severityCounts { + severities = append(severities, SeverityFacetItem{Severity: sev, Count: count}) + } + slices.SortFunc(severities, func(a, b SeverityFacetItem) int { + return strings.Compare(a.Severity.String(), b.Severity.String()) + }) + + resourceTypes := make([]ResourceTypeFacetItem, 0, len(resourceTypeCounts)) + for rt, count := range resourceTypeCounts { + resourceTypes = append(resourceTypes, ResourceTypeFacetItem{ResourceType: rt, Count: count}) + } + slices.SortFunc(resourceTypes, func(a, b ResourceTypeFacetItem) int { + return strings.Compare(a.ResourceType.String(), b.ResourceType.String()) + }) + + environments := make([]model.StringFacetItem, 0, len(environmentCounts)) + for env, count := range environmentCounts { + environments = append(environments, model.StringFacetItem{Value: env, Count: count}) + } + model.SortStringFacetItems(environments) + + issueTypes := make([]IssueTypeFacetItem, 0, len(issueTypeCounts)) + for it, count := range issueTypeCounts { + issueTypes = append(issueTypes, IssueTypeFacetItem{IssueType: it, Count: count}) + } + slices.SortFunc(issueTypes, func(a, b IssueTypeFacetItem) int { + return strings.Compare(a.IssueType.String(), b.IssueType.String()) + }) + + return &IssueFacets{ + Environments: environments, + Severities: severities, + ResourceTypes: resourceTypes, + IssueTypes: issueTypes, + } +} diff --git a/internal/issue/facets_test.go b/internal/issue/facets_test.go new file mode 100644 index 000000000..1211810f7 --- /dev/null +++ b/internal/issue/facets_test.go @@ -0,0 +1,101 @@ +package issue + +import ( + "reflect" + "testing" + + "github.com/nais/api/internal/graph/model" + "github.com/nais/api/internal/issue/issuesql" +) + +func TestBuildFacets(t *testing.T) { + rows := []*issuesql.FacetsForIssuesRow{ + {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "prod", IssueType: "DEPRECATED_INGRESS", TotalCount: 3, FilteredCount: 3}, + {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "dev", IssueType: "DEPRECATED_INGRESS", TotalCount: 1, FilteredCount: 1}, + {Severity: "WARNING", ResourceType: "JOB", Env: "prod", IssueType: "LAST_RUN_FAILED", TotalCount: 2, FilteredCount: 2}, + {Severity: "TODO", ResourceType: "SQLINSTANCE", Env: "prod", IssueType: "SQLINSTANCE_VERSION", TotalCount: 1, FilteredCount: 0}, + } + + tests := []struct { + name string + rows []*issuesql.FacetsForIssuesRow + wantSeverities []SeverityFacetItem + wantResourceTypes []ResourceTypeFacetItem + wantEnvironments []model.StringFacetItem + wantIssueTypes []IssueTypeFacetItem + }{ + { + name: "no filter: filtered_count equals total_count", + rows: rows, + wantSeverities: []SeverityFacetItem{ + {Severity: SeverityCritical, Count: 4}, + {Severity: SeverityTodo, Count: 0}, + {Severity: SeverityWarning, Count: 2}, + }, + wantResourceTypes: []ResourceTypeFacetItem{ + {ResourceType: ResourceTypeApplication, Count: 4}, + {ResourceType: ResourceTypeJob, Count: 2}, + {ResourceType: ResourceTypeSQLInstance, Count: 0}, + }, + wantEnvironments: []model.StringFacetItem{ + {Value: "dev", Count: 1}, + {Value: "prod", Count: 5}, + }, + wantIssueTypes: []IssueTypeFacetItem{ + {IssueType: IssueTypeDeprecatedIngress, Count: 4}, + {IssueType: IssueTypeLastRunFailed, Count: 2}, + {IssueType: IssueTypeSqlInstanceVersion, Count: 0}, + }, + }, + { + name: "with filter: TODO row has filtered_count=0 but is still seeded", + rows: []*issuesql.FacetsForIssuesRow{ + {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "prod", IssueType: "DEPRECATED_INGRESS", TotalCount: 3, FilteredCount: 3}, + {Severity: "WARNING", ResourceType: "JOB", Env: "dev", IssueType: "LAST_RUN_FAILED", TotalCount: 1, FilteredCount: 0}, + }, + wantSeverities: []SeverityFacetItem{ + {Severity: SeverityCritical, Count: 3}, + {Severity: SeverityWarning, Count: 0}, + }, + wantResourceTypes: []ResourceTypeFacetItem{ + {ResourceType: ResourceTypeApplication, Count: 3}, + {ResourceType: ResourceTypeJob, Count: 0}, + }, + wantEnvironments: []model.StringFacetItem{ + {Value: "dev", Count: 0}, + {Value: "prod", Count: 3}, + }, + wantIssueTypes: []IssueTypeFacetItem{ + {IssueType: IssueTypeDeprecatedIngress, Count: 3}, + {IssueType: IssueTypeLastRunFailed, Count: 0}, + }, + }, + { + name: "empty rows returns empty facets", + rows: nil, + wantSeverities: []SeverityFacetItem{}, + wantResourceTypes: []ResourceTypeFacetItem{}, + wantEnvironments: []model.StringFacetItem{}, + wantIssueTypes: []IssueTypeFacetItem{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := buildFacets(tt.rows) + + if !reflect.DeepEqual(got.Severities, tt.wantSeverities) { + t.Errorf("Severities =\n %v\nwant\n %v", got.Severities, tt.wantSeverities) + } + if !reflect.DeepEqual(got.ResourceTypes, tt.wantResourceTypes) { + t.Errorf("ResourceTypes =\n %v\nwant\n %v", got.ResourceTypes, tt.wantResourceTypes) + } + if !reflect.DeepEqual(got.Environments, tt.wantEnvironments) { + t.Errorf("Environments =\n %v\nwant\n %v", got.Environments, tt.wantEnvironments) + } + if !reflect.DeepEqual(got.IssueTypes, tt.wantIssueTypes) { + t.Errorf("IssueTypes =\n %v\nwant\n %v", got.IssueTypes, tt.wantIssueTypes) + } + }) + } +} diff --git a/internal/issue/issuesql/issue.sql.go b/internal/issue/issuesql/issue.sql.go index 8cf588b2d..123a432a3 100644 --- a/internal/issue/issuesql/issue.sql.go +++ b/internal/issue/issuesql/issue.sql.go @@ -10,6 +10,104 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +const facetsForIssues = `-- name: FacetsForIssues :many +SELECT + severity, + resource_type, + env, + issue_type, + COUNT(*) AS total_count, + COUNT(*) FILTER ( + WHERE + ( + $1::TEXT[] IS NULL + OR env = ANY ($1::TEXT[]) + ) + AND ( + $2::TEXT IS NULL + OR issue_type = $2::TEXT + ) + AND ( + $3::severity_level IS NULL + OR severity = $3::severity_level + ) + AND ( + $4::TEXT IS NULL + OR resource_type = $4::TEXT + ) + AND ( + $5::TEXT IS NULL + OR resource_name = $5::TEXT + ) + ) AS filtered_count +FROM + issues +WHERE + team = $6 +GROUP BY + severity, + resource_type, + env, + issue_type +ORDER BY + severity, + resource_type, + env, + issue_type +` + +type FacetsForIssuesParams struct { + Env []string + IssueType *string + Severity *SeverityLevel + ResourceType *string + ResourceName *string + Team string +} + +type FacetsForIssuesRow struct { + Severity SeverityLevel + ResourceType string + Env string + IssueType string + TotalCount int64 + FilteredCount int64 +} + +func (q *Queries) FacetsForIssues(ctx context.Context, arg FacetsForIssuesParams) ([]*FacetsForIssuesRow, error) { + rows, err := q.db.Query(ctx, facetsForIssues, + arg.Env, + arg.IssueType, + arg.Severity, + arg.ResourceType, + arg.ResourceName, + arg.Team, + ) + if err != nil { + return nil, err + } + defer rows.Close() + items := []*FacetsForIssuesRow{} + for rows.Next() { + var i FacetsForIssuesRow + if err := rows.Scan( + &i.Severity, + &i.ResourceType, + &i.Env, + &i.IssueType, + &i.TotalCount, + &i.FilteredCount, + ); err != nil { + return nil, err + } + items = append(items, &i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const getIssueByID = `-- name: GetIssueByID :one SELECT id, issue_type, resource_name, resource_type, team, env, severity, message, issue_details, created_at diff --git a/internal/issue/issuesql/querier.go b/internal/issue/issuesql/querier.go index a9e20b561..96a86d9bb 100644 --- a/internal/issue/issuesql/querier.go +++ b/internal/issue/issuesql/querier.go @@ -9,6 +9,7 @@ import ( ) type Querier interface { + FacetsForIssues(ctx context.Context, arg FacetsForIssuesParams) ([]*FacetsForIssuesRow, error) GetIssueByID(ctx context.Context, id uuid.UUID) (*Issue, error) GetSeverityScoreForWorkload(ctx context.Context, arg GetSeverityScoreForWorkloadParams) (int64, error) ListIssues(ctx context.Context, arg ListIssuesParams) ([]*ListIssuesRow, error) diff --git a/internal/issue/model.go b/internal/issue/model.go index b6ebf41b1..db358c825 100644 --- a/internal/issue/model.go +++ b/internal/issue/model.go @@ -266,10 +266,41 @@ func (e IssueType) MarshalGQL(w io.Writer) { } type ( - IssueConnection = pagination.Connection[Issue] - IssueEdge = pagination.Edge[Issue] + IssueEdge = pagination.Edge[Issue] ) +type IssueConnection struct { + pagination.Connection[Issue] + + teamSlug slug.Slug + filter *IssueFilter +} + +func (c *IssueConnection) GetTeamSlug() slug.Slug { return c.teamSlug } +func (c *IssueConnection) GetFilter() *IssueFilter { return c.filter } + +type IssueFacets struct { + Environments []model.StringFacetItem `json:"environments"` + Severities []SeverityFacetItem `json:"severities"` + ResourceTypes []ResourceTypeFacetItem `json:"resourceTypes"` + IssueTypes []IssueTypeFacetItem `json:"issueTypes"` +} + +type SeverityFacetItem struct { + Severity Severity `json:"severity"` + Count int `json:"count"` +} + +type ResourceTypeFacetItem struct { + ResourceType ResourceType `json:"resourceType"` + Count int `json:"count"` +} + +type IssueTypeFacetItem struct { + IssueType IssueType `json:"issueType"` + Count int `json:"count"` +} + type IssueOrder struct { // Order by this field. Field IssueOrderField `json:"field"` diff --git a/internal/issue/queries.go b/internal/issue/queries.go index 70bb4307b..128b3abde 100644 --- a/internal/issue/queries.go +++ b/internal/issue/queries.go @@ -43,7 +43,7 @@ func GetByIdent(ctx context.Context, id ident.Ident) (Issue, error) { return convert(issue) } -func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, filter *IssueFilter) (*pagination.Connection[Issue], error) { +func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, filter *IssueFilter) (*IssueConnection, error) { params := issuesql.ListIssuesParams{ Team: teamSlug.String(), Offset: page.Offset(), @@ -71,7 +71,7 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina total = ret[0].TotalCount } - return pagination.NewConvertConnectionWithError(ret, page, total, func(from *issuesql.ListIssuesRow) (Issue, error) { + conn, err := pagination.NewConvertConnectionWithError(ret, page, total, func(from *issuesql.ListIssuesRow) (Issue, error) { iss := &issuesql.Issue{ ID: from.ID, IssueType: from.IssueType, @@ -86,6 +86,15 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina } return convert(iss) }) + if err != nil { + return nil, err + } + + return &IssueConnection{ + Connection: *conn, + teamSlug: teamSlug, + filter: filter, + }, nil } func convert(issue *issuesql.Issue) (Issue, error) { diff --git a/internal/issue/queries/issue.sql b/internal/issue/queries/issue.sql index 036cecfd0..7094ad820 100644 --- a/internal/issue/queries/issue.sql +++ b/internal/issue/queries/issue.sql @@ -92,3 +92,49 @@ OFFSET LIMIT sqlc.arg('limit') ; + +-- name: FacetsForIssues :many +SELECT + severity, + resource_type, + env, + issue_type, + COUNT(*) AS total_count, + COUNT(*) FILTER ( + WHERE + ( + sqlc.narg('env')::TEXT[] IS NULL + OR env = ANY (sqlc.narg('env')::TEXT[]) + ) + AND ( + sqlc.narg('issue_type')::TEXT IS NULL + OR issue_type = sqlc.narg('issue_type')::TEXT + ) + AND ( + sqlc.narg('severity')::severity_level IS NULL + OR severity = sqlc.narg('severity')::severity_level + ) + AND ( + sqlc.narg('resource_type')::TEXT IS NULL + OR resource_type = sqlc.narg('resource_type')::TEXT + ) + AND ( + sqlc.narg('resource_name')::TEXT IS NULL + OR resource_name = sqlc.narg('resource_name')::TEXT + ) + ) AS filtered_count +FROM + issues +WHERE + team = @team +GROUP BY + severity, + resource_type, + env, + issue_type +ORDER BY + severity, + resource_type, + env, + issue_type +; From 688383d09923e9b1c474e140724a4cc93e8d8807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Tue, 30 Jun 2026 16:25:33 +0200 Subject: [PATCH 02/11] feat(graph): expose issue facets in GraphQL schema Adds IssueFacets type to IssueConnection with four fields: environments, severities, resourceTypes, issueTypes Each field returns a list of facet items with count of matching issues. Counts respect the current filter but are computed across the full (unpaginated) result set. New GraphQL types: IssueFacets, SeverityFacetItem, ResourceTypeFacetItem, IssueTypeFacetItem All Issues resolvers (team + resource-level) now return *issue.IssueConnection so the connection carries the team slug and filter needed for lazy facet computation. --- internal/graph/applications.resolvers.go | 2 +- .../graph/gengql/applications.generated.go | 6 +- internal/graph/gengql/issues.generated.go | 626 +++++++++++++++++- internal/graph/gengql/jobs.generated.go | 6 +- internal/graph/gengql/opensearch.generated.go | 6 +- internal/graph/gengql/root_.generated.go | 211 ++++++ .../graph/gengql/sqlinstance.generated.go | 6 +- internal/graph/gengql/teams.generated.go | 6 +- internal/graph/gengql/valkey.generated.go | 6 +- internal/graph/issues.resolvers.go | 11 +- internal/graph/jobs.resolvers.go | 2 +- internal/graph/opensearch.resolvers.go | 2 +- internal/graph/schema/issues.graphqls | 64 ++ internal/graph/sqlinstance.resolvers.go | 2 +- internal/graph/valkey.resolvers.go | 2 +- 15 files changed, 925 insertions(+), 33 deletions(-) diff --git a/internal/graph/applications.resolvers.go b/internal/graph/applications.resolvers.go index 2040f038f..72d8d2318 100644 --- a/internal/graph/applications.resolvers.go +++ b/internal/graph/applications.resolvers.go @@ -75,7 +75,7 @@ func (r *applicationResolver) State(ctx context.Context, obj *application.Applic return application.GetState(ctx, obj) } -func (r *applicationResolver) Issues(ctx context.Context, obj *application.Application, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) { +func (r *applicationResolver) Issues(ctx context.Context, obj *application.Application, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err diff --git a/internal/graph/gengql/applications.generated.go b/internal/graph/gengql/applications.generated.go index 8decf3265..d6441ecaa 100644 --- a/internal/graph/gengql/applications.generated.go +++ b/internal/graph/gengql/applications.generated.go @@ -55,7 +55,7 @@ type ApplicationResolver interface { ActivityLog(ctx context.Context, obj *application.Application, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *activitylog.ActivityLogFilter) (*activitylog.ActivityLogEntryConnection, error) State(ctx context.Context, obj *application.Application) (application.ApplicationState, error) - Issues(ctx context.Context, obj *application.Application, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) + Issues(ctx context.Context, obj *application.Application, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) History(ctx context.Context, obj *application.Application) ([]*instancegroup.ApplicationHistory, error) BigQueryDatasets(ctx context.Context, obj *application.Application, orderBy *bigquery.BigQueryDatasetOrder) (*pagination.FacetableConnection[*bigquery.BigQueryDataset, *bigquery.BigQueryDatasetFilter], error) Buckets(ctx context.Context, obj *application.Application, orderBy *bucket.BucketOrder) (*pagination.FacetableConnection[*bucket.Bucket, *bucket.BucketFilter], error) @@ -945,8 +945,8 @@ func (ec *executionContext) _Application_issues(ctx context.Context, field graph return ec.Resolvers.Application().Issues(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*issue.IssueOrder), fc.Args["filter"].(*issue.ResourceIssueFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[issue.Issue]) graphql.Marshaler { - return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *issue.IssueConnection) graphql.Marshaler { + return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx, selections, v) }, true, true, diff --git a/internal/graph/gengql/issues.generated.go b/internal/graph/gengql/issues.generated.go index 2613870d4..025896d31 100644 --- a/internal/graph/gengql/issues.generated.go +++ b/internal/graph/gengql/issues.generated.go @@ -13,6 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/graph/ident" + "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/graph/scalar" "github.com/nais/api/internal/issue" @@ -59,6 +60,9 @@ type InvalidSpecIssueResolver interface { Workload(ctx context.Context, obj *issue.InvalidSpecIssue) (workload.Workload, error) } +type IssueConnectionResolver interface { + Facets(ctx context.Context, obj *issue.IssueConnection) (*issue.IssueFacets, error) +} type LastRunFailedIssueResolver interface { TeamEnvironment(ctx context.Context, obj *issue.LastRunFailedIssue) (*team.TeamEnvironment, error) @@ -1058,7 +1062,7 @@ func (ec *executionContext) fieldContext_InvalidSpecIssue_workload(_ context.Con return fc, nil } -func (ec *executionContext) _IssueConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.Connection[issue.Issue]) (ret graphql.Marshaler) { +func (ec *executionContext) _IssueConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *issue.IssueConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -1090,7 +1094,7 @@ func (ec *executionContext) fieldContext_IssueConnection_pageInfo(_ context.Cont return fc, nil } -func (ec *executionContext) _IssueConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *pagination.Connection[issue.Issue]) (ret graphql.Marshaler) { +func (ec *executionContext) _IssueConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *issue.IssueConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -1122,7 +1126,7 @@ func (ec *executionContext) fieldContext_IssueConnection_nodes(_ context.Context return fc, nil } -func (ec *executionContext) _IssueConnection_edges(ctx context.Context, field graphql.CollectedField, obj *pagination.Connection[issue.Issue]) (ret graphql.Marshaler) { +func (ec *executionContext) _IssueConnection_edges(ctx context.Context, field graphql.CollectedField, obj *issue.IssueConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -1154,6 +1158,38 @@ func (ec *executionContext) fieldContext_IssueConnection_edges(_ context.Context return fc, nil } +func (ec *executionContext) _IssueConnection_facets(ctx context.Context, field graphql.CollectedField, obj *issue.IssueConnection) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueConnection_facets(ctx, field) + }, + func(ctx context.Context) (any, error) { + return ec.Resolvers.IssueConnection().Facets(ctx, obj) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *issue.IssueFacets) graphql.Marshaler { + return ec.marshalOIssueFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueFacets(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_IssueConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "IssueConnection", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_IssueFacets(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _IssueEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[issue.Issue]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1209,6 +1245,180 @@ func (ec *executionContext) fieldContext_IssueEdge_node(_ context.Context, field return fc, nil } +func (ec *executionContext) _IssueFacets_environments(ctx context.Context, field graphql.CollectedField, obj *issue.IssueFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueFacets_environments(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Environments, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { + return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "IssueFacets", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_StringFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _IssueFacets_severities(ctx context.Context, field graphql.CollectedField, obj *issue.IssueFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueFacets_severities(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Severities, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []issue.SeverityFacetItem) graphql.Marshaler { + return ec.marshalNSeverityFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueFacets_severities(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "IssueFacets", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_SeverityFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _IssueFacets_resourceTypes(ctx context.Context, field graphql.CollectedField, obj *issue.IssueFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueFacets_resourceTypes(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ResourceTypes, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []issue.ResourceTypeFacetItem) graphql.Marshaler { + return ec.marshalNResourceTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueFacets_resourceTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "IssueFacets", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ResourceTypeFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _IssueFacets_issueTypes(ctx context.Context, field graphql.CollectedField, obj *issue.IssueFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueFacets_issueTypes(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.IssueTypes, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []issue.IssueTypeFacetItem) graphql.Marshaler { + return ec.marshalNIssueTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueFacets_issueTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "IssueFacets", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_IssueTypeFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _IssueTypeFacetItem_issueType(ctx context.Context, field graphql.CollectedField, obj *issue.IssueTypeFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueTypeFacetItem_issueType(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.IssueType, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v issue.IssueType) graphql.Marshaler { + return ec.marshalNIssueType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueType(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueTypeFacetItem_issueType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("IssueTypeFacetItem", field, false, false, errors.New("field of type IssueType does not have child fields")) +} + +func (ec *executionContext) _IssueTypeFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *issue.IssueTypeFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueTypeFacetItem_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("IssueTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +} + func (ec *executionContext) _LastRunFailedIssue_id(ctx context.Context, field graphql.CollectedField, obj *issue.LastRunFailedIssue) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1764,6 +1974,98 @@ func (ec *executionContext) fieldContext_OpenSearchIssue_event(_ context.Context return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ResourceTypeFacetItem_resourceType(ctx context.Context, field graphql.CollectedField, obj *issue.ResourceTypeFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ResourceTypeFacetItem_resourceType(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ResourceType, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v issue.ResourceType) graphql.Marshaler { + return ec.marshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ResourceTypeFacetItem_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("ResourceTypeFacetItem", field, false, false, errors.New("field of type ResourceType does not have child fields")) +} + +func (ec *executionContext) _ResourceTypeFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *issue.ResourceTypeFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ResourceTypeFacetItem_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_ResourceTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("ResourceTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +} + +func (ec *executionContext) _SeverityFacetItem_severity(ctx context.Context, field graphql.CollectedField, obj *issue.SeverityFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SeverityFacetItem_severity(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Severity, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v issue.Severity) graphql.Marshaler { + return ec.marshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SeverityFacetItem_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("SeverityFacetItem", field, false, false, errors.New("field of type Severity does not have child fields")) +} + +func (ec *executionContext) _SeverityFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *issue.SeverityFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SeverityFacetItem_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_SeverityFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("SeverityFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +} + func (ec *executionContext) _SqlInstanceStateIssue_id(ctx context.Context, field graphql.CollectedField, obj *issue.SqlInstanceStateIssue) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3819,7 +4121,7 @@ func (ec *executionContext) _InvalidSpecIssue(ctx context.Context, sel ast.Selec var issueConnectionImplementors = []string{"IssueConnection"} -func (ec *executionContext) _IssueConnection(ctx context.Context, sel ast.SelectionSet, obj *pagination.Connection[issue.Issue]) graphql.Marshaler { +func (ec *executionContext) _IssueConnection(ctx context.Context, sel ast.SelectionSet, obj *issue.IssueConnection) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, issueConnectionImplementors) out := graphql.NewFieldSet(fields) @@ -3831,18 +4133,51 @@ func (ec *executionContext) _IssueConnection(ctx context.Context, sel ast.Select case "pageInfo": out.Values[i] = ec._IssueConnection_pageInfo(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "nodes": out.Values[i] = ec._IssueConnection_nodes(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "edges": out.Values[i] = ec._IssueConnection_edges(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) + } + case "facets": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._IssueConnection_facets(ctx, field, obj) + return res } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3910,6 +4245,104 @@ func (ec *executionContext) _IssueEdge(ctx context.Context, sel ast.SelectionSet return out } +var issueFacetsImplementors = []string{"IssueFacets"} + +func (ec *executionContext) _IssueFacets(ctx context.Context, sel ast.SelectionSet, obj *issue.IssueFacets) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, issueFacetsImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("IssueFacets") + case "environments": + out.Values[i] = ec._IssueFacets_environments(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "severities": + out.Values[i] = ec._IssueFacets_severities(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceTypes": + out.Values[i] = ec._IssueFacets_resourceTypes(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "issueTypes": + out.Values[i] = ec._IssueFacets_issueTypes(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var issueTypeFacetItemImplementors = []string{"IssueTypeFacetItem"} + +func (ec *executionContext) _IssueTypeFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.IssueTypeFacetItem) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, issueTypeFacetItemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("IssueTypeFacetItem") + case "issueType": + out.Values[i] = ec._IssueTypeFacetItem_issueType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "count": + out.Values[i] = ec._IssueTypeFacetItem_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var lastRunFailedIssueImplementors = []string{"LastRunFailedIssue", "Issue", "Node"} func (ec *executionContext) _LastRunFailedIssue(ctx context.Context, sel ast.SelectionSet, obj *issue.LastRunFailedIssue) graphql.Marshaler { @@ -4399,6 +4832,94 @@ func (ec *executionContext) _OpenSearchIssue(ctx context.Context, sel ast.Select return out } +var resourceTypeFacetItemImplementors = []string{"ResourceTypeFacetItem"} + +func (ec *executionContext) _ResourceTypeFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.ResourceTypeFacetItem) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, resourceTypeFacetItemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ResourceTypeFacetItem") + case "resourceType": + out.Values[i] = ec._ResourceTypeFacetItem_resourceType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "count": + out.Values[i] = ec._ResourceTypeFacetItem_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var severityFacetItemImplementors = []string{"SeverityFacetItem"} + +func (ec *executionContext) _SeverityFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.SeverityFacetItem) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, severityFacetItemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("SeverityFacetItem") + case "severity": + out.Values[i] = ec._SeverityFacetItem_severity(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "count": + out.Values[i] = ec._SeverityFacetItem_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var sqlInstanceStateIssueImplementors = []string{"SqlInstanceStateIssue", "Issue", "Node"} func (ec *executionContext) _SqlInstanceStateIssue(ctx context.Context, sel ast.SelectionSet, obj *issue.SqlInstanceStateIssue) graphql.Marshaler { @@ -5199,11 +5720,11 @@ func (ec *executionContext) marshalNIssue2ᚕgithubᚗcomᚋnaisᚋapiᚋinterna return ret } -func (ec *executionContext) marshalNIssueConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx context.Context, sel ast.SelectionSet, v pagination.Connection[issue.Issue]) graphql.Marshaler { +func (ec *executionContext) marshalNIssueConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx context.Context, sel ast.SelectionSet, v issue.IssueConnection) graphql.Marshaler { return ec._IssueConnection(ctx, sel, &v) } -func (ec *executionContext) marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx context.Context, sel ast.SelectionSet, v *pagination.Connection[issue.Issue]) graphql.Marshaler { +func (ec *executionContext) marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx context.Context, sel ast.SelectionSet, v *issue.IssueConnection) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") @@ -5243,6 +5764,66 @@ func (ec *executionContext) marshalNIssueOrderField2githubᚗcomᚋnaisᚋapiᚋ return v } +func (ec *executionContext) unmarshalNIssueType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueType(ctx context.Context, v any) (issue.IssueType, error) { + var res issue.IssueType + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNIssueType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueType(ctx context.Context, sel ast.SelectionSet, v issue.IssueType) graphql.Marshaler { + return v +} + +func (ec *executionContext) marshalNIssueTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.IssueTypeFacetItem) graphql.Marshaler { + return ec._IssueTypeFacetItem(ctx, sel, &v) +} + +func (ec *executionContext) marshalNIssueTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.IssueTypeFacetItem) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNIssueTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItem(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx context.Context, v any) (issue.ResourceType, error) { + var res issue.ResourceType + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx context.Context, sel ast.SelectionSet, v issue.ResourceType) graphql.Marshaler { + return v +} + +func (ec *executionContext) marshalNResourceTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.ResourceTypeFacetItem) graphql.Marshaler { + return ec._ResourceTypeFacetItem(ctx, sel, &v) +} + +func (ec *executionContext) marshalNResourceTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.ResourceTypeFacetItem) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNResourceTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItem(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) unmarshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx context.Context, v any) (issue.Severity, error) { var res issue.Severity err := res.UnmarshalGQL(v) @@ -5253,6 +5834,26 @@ func (ec *executionContext) marshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinterna return v } +func (ec *executionContext) marshalNSeverityFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.SeverityFacetItem) graphql.Marshaler { + return ec._SeverityFacetItem(ctx, sel, &v) +} + +func (ec *executionContext) marshalNSeverityFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.SeverityFacetItem) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNSeverityFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItem(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) unmarshalNWorkloadProblemType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐWorkloadProblemType(ctx context.Context, v any) (issue.WorkloadProblemType, error) { var res issue.WorkloadProblemType err := res.UnmarshalGQL(v) @@ -5263,6 +5864,13 @@ func (ec *executionContext) marshalNWorkloadProblemType2githubᚗcomᚋnaisᚋap return v } +func (ec *executionContext) marshalOIssueFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueFacets(ctx context.Context, sel ast.SelectionSet, v *issue.IssueFacets) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._IssueFacets(ctx, sel, v) +} + func (ec *executionContext) unmarshalOIssueFilter2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueFilter(ctx context.Context, v any) (*issue.IssueFilter, error) { if v == nil { return nil, nil diff --git a/internal/graph/gengql/jobs.generated.go b/internal/graph/gengql/jobs.generated.go index a472ae8c0..f7774d0c3 100644 --- a/internal/graph/gengql/jobs.generated.go +++ b/internal/graph/gengql/jobs.generated.go @@ -59,7 +59,7 @@ type JobResolver interface { ActivityLog(ctx context.Context, obj *job.Job, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *activitylog.ActivityLogFilter) (*activitylog.ActivityLogEntryConnection, error) State(ctx context.Context, obj *job.Job) (job.JobState, error) - Issues(ctx context.Context, obj *job.Job, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) + Issues(ctx context.Context, obj *job.Job, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) BigQueryDatasets(ctx context.Context, obj *job.Job, orderBy *bigquery.BigQueryDatasetOrder) (*pagination.FacetableConnection[*bigquery.BigQueryDataset, *bigquery.BigQueryDatasetFilter], error) Buckets(ctx context.Context, obj *job.Job, orderBy *bucket.BucketOrder) (*pagination.FacetableConnection[*bucket.Bucket, *bucket.BucketFilter], error) Configs(ctx context.Context, obj *job.Job, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.FacetableConnection[*config.Config, *config.ConfigFilter], error) @@ -1055,8 +1055,8 @@ func (ec *executionContext) _Job_issues(ctx context.Context, field graphql.Colle return ec.Resolvers.Job().Issues(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*issue.IssueOrder), fc.Args["filter"].(*issue.ResourceIssueFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[issue.Issue]) graphql.Marshaler { - return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *issue.IssueConnection) graphql.Marshaler { + return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx, selections, v) }, true, true, diff --git a/internal/graph/gengql/opensearch.generated.go b/internal/graph/gengql/opensearch.generated.go index 96f7b168c..7e543eec0 100644 --- a/internal/graph/gengql/opensearch.generated.go +++ b/internal/graph/gengql/opensearch.generated.go @@ -36,7 +36,7 @@ type OpenSearchResolver interface { Access(ctx context.Context, obj *opensearch.OpenSearch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *opensearch.OpenSearchAccessOrder) (*pagination.Connection[*opensearch.OpenSearchAccess], error) Version(ctx context.Context, obj *opensearch.OpenSearch) (*opensearch.OpenSearchVersion, error) - Issues(ctx context.Context, obj *opensearch.OpenSearch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) + Issues(ctx context.Context, obj *opensearch.OpenSearch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) ActivityLog(ctx context.Context, obj *opensearch.OpenSearch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *activitylog.ActivityLogFilter) (*activitylog.ActivityLogEntryConnection, error) Cost(ctx context.Context, obj *opensearch.OpenSearch) (*cost.OpenSearchCost, error) Maintenance(ctx context.Context, obj *opensearch.OpenSearch) (*servicemaintenance.OpenSearchMaintenance, error) @@ -671,8 +671,8 @@ func (ec *executionContext) _OpenSearch_issues(ctx context.Context, field graphq return ec.Resolvers.OpenSearch().Issues(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*issue.IssueOrder), fc.Args["filter"].(*issue.ResourceIssueFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[issue.Issue]) graphql.Marshaler { - return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *issue.IssueConnection) graphql.Marshaler { + return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx, selections, v) }, true, true, diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 31eb121a4..69ae6eec0 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -87,6 +87,7 @@ type ResolverRoot interface { IngressMetrics() IngressMetricsResolver InstanceGroup() InstanceGroupResolver InvalidSpecIssue() InvalidSpecIssueResolver + IssueConnection() IssueConnectionResolver Job() JobResolver JobConnection() JobConnectionResolver JobRun() JobRunResolver @@ -1141,6 +1142,7 @@ type ComplexityRoot struct { IssueConnection struct { Edges func(childComplexity int) int + Facets func(childComplexity int) int Nodes func(childComplexity int) int PageInfo func(childComplexity int) int } @@ -1150,6 +1152,18 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + IssueFacets struct { + Environments func(childComplexity int) int + IssueTypes func(childComplexity int) int + ResourceTypes func(childComplexity int) int + Severities func(childComplexity int) int + } + + IssueTypeFacetItem struct { + Count func(childComplexity int) int + IssueType func(childComplexity int) int + } + Job struct { ActivityLog func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *activitylog.ActivityLogFilter) int AuthIntegrations func(childComplexity int) int @@ -2049,6 +2063,11 @@ type ComplexityRoot struct { Value func(childComplexity int) int } + ResourceTypeFacetItem struct { + Count func(childComplexity int) int + ResourceType func(childComplexity int) int + } + RestartApplicationPayload struct { Application func(childComplexity int) int } @@ -2514,6 +2533,11 @@ type ComplexityRoot struct { Member func(childComplexity int) int } + SeverityFacetItem struct { + Count func(childComplexity int) int + Severity func(childComplexity int) int + } + SqlDatabase struct { Charset func(childComplexity int) int Collation func(childComplexity int) int @@ -7545,6 +7569,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.IssueConnection.Edges(childComplexity), true + case "IssueConnection.facets": + if e.ComplexityRoot.IssueConnection.Facets == nil { + break + } + + return e.ComplexityRoot.IssueConnection.Facets(childComplexity), true + case "IssueConnection.nodes": if e.ComplexityRoot.IssueConnection.Nodes == nil { break @@ -7573,6 +7604,48 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.IssueEdge.Node(childComplexity), true + case "IssueFacets.environments": + if e.ComplexityRoot.IssueFacets.Environments == nil { + break + } + + return e.ComplexityRoot.IssueFacets.Environments(childComplexity), true + + case "IssueFacets.issueTypes": + if e.ComplexityRoot.IssueFacets.IssueTypes == nil { + break + } + + return e.ComplexityRoot.IssueFacets.IssueTypes(childComplexity), true + + case "IssueFacets.resourceTypes": + if e.ComplexityRoot.IssueFacets.ResourceTypes == nil { + break + } + + return e.ComplexityRoot.IssueFacets.ResourceTypes(childComplexity), true + + case "IssueFacets.severities": + if e.ComplexityRoot.IssueFacets.Severities == nil { + break + } + + return e.ComplexityRoot.IssueFacets.Severities(childComplexity), true + + case "IssueTypeFacetItem.count": + if e.ComplexityRoot.IssueTypeFacetItem.Count == nil { + break + } + + return e.ComplexityRoot.IssueTypeFacetItem.Count(childComplexity), true + + case "IssueTypeFacetItem.issueType": + if e.ComplexityRoot.IssueTypeFacetItem.IssueType == nil { + break + } + + return e.ComplexityRoot.IssueTypeFacetItem.IssueType(childComplexity), true + case "Job.activityLog": if e.ComplexityRoot.Job.ActivityLog == nil { break @@ -12038,6 +12111,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ResourceLabel.Value(childComplexity), true + case "ResourceTypeFacetItem.count": + if e.ComplexityRoot.ResourceTypeFacetItem.Count == nil { + break + } + + return e.ComplexityRoot.ResourceTypeFacetItem.Count(childComplexity), true + + case "ResourceTypeFacetItem.resourceType": + if e.ComplexityRoot.ResourceTypeFacetItem.ResourceType == nil { + break + } + + return e.ComplexityRoot.ResourceTypeFacetItem.ResourceType(childComplexity), true + case "RestartApplicationPayload.application": if e.ComplexityRoot.RestartApplicationPayload.Application == nil { break @@ -14047,6 +14134,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SetTeamMemberRolePayload.Member(childComplexity), true + case "SeverityFacetItem.count": + if e.ComplexityRoot.SeverityFacetItem.Count == nil { + break + } + + return e.ComplexityRoot.SeverityFacetItem.Count(childComplexity), true + + case "SeverityFacetItem.severity": + if e.ComplexityRoot.SeverityFacetItem.Severity == nil { + break + } + + return e.ComplexityRoot.SeverityFacetItem.Severity(childComplexity), true + case "SqlDatabase.charset": if e.ComplexityRoot.SqlDatabase.Charset == nil { break @@ -23170,6 +23271,70 @@ type IssueConnection { "List of edges." edges: [IssueEdge!]! + + """ + Facets for the issues. Provides distribution counts to help narrow down results. + Facet counts are computed over the full result set (ignoring pagination) but respect the current filter. + """ + facets: IssueFacets +} + +""" +Facets for issues, providing distribution counts across different dimensions. +""" +type IssueFacets { + """ + Distribution of issues by environment. + """ + environments: [StringFacetItem!]! + + """ + Distribution of issues by severity. + """ + severities: [SeverityFacetItem!]! + + """ + Distribution of issues by resource type. + """ + resourceTypes: [ResourceTypeFacetItem!]! + + """ + Distribution of issues by issue type. + """ + issueTypes: [IssueTypeFacetItem!]! +} + +""" +A single facet item for issue severities. +""" +type SeverityFacetItem { + "The severity." + severity: Severity! + + "Number of matching issues." + count: Int! +} + +""" +A single facet item for resource types. +""" +type ResourceTypeFacetItem { + "The resource type." + resourceType: ResourceType! + + "Number of matching issues." + count: Int! +} + +""" +A single facet item for issue types. +""" +type IssueTypeFacetItem { + "The issue type." + issueType: IssueType! + + "Number of matching issues." + count: Int! } type IssueEdge { @@ -34025,6 +34190,8 @@ func (ec *executionContext) childFields_IssueConnection(ctx context.Context, fie return ec.fieldContext_IssueConnection_nodes(ctx, field) case "edges": return ec.fieldContext_IssueConnection_edges(ctx, field) + case "facets": + return ec.fieldContext_IssueConnection_facets(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type IssueConnection", field.Name) } @@ -34039,6 +34206,30 @@ func (ec *executionContext) childFields_IssueEdge(ctx context.Context, field gra return nil, fmt.Errorf("no field named %q was found under type IssueEdge", field.Name) } +func (ec *executionContext) childFields_IssueFacets(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "environments": + return ec.fieldContext_IssueFacets_environments(ctx, field) + case "severities": + return ec.fieldContext_IssueFacets_severities(ctx, field) + case "resourceTypes": + return ec.fieldContext_IssueFacets_resourceTypes(ctx, field) + case "issueTypes": + return ec.fieldContext_IssueFacets_issueTypes(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type IssueFacets", field.Name) +} + +func (ec *executionContext) childFields_IssueTypeFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "issueType": + return ec.fieldContext_IssueTypeFacetItem_issueType(ctx, field) + case "count": + return ec.fieldContext_IssueTypeFacetItem_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type IssueTypeFacetItem", field.Name) +} + func (ec *executionContext) childFields_Job(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": @@ -35163,6 +35354,16 @@ func (ec *executionContext) childFields_ResourceLabel(ctx context.Context, field return nil, fmt.Errorf("no field named %q was found under type ResourceLabel", field.Name) } +func (ec *executionContext) childFields_ResourceTypeFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "resourceType": + return ec.fieldContext_ResourceTypeFacetItem_resourceType(ctx, field) + case "count": + return ec.fieldContext_ResourceTypeFacetItem_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ResourceTypeFacetItem", field.Name) +} + func (ec *executionContext) childFields_RestartApplicationPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "application": @@ -35631,6 +35832,16 @@ func (ec *executionContext) childFields_SetTeamMemberRolePayload(ctx context.Con return nil, fmt.Errorf("no field named %q was found under type SetTeamMemberRolePayload", field.Name) } +func (ec *executionContext) childFields_SeverityFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "severity": + return ec.fieldContext_SeverityFacetItem_severity(ctx, field) + case "count": + return ec.fieldContext_SeverityFacetItem_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type SeverityFacetItem", field.Name) +} + func (ec *executionContext) childFields_SqlDatabase(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": diff --git a/internal/graph/gengql/sqlinstance.generated.go b/internal/graph/gengql/sqlinstance.generated.go index e1aedb0f5..6dd122ceb 100644 --- a/internal/graph/gengql/sqlinstance.generated.go +++ b/internal/graph/gengql/sqlinstance.generated.go @@ -37,7 +37,7 @@ type SqlInstanceResolver interface { Users(ctx context.Context, obj *sqlinstance.SQLInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *sqlinstance.SQLInstanceUserOrder) (*pagination.Connection[*sqlinstance.SQLInstanceUser], error) Metrics(ctx context.Context, obj *sqlinstance.SQLInstance) (*sqlinstance.SQLInstanceMetrics, error) State(ctx context.Context, obj *sqlinstance.SQLInstance) (sqlinstance.SQLInstanceState, error) - Issues(ctx context.Context, obj *sqlinstance.SQLInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) + Issues(ctx context.Context, obj *sqlinstance.SQLInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) AuditLog(ctx context.Context, obj *sqlinstance.SQLInstance) (*sqlinstance.AuditLog, error) Cost(ctx context.Context, obj *sqlinstance.SQLInstance) (*cost.SQLInstanceCost, error) } @@ -1147,8 +1147,8 @@ func (ec *executionContext) _SqlInstance_issues(ctx context.Context, field graph return ec.Resolvers.SqlInstance().Issues(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*issue.IssueOrder), fc.Args["filter"].(*issue.ResourceIssueFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[issue.Issue]) graphql.Marshaler { - return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *issue.IssueConnection) graphql.Marshaler { + return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx, selections, v) }, true, true, diff --git a/internal/graph/gengql/teams.generated.go b/internal/graph/gengql/teams.generated.go index 09e52e9e1..f8b2f2764 100644 --- a/internal/graph/gengql/teams.generated.go +++ b/internal/graph/gengql/teams.generated.go @@ -69,7 +69,7 @@ type TeamResolver interface { Cost(ctx context.Context, obj *team.Team) (*cost.TeamCost, error) DeploymentKey(ctx context.Context, obj *team.Team) (*deployment.DeploymentKey, error) Deployments(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[*deployment.Deployment], error) - Issues(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.IssueFilter) (*pagination.Connection[issue.Issue], error) + Issues(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.IssueFilter) (*issue.IssueConnection, error) Jobs(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *job.JobOrder, filter *job.TeamJobsFilter) (*pagination.FacetableConnection[*job.Job, *job.TeamJobsFilter], error) KafkaTopics(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *kafkatopic.KafkaTopicOrder, filter *kafkatopic.KafkaTopicFilter) (*pagination.FacetableConnection[*kafkatopic.KafkaTopic, *kafkatopic.KafkaTopicFilter], error) OpenSearches(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *opensearch.OpenSearchOrder, filter *opensearch.OpenSearchFilter) (*pagination.FacetableConnection[*opensearch.OpenSearch, *opensearch.OpenSearchFilter], error) @@ -2566,8 +2566,8 @@ func (ec *executionContext) _Team_issues(ctx context.Context, field graphql.Coll return ec.Resolvers.Team().Issues(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*issue.IssueOrder), fc.Args["filter"].(*issue.IssueFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[issue.Issue]) graphql.Marshaler { - return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *issue.IssueConnection) graphql.Marshaler { + return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx, selections, v) }, true, true, diff --git a/internal/graph/gengql/valkey.generated.go b/internal/graph/gengql/valkey.generated.go index ed0a51b7e..748c092e1 100644 --- a/internal/graph/gengql/valkey.generated.go +++ b/internal/graph/gengql/valkey.generated.go @@ -35,7 +35,7 @@ type ValkeyResolver interface { Workload(ctx context.Context, obj *valkey.Valkey) (workload.Workload, error) State(ctx context.Context, obj *valkey.Valkey) (valkey.ValkeyState, error) - Issues(ctx context.Context, obj *valkey.Valkey, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) + Issues(ctx context.Context, obj *valkey.Valkey, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) ActivityLog(ctx context.Context, obj *valkey.Valkey, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *activitylog.ActivityLogFilter) (*activitylog.ActivityLogEntryConnection, error) Cost(ctx context.Context, obj *valkey.Valkey) (*cost.ValkeyCost, error) Maintenance(ctx context.Context, obj *valkey.Valkey) (*servicemaintenance.ValkeyMaintenance, error) @@ -739,8 +739,8 @@ func (ec *executionContext) _Valkey_issues(ctx context.Context, field graphql.Co return ec.Resolvers.Valkey().Issues(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*issue.IssueOrder), fc.Args["filter"].(*issue.ResourceIssueFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[issue.Issue]) graphql.Marshaler { - return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *issue.IssueConnection) graphql.Marshaler { + return ec.marshalNIssueConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueConnection(ctx, selections, v) }, true, true, diff --git a/internal/graph/issues.resolvers.go b/internal/graph/issues.resolvers.go index 58e6143e3..4ccb749bc 100644 --- a/internal/graph/issues.resolvers.go +++ b/internal/graph/issues.resolvers.go @@ -68,6 +68,10 @@ func (r *invalidSpecIssueResolver) Workload(ctx context.Context, obj *issue.Inva return getWorkloadByResourceType(ctx, obj.TeamSlug, obj.EnvironmentName, obj.ResourceName, obj.ResourceType) } +func (r *issueConnectionResolver) Facets(ctx context.Context, obj *issue.IssueConnection) (*issue.IssueFacets, error) { + return issue.ComputeFacets(ctx, obj.GetTeamSlug(), obj.GetFilter()) +} + func (r *lastRunFailedIssueResolver) TeamEnvironment(ctx context.Context, obj *issue.LastRunFailedIssue) (*team.TeamEnvironment, error) { return team.GetTeamEnvironment(ctx, obj.TeamSlug, obj.EnvironmentName) } @@ -116,7 +120,7 @@ func (r *sqlInstanceVersionIssueResolver) SQLInstance(ctx context.Context, obj * return sqlinstance.Get(ctx, obj.TeamSlug, obj.EnvironmentName, obj.ResourceName) } -func (r *teamResolver) Issues(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.IssueFilter) (*pagination.Connection[issue.Issue], error) { +func (r *teamResolver) Issues(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.IssueFilter) (*issue.IssueConnection, error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err @@ -181,6 +185,10 @@ func (r *Resolver) InvalidSpecIssue() gengql.InvalidSpecIssueResolver { return &invalidSpecIssueResolver{r} } +func (r *Resolver) IssueConnection() gengql.IssueConnectionResolver { + return &issueConnectionResolver{r} +} + func (r *Resolver) LastRunFailedIssue() gengql.LastRunFailedIssueResolver { return &lastRunFailedIssueResolver{r} } @@ -226,6 +234,7 @@ type ( externalIngressCriticalVulnerabilityIssueResolver struct{ *Resolver } failedSynchronizationIssueResolver struct{ *Resolver } invalidSpecIssueResolver struct{ *Resolver } + issueConnectionResolver struct{ *Resolver } lastRunFailedIssueResolver struct{ *Resolver } missingSbomIssueResolver struct{ *Resolver } noRunningInstancesIssueResolver struct{ *Resolver } diff --git a/internal/graph/jobs.resolvers.go b/internal/graph/jobs.resolvers.go index 6cc3eda67..25d597891 100644 --- a/internal/graph/jobs.resolvers.go +++ b/internal/graph/jobs.resolvers.go @@ -73,7 +73,7 @@ func (r *jobResolver) State(ctx context.Context, obj *job.Job) (job.JobState, er return job.GetState(ctx, obj) } -func (r *jobResolver) Issues(ctx context.Context, obj *job.Job, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) { +func (r *jobResolver) Issues(ctx context.Context, obj *job.Job, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err diff --git a/internal/graph/opensearch.resolvers.go b/internal/graph/opensearch.resolvers.go index 9de3ac5ab..b341d358c 100644 --- a/internal/graph/opensearch.resolvers.go +++ b/internal/graph/opensearch.resolvers.go @@ -79,7 +79,7 @@ func (r *openSearchResolver) Version(ctx context.Context, obj *opensearch.OpenSe return opensearch.GetOpenSearchVersion(ctx, obj) } -func (r *openSearchResolver) Issues(ctx context.Context, obj *opensearch.OpenSearch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) { +func (r *openSearchResolver) Issues(ctx context.Context, obj *opensearch.OpenSearch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err diff --git a/internal/graph/schema/issues.graphqls b/internal/graph/schema/issues.graphqls index 6558ea2b1..792406311 100644 --- a/internal/graph/schema/issues.graphqls +++ b/internal/graph/schema/issues.graphqls @@ -76,6 +76,70 @@ type IssueConnection { "List of edges." edges: [IssueEdge!]! + + """ + Facets for the issues. Provides distribution counts to help narrow down results. + Facet counts are computed over the full result set (ignoring pagination) but respect the current filter. + """ + facets: IssueFacets +} + +""" +Facets for issues, providing distribution counts across different dimensions. +""" +type IssueFacets { + """ + Distribution of issues by environment. + """ + environments: [StringFacetItem!]! + + """ + Distribution of issues by severity. + """ + severities: [SeverityFacetItem!]! + + """ + Distribution of issues by resource type. + """ + resourceTypes: [ResourceTypeFacetItem!]! + + """ + Distribution of issues by issue type. + """ + issueTypes: [IssueTypeFacetItem!]! +} + +""" +A single facet item for issue severities. +""" +type SeverityFacetItem { + "The severity." + severity: Severity! + + "Number of matching issues." + count: Int! +} + +""" +A single facet item for resource types. +""" +type ResourceTypeFacetItem { + "The resource type." + resourceType: ResourceType! + + "Number of matching issues." + count: Int! +} + +""" +A single facet item for issue types. +""" +type IssueTypeFacetItem { + "The issue type." + issueType: IssueType! + + "Number of matching issues." + count: Int! } type IssueEdge { diff --git a/internal/graph/sqlinstance.resolvers.go b/internal/graph/sqlinstance.resolvers.go index baf764e10..5eea87409 100644 --- a/internal/graph/sqlinstance.resolvers.go +++ b/internal/graph/sqlinstance.resolvers.go @@ -96,7 +96,7 @@ func (r *sqlInstanceResolver) State(ctx context.Context, obj *sqlinstance.SQLIns return sqlinstance.GetState(ctx, obj.ProjectID, obj.Name) } -func (r *sqlInstanceResolver) Issues(ctx context.Context, obj *sqlinstance.SQLInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) { +func (r *sqlInstanceResolver) Issues(ctx context.Context, obj *sqlinstance.SQLInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err diff --git a/internal/graph/valkey.resolvers.go b/internal/graph/valkey.resolvers.go index fbacd1c4e..587a17846 100644 --- a/internal/graph/valkey.resolvers.go +++ b/internal/graph/valkey.resolvers.go @@ -94,7 +94,7 @@ func (r *valkeyResolver) State(ctx context.Context, obj *valkey.Valkey) (valkey. return valkey.State(ctx, obj) } -func (r *valkeyResolver) Issues(ctx context.Context, obj *valkey.Valkey, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*pagination.Connection[issue.Issue], error) { +func (r *valkeyResolver) Issues(ctx context.Context, obj *valkey.Valkey, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *issue.IssueOrder, filter *issue.ResourceIssueFilter) (*issue.IssueConnection, error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err From bdc92e577ffac6417ff76588eca8a120ca0c6582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Tue, 30 Jun 2026 16:48:34 +0200 Subject: [PATCH 03/11] fix: scope vs filter in FacetsForIssues, normalize empty environments Address Copilot review feedback: - FacetsForIssues SQL: split scope params (resource_type, resource_name, env) into the outer WHERE clause so total_count reflects the actual connection scope, matching the activitylog FacetsForActivityTypes pattern. User filter params remain in COUNT(*) FILTER (...). - IssueConnection now carries a separate IssueScope for resource-level queries (application, job, opensearch, sqlinstance, valkey). Resource resolvers build the scope from the resource object instead of embedding it in IssueFilter. - Normalize empty environments slice to nil in ListIssues and ComputeFacets so that an empty []string{} does not produce an always-false ANY predicate. --- internal/graph/applications.resolvers.go | 15 +++++------ internal/graph/issues.resolvers.go | 4 +-- internal/graph/jobs.resolvers.go | 15 +++++------ internal/graph/opensearch.resolvers.go | 15 +++++------ internal/graph/sqlinstance.resolvers.go | 15 +++++------ internal/graph/valkey.resolvers.go | 15 +++++------ internal/issue/facets.go | 18 ++++++++++--- internal/issue/issuesql/issue.sql.go | 34 ++++++++++++++++++------ internal/issue/model.go | 8 ++++++ internal/issue/queries.go | 19 ++++++++++--- internal/issue/queries/issue.sql | 20 +++++++++++--- 11 files changed, 116 insertions(+), 62 deletions(-) diff --git a/internal/graph/applications.resolvers.go b/internal/graph/applications.resolvers.go index 72d8d2318..e4461d19f 100644 --- a/internal/graph/applications.resolvers.go +++ b/internal/graph/applications.resolvers.go @@ -81,18 +81,17 @@ func (r *applicationResolver) Issues(ctx context.Context, obj *application.Appli return nil, err } - t := issue.ResourceTypeApplication - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &t, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeApplication, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.Severity = filter.Severity - f.IssueType = filter.IssueType + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *applicationResolver) History(ctx context.Context, obj *application.Application) ([]*instancegroup.ApplicationHistory, error) { diff --git a/internal/graph/issues.resolvers.go b/internal/graph/issues.resolvers.go index 4ccb749bc..558894d1f 100644 --- a/internal/graph/issues.resolvers.go +++ b/internal/graph/issues.resolvers.go @@ -69,7 +69,7 @@ func (r *invalidSpecIssueResolver) Workload(ctx context.Context, obj *issue.Inva } func (r *issueConnectionResolver) Facets(ctx context.Context, obj *issue.IssueConnection) (*issue.IssueFacets, error) { - return issue.ComputeFacets(ctx, obj.GetTeamSlug(), obj.GetFilter()) + return issue.ComputeFacets(ctx, obj.GetTeamSlug(), obj.GetScope(), obj.GetFilter()) } func (r *lastRunFailedIssueResolver) TeamEnvironment(ctx context.Context, obj *issue.LastRunFailedIssue) (*team.TeamEnvironment, error) { @@ -126,7 +126,7 @@ func (r *teamResolver) Issues(ctx context.Context, obj *team.Team, first *int, a return nil, err } - return issue.ListIssues(ctx, obj.Slug, page, orderBy, filter) + return issue.ListIssues(ctx, obj.Slug, page, orderBy, nil, filter) } func (r *unleashReleaseChannelIssueResolver) TeamEnvironment(ctx context.Context, obj *issue.UnleashReleaseChannelIssue) (*team.TeamEnvironment, error) { diff --git a/internal/graph/jobs.resolvers.go b/internal/graph/jobs.resolvers.go index 25d597891..ed17c7def 100644 --- a/internal/graph/jobs.resolvers.go +++ b/internal/graph/jobs.resolvers.go @@ -79,18 +79,17 @@ func (r *jobResolver) Issues(ctx context.Context, obj *job.Job, first *int, afte return nil, err } - jobType := issue.ResourceTypeJob - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &jobType, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeJob, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.Severity = filter.Severity - f.IssueType = filter.IssueType + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *jobConnectionResolver) Facets(ctx context.Context, obj *pagination.FacetableConnection[*job.Job, *job.TeamJobsFilter]) (*job.JobFacets, error) { diff --git a/internal/graph/opensearch.resolvers.go b/internal/graph/opensearch.resolvers.go index b341d358c..06e8dd9ac 100644 --- a/internal/graph/opensearch.resolvers.go +++ b/internal/graph/opensearch.resolvers.go @@ -85,18 +85,17 @@ func (r *openSearchResolver) Issues(ctx context.Context, obj *opensearch.OpenSea return nil, err } - t := issue.ResourceTypeOpensearch - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &t, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeOpensearch, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.Severity = filter.Severity - f.IssueType = filter.IssueType + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *openSearchAccessResolver) Workload(ctx context.Context, obj *opensearch.OpenSearchAccess) (workload.Workload, error) { diff --git a/internal/graph/sqlinstance.resolvers.go b/internal/graph/sqlinstance.resolvers.go index 5eea87409..71883ff46 100644 --- a/internal/graph/sqlinstance.resolvers.go +++ b/internal/graph/sqlinstance.resolvers.go @@ -102,18 +102,17 @@ func (r *sqlInstanceResolver) Issues(ctx context.Context, obj *sqlinstance.SQLIn return nil, err } - t := issue.ResourceTypeSQLInstance - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &t, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeSQLInstance, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.Severity = filter.Severity - f.IssueType = filter.IssueType + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *sqlInstanceResolver) AuditLog(ctx context.Context, obj *sqlinstance.SQLInstance) (*sqlinstance.AuditLog, error) { diff --git a/internal/graph/valkey.resolvers.go b/internal/graph/valkey.resolvers.go index 587a17846..a276b6973 100644 --- a/internal/graph/valkey.resolvers.go +++ b/internal/graph/valkey.resolvers.go @@ -100,18 +100,17 @@ func (r *valkeyResolver) Issues(ctx context.Context, obj *valkey.Valkey, first * return nil, err } - t := issue.ResourceTypeValkey - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &t, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeValkey, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.Severity = filter.Severity - f.IssueType = filter.IssueType + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *valkeyAccessResolver) Workload(ctx context.Context, obj *valkey.ValkeyAccess) (workload.Workload, error) { diff --git a/internal/issue/facets.go b/internal/issue/facets.go index 5f969f526..8a05290c5 100644 --- a/internal/issue/facets.go +++ b/internal/issue/facets.go @@ -10,16 +10,26 @@ import ( "github.com/nais/api/internal/slug" ) -func ComputeFacets(ctx context.Context, teamSlug slug.Slug, filter *IssueFilter) (*IssueFacets, error) { +func ComputeFacets(ctx context.Context, teamSlug slug.Slug, scope *IssueScope, filter *IssueFilter) (*IssueFacets, error) { params := issuesql.FacetsForIssuesParams{ Team: teamSlug.String(), } + if scope != nil { + params.ScopeResourceName = &scope.ResourceName + params.ScopeResourceType = (*string)(&scope.ResourceType) + params.ScopeEnv = &scope.Env + } + if filter != nil { - params.Env = filter.Environments - params.ResourceType = (*string)(filter.ResourceType) + if scope == nil { + if len(filter.Environments) > 0 { + params.Env = filter.Environments + } + params.FilterResourceType = (*string)(filter.ResourceType) + params.FilterResourceName = filter.ResourceName + } params.IssueType = (*string)(filter.IssueType) - params.ResourceName = filter.ResourceName if filter.Severity != nil { params.Severity = new(issuesql.SeverityLevel(*filter.Severity)) } diff --git a/internal/issue/issuesql/issue.sql.go b/internal/issue/issuesql/issue.sql.go index 123a432a3..a38da0029 100644 --- a/internal/issue/issuesql/issue.sql.go +++ b/internal/issue/issuesql/issue.sql.go @@ -44,6 +44,18 @@ FROM issues WHERE team = $6 + AND ( + $7::TEXT IS NULL + OR resource_type = $7::TEXT + ) + AND ( + $8::TEXT IS NULL + OR resource_name = $8::TEXT + ) + AND ( + $9::TEXT IS NULL + OR env = $9::TEXT + ) GROUP BY severity, resource_type, @@ -57,12 +69,15 @@ ORDER BY ` type FacetsForIssuesParams struct { - Env []string - IssueType *string - Severity *SeverityLevel - ResourceType *string - ResourceName *string - Team string + Env []string + IssueType *string + Severity *SeverityLevel + FilterResourceType *string + FilterResourceName *string + Team string + ScopeResourceType *string + ScopeResourceName *string + ScopeEnv *string } type FacetsForIssuesRow struct { @@ -79,9 +94,12 @@ func (q *Queries) FacetsForIssues(ctx context.Context, arg FacetsForIssuesParams arg.Env, arg.IssueType, arg.Severity, - arg.ResourceType, - arg.ResourceName, + arg.FilterResourceType, + arg.FilterResourceName, arg.Team, + arg.ScopeResourceType, + arg.ScopeResourceName, + arg.ScopeEnv, ) if err != nil { return nil, err diff --git a/internal/issue/model.go b/internal/issue/model.go index db358c825..2b4a5b971 100644 --- a/internal/issue/model.go +++ b/internal/issue/model.go @@ -269,14 +269,22 @@ type ( IssueEdge = pagination.Edge[Issue] ) +type IssueScope struct { + ResourceName string + ResourceType ResourceType + Env string +} + type IssueConnection struct { pagination.Connection[Issue] teamSlug slug.Slug + scope *IssueScope filter *IssueFilter } func (c *IssueConnection) GetTeamSlug() slug.Slug { return c.teamSlug } +func (c *IssueConnection) GetScope() *IssueScope { return c.scope } func (c *IssueConnection) GetFilter() *IssueFilter { return c.filter } type IssueFacets struct { diff --git a/internal/issue/queries.go b/internal/issue/queries.go index 128b3abde..ad1ab7401 100644 --- a/internal/issue/queries.go +++ b/internal/issue/queries.go @@ -43,7 +43,7 @@ func GetByIdent(ctx context.Context, id ident.Ident) (Issue, error) { return convert(issue) } -func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, filter *IssueFilter) (*IssueConnection, error) { +func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, scope *IssueScope, filter *IssueFilter) (*IssueConnection, error) { params := issuesql.ListIssuesParams{ Team: teamSlug.String(), Offset: page.Offset(), @@ -51,11 +51,21 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina OrderBy: orderBy.String(), } + if scope != nil { + params.ResourceName = &scope.ResourceName + params.ResourceType = (*string)(&scope.ResourceType) + params.Env = []string{scope.Env} + } + if filter != nil { - params.Env = filter.Environments - params.ResourceType = (*string)(filter.ResourceType) + if scope == nil { + if len(filter.Environments) > 0 { + params.Env = filter.Environments + } + params.ResourceType = (*string)(filter.ResourceType) + params.ResourceName = filter.ResourceName + } params.IssueType = (*string)(filter.IssueType) - params.ResourceName = filter.ResourceName if filter.Severity != nil { params.Severity = new(issuesql.SeverityLevel(*filter.Severity)) } @@ -93,6 +103,7 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina return &IssueConnection{ Connection: *conn, teamSlug: teamSlug, + scope: scope, filter: filter, }, nil } diff --git a/internal/issue/queries/issue.sql b/internal/issue/queries/issue.sql index 7094ad820..184735412 100644 --- a/internal/issue/queries/issue.sql +++ b/internal/issue/queries/issue.sql @@ -115,18 +115,30 @@ SELECT OR severity = sqlc.narg('severity')::severity_level ) AND ( - sqlc.narg('resource_type')::TEXT IS NULL - OR resource_type = sqlc.narg('resource_type')::TEXT + sqlc.narg('filter_resource_type')::TEXT IS NULL + OR resource_type = sqlc.narg('filter_resource_type')::TEXT ) AND ( - sqlc.narg('resource_name')::TEXT IS NULL - OR resource_name = sqlc.narg('resource_name')::TEXT + sqlc.narg('filter_resource_name')::TEXT IS NULL + OR resource_name = sqlc.narg('filter_resource_name')::TEXT ) ) AS filtered_count FROM issues WHERE team = @team + AND ( + sqlc.narg('scope_resource_type')::TEXT IS NULL + OR resource_type = sqlc.narg('scope_resource_type')::TEXT + ) + AND ( + sqlc.narg('scope_resource_name')::TEXT IS NULL + OR resource_name = sqlc.narg('scope_resource_name')::TEXT + ) + AND ( + sqlc.narg('scope_env')::TEXT IS NULL + OR env = sqlc.narg('scope_env')::TEXT + ) GROUP BY severity, resource_type, From a714d943ad9788323afedd2642a40b69d9002a88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 10:30:05 +0200 Subject: [PATCH 04/11] feat(graph): add facets to AlertConnection --- internal/alerts/facets.go | 44 +++ internal/alerts/models.go | 15 +- internal/graph/alerts.resolvers.go | 40 +-- internal/graph/gengql/alerts.generated.go | 374 +++++++++++++++++++++- internal/graph/gengql/root_.generated.go | 97 ++++++ internal/graph/gengql/teams.generated.go | 12 +- internal/graph/schema/alerts.graphqls | 28 ++ 7 files changed, 574 insertions(+), 36 deletions(-) create mode 100644 internal/alerts/facets.go diff --git a/internal/alerts/facets.go b/internal/alerts/facets.go new file mode 100644 index 000000000..0651c2b8c --- /dev/null +++ b/internal/alerts/facets.go @@ -0,0 +1,44 @@ +package alerts + +import ( + "context" + "slices" + "strings" + + "github.com/nais/api/internal/graph/model" +) + +func (f *AlertFacets) Filtered(ctx context.Context) []Alert { + f.filteredOnce.Do(func() { + f.filteredAlerts = SortFilter.Filter(ctx, f.AllAlerts, f.Filter) + }) + return f.filteredAlerts +} + +func (f *AlertFacets) Environments(ctx context.Context) []model.StringFacetItem { + filtered := f.Filtered(ctx) + return model.ComputeEnvironmentsFacet(f.AllAlerts, filtered, func(a Alert) string { + return a.GetEnvironmentName() + }) +} + +func (f *AlertFacets) States(ctx context.Context) []AlertStateFacetItem { + stateCounts := map[AlertState]int{} + for _, a := range f.AllAlerts { + if _, ok := stateCounts[a.GetState()]; !ok { + stateCounts[a.GetState()] = 0 + } + } + for _, a := range f.Filtered(ctx) { + stateCounts[a.GetState()]++ + } + + items := make([]AlertStateFacetItem, 0, len(stateCounts)) + for state, count := range stateCounts { + items = append(items, AlertStateFacetItem{State: state, Count: count}) + } + slices.SortFunc(items, func(a, b AlertStateFacetItem) int { + return strings.Compare(a.State.String(), b.State.String()) + }) + return items +} diff --git a/internal/alerts/models.go b/internal/alerts/models.go index b5ffc9a13..03254c7f1 100644 --- a/internal/alerts/models.go +++ b/internal/alerts/models.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "strconv" + "sync" "time" "github.com/nais/api/internal/graph/ident" @@ -15,10 +16,22 @@ import ( ) type ( - AlertConnection = pagination.Connection[Alert] + AlertConnection = pagination.FacetableConnection[Alert, *TeamAlertsFilter] AlertEdge = pagination.Edge[Alert] ) +type AlertFacets struct { + AllAlerts []Alert + Filter *TeamAlertsFilter + filteredOnce sync.Once + filteredAlerts []Alert +} + +type AlertStateFacetItem struct { + State AlertState `json:"state"` + Count int `json:"count"` +} + type Alert interface { model.Node GetName() string diff --git a/internal/graph/alerts.resolvers.go b/internal/graph/alerts.resolvers.go index abf575b58..6b45563fc 100644 --- a/internal/graph/alerts.resolvers.go +++ b/internal/graph/alerts.resolvers.go @@ -11,6 +11,13 @@ import ( "github.com/nais/api/internal/team" ) +func (r *alertConnectionResolver) Facets(ctx context.Context, obj *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) (*alerts.AlertFacets, error) { + return &alerts.AlertFacets{ + AllAlerts: obj.GetAllItems(), + Filter: obj.GetFilter(), + }, nil +} + func (r *prometheusAlertResolver) Team(ctx context.Context, obj *alerts.PrometheusAlert) (*team.Team, error) { team, err := team.Get(ctx, obj.TeamSlug) if err != nil { @@ -24,7 +31,7 @@ func (r *prometheusAlertResolver) TeamEnvironment(ctx context.Context, obj *aler return team.GetTeamEnvironment(ctx, obj.TeamSlug, obj.EnvironmentName) } -func (r *teamResolver) Alerts(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.Connection[alerts.Alert], error) { +func (r *teamResolver) Alerts(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter], error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err @@ -40,20 +47,13 @@ func (r *teamResolver) Alerts(ctx context.Context, obj *team.Team, first *int, a a = append(a, alert) } - filtered := alerts.SortFilter.Filter(ctx, a, filter) if orderBy == nil { - orderBy = &alerts.AlertOrder{ - Field: "NAME", - Direction: model.OrderDirectionAsc, - } + orderBy = &alerts.AlertOrder{Field: "NAME", Direction: model.OrderDirectionAsc} } - alerts.SortFilter.Sort(ctx, filtered, orderBy.Field, orderBy.Direction) - - ret := pagination.Slice(filtered, page) - return pagination.NewConnection(ret, page, len(filtered)), nil + return alerts.SortFilter.PaginatedList(ctx, a, page, orderBy.Field, orderBy.Direction, filter), nil } -func (r *teamEnvironmentResolver) Alerts(ctx context.Context, obj *team.TeamEnvironment, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.Connection[alerts.Alert], error) { +func (r *teamEnvironmentResolver) Alerts(ctx context.Context, obj *team.TeamEnvironment, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter], error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err @@ -69,21 +69,21 @@ func (r *teamEnvironmentResolver) Alerts(ctx context.Context, obj *team.TeamEnvi a = append(a, alert) } - filtered := alerts.SortFilter.Filter(ctx, a, filter) if orderBy == nil { - orderBy = &alerts.AlertOrder{ - Field: "NAME", - Direction: model.OrderDirectionAsc, - } + orderBy = &alerts.AlertOrder{Field: "NAME", Direction: model.OrderDirectionAsc} } - alerts.SortFilter.Sort(ctx, filtered, orderBy.Field, orderBy.Direction) + return alerts.SortFilter.PaginatedList(ctx, a, page, orderBy.Field, orderBy.Direction, filter), nil +} - ret := pagination.Slice(filtered, page) - return pagination.NewConnection(ret, page, len(filtered)), nil +func (r *Resolver) AlertConnection() gengql.AlertConnectionResolver { + return &alertConnectionResolver{r} } func (r *Resolver) PrometheusAlert() gengql.PrometheusAlertResolver { return &prometheusAlertResolver{r} } -type prometheusAlertResolver struct{ *Resolver } +type ( + alertConnectionResolver struct{ *Resolver } + prometheusAlertResolver struct{ *Resolver } +) diff --git a/internal/graph/gengql/alerts.generated.go b/internal/graph/gengql/alerts.generated.go index 56f5edbfa..3a1970697 100644 --- a/internal/graph/gengql/alerts.generated.go +++ b/internal/graph/gengql/alerts.generated.go @@ -14,6 +14,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/alerts" "github.com/nais/api/internal/graph/ident" + "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/team" "github.com/vektah/gqlparser/v2/ast" @@ -21,6 +22,9 @@ import ( // region ************************** generated!.gotpl ************************** +type AlertConnectionResolver interface { + Facets(ctx context.Context, obj *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) (*alerts.AlertFacets, error) +} type PrometheusAlertResolver interface { Team(ctx context.Context, obj *alerts.PrometheusAlert) (*team.Team, error) TeamEnvironment(ctx context.Context, obj *alerts.PrometheusAlert) (*team.TeamEnvironment, error) @@ -38,7 +42,7 @@ type PrometheusAlertResolver interface { // region **************************** field.gotpl ***************************** -func (ec *executionContext) _AlertConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.Connection[alerts.Alert]) (ret graphql.Marshaler) { +func (ec *executionContext) _AlertConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -70,7 +74,7 @@ func (ec *executionContext) fieldContext_AlertConnection_pageInfo(_ context.Cont return fc, nil } -func (ec *executionContext) _AlertConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *pagination.Connection[alerts.Alert]) (ret graphql.Marshaler) { +func (ec *executionContext) _AlertConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -102,7 +106,7 @@ func (ec *executionContext) fieldContext_AlertConnection_nodes(_ context.Context return fc, nil } -func (ec *executionContext) _AlertConnection_edges(ctx context.Context, field graphql.CollectedField, obj *pagination.Connection[alerts.Alert]) (ret graphql.Marshaler) { +func (ec *executionContext) _AlertConnection_edges(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -134,6 +138,38 @@ func (ec *executionContext) fieldContext_AlertConnection_edges(_ context.Context return fc, nil } +func (ec *executionContext) _AlertConnection_facets(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_AlertConnection_facets(ctx, field) + }, + func(ctx context.Context) (any, error) { + return ec.Resolvers.AlertConnection().Facets(ctx, obj) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *alerts.AlertFacets) graphql.Marshaler { + return ec.marshalOAlertFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertFacets(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_AlertConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AlertConnection", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_AlertFacets(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _AlertEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[alerts.Alert]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -189,6 +225,116 @@ func (ec *executionContext) fieldContext_AlertEdge_node(_ context.Context, field return fc, nil } +func (ec *executionContext) _AlertFacets_environments(ctx context.Context, field graphql.CollectedField, obj *alerts.AlertFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_AlertFacets_environments(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Environments(ctx), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { + return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_AlertFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AlertFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_StringFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _AlertFacets_states(ctx context.Context, field graphql.CollectedField, obj *alerts.AlertFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_AlertFacets_states(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.States(ctx), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []alerts.AlertStateFacetItem) graphql.Marshaler { + return ec.marshalNAlertStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertStateFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_AlertFacets_states(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "AlertFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_AlertStateFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _AlertStateFacetItem_state(ctx context.Context, field graphql.CollectedField, obj *alerts.AlertStateFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_AlertStateFacetItem_state(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.State, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v alerts.AlertState) graphql.Marshaler { + return ec.marshalNAlertState2githubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertState(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_AlertStateFacetItem_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("AlertStateFacetItem", field, false, false, errors.New("field of type AlertState does not have child fields")) +} + +func (ec *executionContext) _AlertStateFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *alerts.AlertStateFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_AlertStateFacetItem_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_AlertStateFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("AlertStateFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +} + func (ec *executionContext) _PrometheusAlarm_action(ctx context.Context, field graphql.CollectedField, obj *alerts.PrometheusAlarm) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -676,7 +822,7 @@ func (ec *executionContext) _Alert(ctx context.Context, sel ast.SelectionSet, ob var alertConnectionImplementors = []string{"AlertConnection"} -func (ec *executionContext) _AlertConnection(ctx context.Context, sel ast.SelectionSet, obj *pagination.Connection[alerts.Alert]) graphql.Marshaler { +func (ec *executionContext) _AlertConnection(ctx context.Context, sel ast.SelectionSet, obj *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, alertConnectionImplementors) out := graphql.NewFieldSet(fields) @@ -688,18 +834,51 @@ func (ec *executionContext) _AlertConnection(ctx context.Context, sel ast.Select case "pageInfo": out.Values[i] = ec._AlertConnection_pageInfo(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "nodes": out.Values[i] = ec._AlertConnection_nodes(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "edges": out.Values[i] = ec._AlertConnection_edges(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } + case "facets": + field := field + + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._AlertConnection_facets(ctx, field, obj) + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -767,6 +946,156 @@ func (ec *executionContext) _AlertEdge(ctx context.Context, sel ast.SelectionSet return out } +var alertFacetsImplementors = []string{"AlertFacets"} + +func (ec *executionContext) _AlertFacets(ctx context.Context, sel ast.SelectionSet, obj *alerts.AlertFacets) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, alertFacetsImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("AlertFacets") + case "environments": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._AlertFacets_environments(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "states": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._AlertFacets_states(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var alertStateFacetItemImplementors = []string{"AlertStateFacetItem"} + +func (ec *executionContext) _AlertStateFacetItem(ctx context.Context, sel ast.SelectionSet, obj *alerts.AlertStateFacetItem) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, alertStateFacetItemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("AlertStateFacetItem") + case "state": + out.Values[i] = ec._AlertStateFacetItem_state(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "count": + out.Values[i] = ec._AlertStateFacetItem_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var prometheusAlarmImplementors = []string{"PrometheusAlarm"} func (ec *executionContext) _PrometheusAlarm(ctx context.Context, sel ast.SelectionSet, obj *alerts.PrometheusAlarm) graphql.Marshaler { @@ -1002,11 +1331,11 @@ func (ec *executionContext) marshalNAlert2ᚕgithubᚗcomᚋnaisᚋapiᚋinterna return ret } -func (ec *executionContext) marshalNAlertConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx context.Context, sel ast.SelectionSet, v pagination.Connection[alerts.Alert]) graphql.Marshaler { +func (ec *executionContext) marshalNAlertConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx context.Context, sel ast.SelectionSet, v pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) graphql.Marshaler { return ec._AlertConnection(ctx, sel, &v) } -func (ec *executionContext) marshalNAlertConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx context.Context, sel ast.SelectionSet, v *pagination.Connection[alerts.Alert]) graphql.Marshaler { +func (ec *executionContext) marshalNAlertConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx context.Context, sel ast.SelectionSet, v *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") @@ -1056,6 +1385,26 @@ func (ec *executionContext) marshalNAlertState2githubᚗcomᚋnaisᚋapiᚋinter return v } +func (ec *executionContext) marshalNAlertStateFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertStateFacetItem(ctx context.Context, sel ast.SelectionSet, v alerts.AlertStateFacetItem) graphql.Marshaler { + return ec._AlertStateFacetItem(ctx, sel, &v) +} + +func (ec *executionContext) marshalNAlertStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertStateFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []alerts.AlertStateFacetItem) graphql.Marshaler { + ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { + fc := graphql.GetFieldContext(ctx) + fc.Result = &v[i] + return ec.marshalNAlertStateFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertStateFacetItem(ctx, sel, v[i]) + }) + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) marshalNPrometheusAlarm2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐPrometheusAlarmᚄ(ctx context.Context, sel ast.SelectionSet, v []*alerts.PrometheusAlarm) graphql.Marshaler { ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) @@ -1082,6 +1431,13 @@ func (ec *executionContext) marshalNPrometheusAlarm2ᚖgithubᚗcomᚋnaisᚋapi return ec._PrometheusAlarm(ctx, sel, v) } +func (ec *executionContext) marshalOAlertFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertFacets(ctx context.Context, sel ast.SelectionSet, v *alerts.AlertFacets) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._AlertFacets(ctx, sel, v) +} + func (ec *executionContext) unmarshalOAlertOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋalertsᚐAlertOrder(ctx context.Context, v any) (*alerts.AlertOrder, error) { if v == nil { return nil, nil diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 69ae6eec0..5a554d169 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -59,6 +59,7 @@ type Config = graphql.Config[ResolverRoot, DirectiveRoot, ComplexityRoot] type ResolverRoot interface { ActivityLogEntryConnection() ActivityLogEntryConnectionResolver + AlertConnection() AlertConnectionResolver Application() ApplicationResolver ApplicationConnection() ApplicationConnectionResolver ApplicationInstance() ApplicationInstanceResolver @@ -212,6 +213,7 @@ type ComplexityRoot struct { AlertConnection struct { Edges func(childComplexity int) int + Facets func(childComplexity int) int Nodes func(childComplexity int) int PageInfo func(childComplexity int) int } @@ -221,6 +223,16 @@ type ComplexityRoot struct { Node func(childComplexity int) int } + AlertFacets struct { + Environments func(childComplexity int) int + States func(childComplexity int) int + } + + AlertStateFacetItem struct { + Count func(childComplexity int) int + State func(childComplexity int) int + } + AllowTeamAccessToUnleashPayload struct { Unleash func(childComplexity int) int } @@ -3854,6 +3866,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.AlertConnection.Edges(childComplexity), true + case "AlertConnection.facets": + if e.ComplexityRoot.AlertConnection.Facets == nil { + break + } + + return e.ComplexityRoot.AlertConnection.Facets(childComplexity), true + case "AlertConnection.nodes": if e.ComplexityRoot.AlertConnection.Nodes == nil { break @@ -3882,6 +3901,34 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.AlertEdge.Node(childComplexity), true + case "AlertFacets.environments": + if e.ComplexityRoot.AlertFacets.Environments == nil { + break + } + + return e.ComplexityRoot.AlertFacets.Environments(childComplexity), true + + case "AlertFacets.states": + if e.ComplexityRoot.AlertFacets.States == nil { + break + } + + return e.ComplexityRoot.AlertFacets.States(childComplexity), true + + case "AlertStateFacetItem.count": + if e.ComplexityRoot.AlertStateFacetItem.Count == nil { + break + } + + return e.ComplexityRoot.AlertStateFacetItem.Count(childComplexity), true + + case "AlertStateFacetItem.state": + if e.ComplexityRoot.AlertStateFacetItem.State == nil { + break + } + + return e.ComplexityRoot.AlertStateFacetItem.State(childComplexity), true + case "AllowTeamAccessToUnleashPayload.unleash": if e.ComplexityRoot.AllowTeamAccessToUnleashPayload.Unleash == nil { break @@ -20010,6 +20057,34 @@ type AlertConnection { List of edges. """ edges: [AlertEdge!]! + + """ + Facets for alerts. Provides distribution counts to help narrow down results. + Facet counts are computed over the full result set (ignoring pagination) but respect the current filter. + """ + facets: AlertFacets +} + +""" +Facets for alerts, providing distribution counts across different dimensions. +""" +type AlertFacets { + "Distribution of alerts by environment." + environments: [StringFacetItem!]! + + "Distribution of alerts by state." + states: [AlertStateFacetItem!]! +} + +""" +A single facet item for alert states. +""" +type AlertStateFacetItem { + "The alert state." + state: AlertState! + + "Number of matching alerts." + count: Int! } """ @@ -32762,6 +32837,8 @@ func (ec *executionContext) childFields_AlertConnection(ctx context.Context, fie return ec.fieldContext_AlertConnection_nodes(ctx, field) case "edges": return ec.fieldContext_AlertConnection_edges(ctx, field) + case "facets": + return ec.fieldContext_AlertConnection_facets(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type AlertConnection", field.Name) } @@ -32776,6 +32853,26 @@ func (ec *executionContext) childFields_AlertEdge(ctx context.Context, field gra return nil, fmt.Errorf("no field named %q was found under type AlertEdge", field.Name) } +func (ec *executionContext) childFields_AlertFacets(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "environments": + return ec.fieldContext_AlertFacets_environments(ctx, field) + case "states": + return ec.fieldContext_AlertFacets_states(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type AlertFacets", field.Name) +} + +func (ec *executionContext) childFields_AlertStateFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "state": + return ec.fieldContext_AlertStateFacetItem_state(ctx, field) + case "count": + return ec.fieldContext_AlertStateFacetItem_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type AlertStateFacetItem", field.Name) +} + func (ec *executionContext) childFields_AllowTeamAccessToUnleashPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "unleash": diff --git a/internal/graph/gengql/teams.generated.go b/internal/graph/gengql/teams.generated.go index f8b2f2764..0480e03c0 100644 --- a/internal/graph/gengql/teams.generated.go +++ b/internal/graph/gengql/teams.generated.go @@ -61,7 +61,7 @@ type TeamResolver interface { DeleteKey(ctx context.Context, obj *team.Team, key string) (*team.TeamDeleteKey, error) InventoryCounts(ctx context.Context, obj *team.Team) (*team.TeamInventoryCounts, error) ActivityLog(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *activitylog.ActivityLogFilter) (*activitylog.ActivityLogEntryConnection, error) - Alerts(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.Connection[alerts.Alert], error) + Alerts(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter], error) Applications(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *application.ApplicationOrder, filter *application.TeamApplicationsFilter) (*pagination.FacetableConnection[*application.Application, *application.TeamApplicationsFilter], error) BigQueryDatasets(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *bigquery.BigQueryDatasetOrder, filter *bigquery.BigQueryDatasetFilter) (*pagination.FacetableConnection[*bigquery.BigQueryDataset, *bigquery.BigQueryDatasetFilter], error) Buckets(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *bucket.BucketOrder, filter *bucket.BucketFilter) (*pagination.FacetableConnection[*bucket.Bucket, *bucket.BucketFilter], error) @@ -94,7 +94,7 @@ type TeamDeleteKeyResolver interface { } type TeamEnvironmentResolver interface { Team(ctx context.Context, obj *team.TeamEnvironment) (*team.Team, error) - Alerts(ctx context.Context, obj *team.TeamEnvironment, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.Connection[alerts.Alert], error) + Alerts(ctx context.Context, obj *team.TeamEnvironment, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *alerts.AlertOrder, filter *alerts.TeamAlertsFilter) (*pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter], error) Application(ctx context.Context, obj *team.TeamEnvironment, name string) (*application.Application, error) BigQueryDataset(ctx context.Context, obj *team.TeamEnvironment, name string) (*bigquery.BigQueryDataset, error) Bucket(ctx context.Context, obj *team.TeamEnvironment, name string) (*bucket.Bucket, error) @@ -2238,8 +2238,8 @@ func (ec *executionContext) _Team_alerts(ctx context.Context, field graphql.Coll return ec.Resolvers.Team().Alerts(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*alerts.AlertOrder), fc.Args["filter"].(*alerts.TeamAlertsFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[alerts.Alert]) graphql.Marshaler { - return ec.marshalNAlertConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) graphql.Marshaler { + return ec.marshalNAlertConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) }, true, true, @@ -4340,8 +4340,8 @@ func (ec *executionContext) _TeamEnvironment_alerts(ctx context.Context, field g return ec.Resolvers.TeamEnvironment().Alerts(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*alerts.AlertOrder), fc.Args["filter"].(*alerts.TeamAlertsFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[alerts.Alert]) graphql.Marshaler { - return ec.marshalNAlertConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[alerts.Alert, *alerts.TeamAlertsFilter]) graphql.Marshaler { + return ec.marshalNAlertConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) }, true, true, diff --git a/internal/graph/schema/alerts.graphqls b/internal/graph/schema/alerts.graphqls index 640503bf3..62b35da69 100644 --- a/internal/graph/schema/alerts.graphqls +++ b/internal/graph/schema/alerts.graphqls @@ -197,6 +197,34 @@ type AlertConnection { List of edges. """ edges: [AlertEdge!]! + + """ + Facets for alerts. Provides distribution counts to help narrow down results. + Facet counts are computed over the full result set (ignoring pagination) but respect the current filter. + """ + facets: AlertFacets +} + +""" +Facets for alerts, providing distribution counts across different dimensions. +""" +type AlertFacets { + "Distribution of alerts by environment." + environments: [StringFacetItem!]! + + "Distribution of alerts by state." + states: [AlertStateFacetItem!]! +} + +""" +A single facet item for alert states. +""" +type AlertStateFacetItem { + "The alert state." + state: AlertState! + + "Number of matching alerts." + count: Int! } """ From d3edc3a30e16eb455ea9e01c1f2dca76c18d633d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 10:32:23 +0200 Subject: [PATCH 05/11] test(alerts): add facets tests --- internal/alerts/facets_test.go | 137 +++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 internal/alerts/facets_test.go diff --git a/internal/alerts/facets_test.go b/internal/alerts/facets_test.go new file mode 100644 index 000000000..df40296f3 --- /dev/null +++ b/internal/alerts/facets_test.go @@ -0,0 +1,137 @@ +package alerts + +import ( + "context" + "reflect" + "testing" + + "github.com/nais/api/internal/graph/model" + "github.com/nais/api/internal/slug" +) + +func makeAlert(name, env string, state AlertState) Alert { + return &PrometheusAlert{ + BaseAlert: BaseAlert{ + Name: name, + State: state, + TeamSlug: slug.Slug("myteam"), + EnvironmentName: env, + }, + } +} + +func TestAlertFacets_Environments(t *testing.T) { + ctx := context.Background() + + all := []Alert{ + makeAlert("a1", "prod", AlertStateFiring), + makeAlert("a2", "prod", AlertStateInactive), + makeAlert("a3", "dev", AlertStateFiring), + makeAlert("a4", "dev", AlertStatePending), + } + + tests := []struct { + name string + filter *TeamAlertsFilter + want []model.StringFacetItem + }{ + { + name: "no filter: all counts match totals", + filter: nil, + want: []model.StringFacetItem{ + {Value: "dev", Count: 2}, + {Value: "prod", Count: 2}, + }, + }, + { + name: "filter by environment: other env count is zero but still present", + filter: &TeamAlertsFilter{Environments: []string{"prod"}}, + want: []model.StringFacetItem{ + {Value: "dev", Count: 0}, + {Value: "prod", Count: 2}, + }, + }, + { + name: "filter by state: env counts reflect matching alerts", + filter: &TeamAlertsFilter{States: []AlertState{AlertStateFiring}}, + want: []model.StringFacetItem{ + {Value: "dev", Count: 1}, + {Value: "prod", Count: 1}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f := &AlertFacets{AllAlerts: all, Filter: tt.filter} + got := f.Environments(ctx) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Environments =\n %v\nwant\n %v", got, tt.want) + } + }) + } +} + +func TestAlertFacets_States(t *testing.T) { + ctx := context.Background() + + all := []Alert{ + makeAlert("a1", "prod", AlertStateFiring), + makeAlert("a2", "prod", AlertStateInactive), + makeAlert("a3", "dev", AlertStateFiring), + makeAlert("a4", "dev", AlertStatePending), + } + + tests := []struct { + name string + filter *TeamAlertsFilter + want []AlertStateFacetItem + }{ + { + name: "no filter: all states present with full counts", + filter: nil, + want: []AlertStateFacetItem{ + {State: AlertStateFiring, Count: 2}, + {State: AlertStateInactive, Count: 1}, + {State: AlertStatePending, Count: 1}, + }, + }, + { + name: "filter by state: non-matching states have count 0", + filter: &TeamAlertsFilter{States: []AlertState{AlertStateFiring}}, + want: []AlertStateFacetItem{ + {State: AlertStateFiring, Count: 2}, + {State: AlertStateInactive, Count: 0}, + {State: AlertStatePending, Count: 0}, + }, + }, + { + name: "filter by environment: state counts reflect only matching env", + filter: &TeamAlertsFilter{Environments: []string{"prod"}}, + want: []AlertStateFacetItem{ + {State: AlertStateFiring, Count: 1}, + {State: AlertStateInactive, Count: 1}, + {State: AlertStatePending, Count: 0}, + }, + }, + { + name: "empty alerts: no facet items", + filter: nil, + want: []AlertStateFacetItem{}, + }, + } + + for i, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + alertsSlice := all + if i == len(tests)-1 { + alertsSlice = nil + } + f := &AlertFacets{AllAlerts: alertsSlice, Filter: tt.filter} + got := f.States(ctx) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("States =\n %v\nwant\n %v", got, tt.want) + } + }) + } +} From de7c9e0facea8cf37278e16b35d645e52923d8b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 10:54:24 +0200 Subject: [PATCH 06/11] test(issue): fix misleading test case name in TestBuildFacets --- internal/issue/facets_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/issue/facets_test.go b/internal/issue/facets_test.go index 1211810f7..f55b6e5b5 100644 --- a/internal/issue/facets_test.go +++ b/internal/issue/facets_test.go @@ -25,7 +25,7 @@ func TestBuildFacets(t *testing.T) { wantIssueTypes []IssueTypeFacetItem }{ { - name: "no filter: filtered_count equals total_count", + name: "mixed rows: seeded values with zero filtered_count are included", rows: rows, wantSeverities: []SeverityFacetItem{ {Severity: SeverityCritical, Count: 4}, From 5f16765d1999dcf87dd1830719202129e5e1801b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 11:17:39 +0200 Subject: [PATCH 07/11] refactor(graph): rename SeverityFacetItem and ResourceTypeFacetItem to IssueSeverityFacetItem and IssueResourceTypeFacetItem --- internal/graph/gengql/issues.generated.go | 442 +++++++++++----------- internal/graph/gengql/root_.generated.go | 124 +++--- internal/graph/schema/issues.graphqls | 8 +- internal/issue/facets.go | 12 +- internal/issue/facets_test.go | 16 +- internal/issue/model.go | 12 +- 6 files changed, 307 insertions(+), 307 deletions(-) diff --git a/internal/graph/gengql/issues.generated.go b/internal/graph/gengql/issues.generated.go index 025896d31..fb56b878a 100644 --- a/internal/graph/gengql/issues.generated.go +++ b/internal/graph/gengql/issues.generated.go @@ -1289,8 +1289,8 @@ func (ec *executionContext) _IssueFacets_severities(ctx context.Context, field g return obj.Severities, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []issue.SeverityFacetItem) graphql.Marshaler { - return ec.marshalNSeverityFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []issue.IssueSeverityFacetItem) graphql.Marshaler { + return ec.marshalNIssueSeverityFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueSeverityFacetItemᚄ(ctx, selections, v) }, true, true, @@ -1303,7 +1303,7 @@ func (ec *executionContext) fieldContext_IssueFacets_severities(_ context.Contex IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_SeverityFacetItem(ctx, field) + return ec.childFields_IssueSeverityFacetItem(ctx, field) }, } return fc, nil @@ -1321,8 +1321,8 @@ func (ec *executionContext) _IssueFacets_resourceTypes(ctx context.Context, fiel return obj.ResourceTypes, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []issue.ResourceTypeFacetItem) graphql.Marshaler { - return ec.marshalNResourceTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []issue.IssueResourceTypeFacetItem) graphql.Marshaler { + return ec.marshalNIssueResourceTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueResourceTypeFacetItemᚄ(ctx, selections, v) }, true, true, @@ -1335,7 +1335,7 @@ func (ec *executionContext) fieldContext_IssueFacets_resourceTypes(_ context.Con IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_ResourceTypeFacetItem(ctx, field) + return ec.childFields_IssueResourceTypeFacetItem(ctx, field) }, } return fc, nil @@ -1373,6 +1373,98 @@ func (ec *executionContext) fieldContext_IssueFacets_issueTypes(_ context.Contex return fc, nil } +func (ec *executionContext) _IssueResourceTypeFacetItem_resourceType(ctx context.Context, field graphql.CollectedField, obj *issue.IssueResourceTypeFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueResourceTypeFacetItem_resourceType(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ResourceType, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v issue.ResourceType) graphql.Marshaler { + return ec.marshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueResourceTypeFacetItem_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("IssueResourceTypeFacetItem", field, false, false, errors.New("field of type ResourceType does not have child fields")) +} + +func (ec *executionContext) _IssueResourceTypeFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *issue.IssueResourceTypeFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueResourceTypeFacetItem_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueResourceTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("IssueResourceTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +} + +func (ec *executionContext) _IssueSeverityFacetItem_severity(ctx context.Context, field graphql.CollectedField, obj *issue.IssueSeverityFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueSeverityFacetItem_severity(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Severity, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v issue.Severity) graphql.Marshaler { + return ec.marshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueSeverityFacetItem_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("IssueSeverityFacetItem", field, false, false, errors.New("field of type Severity does not have child fields")) +} + +func (ec *executionContext) _IssueSeverityFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *issue.IssueSeverityFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_IssueSeverityFacetItem_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_IssueSeverityFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("IssueSeverityFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +} + func (ec *executionContext) _IssueTypeFacetItem_issueType(ctx context.Context, field graphql.CollectedField, obj *issue.IssueTypeFacetItem) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1974,98 +2066,6 @@ func (ec *executionContext) fieldContext_OpenSearchIssue_event(_ context.Context return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _ResourceTypeFacetItem_resourceType(ctx context.Context, field graphql.CollectedField, obj *issue.ResourceTypeFacetItem) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_ResourceTypeFacetItem_resourceType(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.ResourceType, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v issue.ResourceType) graphql.Marshaler { - return ec.marshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_ResourceTypeFacetItem_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("ResourceTypeFacetItem", field, false, false, errors.New("field of type ResourceType does not have child fields")) -} - -func (ec *executionContext) _ResourceTypeFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *issue.ResourceTypeFacetItem) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_ResourceTypeFacetItem_count(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Count, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_ResourceTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("ResourceTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) -} - -func (ec *executionContext) _SeverityFacetItem_severity(ctx context.Context, field graphql.CollectedField, obj *issue.SeverityFacetItem) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_SeverityFacetItem_severity(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Severity, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v issue.Severity) graphql.Marshaler { - return ec.marshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_SeverityFacetItem_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("SeverityFacetItem", field, false, false, errors.New("field of type Severity does not have child fields")) -} - -func (ec *executionContext) _SeverityFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *issue.SeverityFacetItem) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_SeverityFacetItem_count(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Count, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_SeverityFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("SeverityFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) -} - func (ec *executionContext) _SqlInstanceStateIssue_id(ctx context.Context, field graphql.CollectedField, obj *issue.SqlInstanceStateIssue) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -4299,6 +4299,94 @@ func (ec *executionContext) _IssueFacets(ctx context.Context, sel ast.SelectionS return out } +var issueResourceTypeFacetItemImplementors = []string{"IssueResourceTypeFacetItem"} + +func (ec *executionContext) _IssueResourceTypeFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.IssueResourceTypeFacetItem) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, issueResourceTypeFacetItemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("IssueResourceTypeFacetItem") + case "resourceType": + out.Values[i] = ec._IssueResourceTypeFacetItem_resourceType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "count": + out.Values[i] = ec._IssueResourceTypeFacetItem_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var issueSeverityFacetItemImplementors = []string{"IssueSeverityFacetItem"} + +func (ec *executionContext) _IssueSeverityFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.IssueSeverityFacetItem) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, issueSeverityFacetItemImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("IssueSeverityFacetItem") + case "severity": + out.Values[i] = ec._IssueSeverityFacetItem_severity(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "count": + out.Values[i] = ec._IssueSeverityFacetItem_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var issueTypeFacetItemImplementors = []string{"IssueTypeFacetItem"} func (ec *executionContext) _IssueTypeFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.IssueTypeFacetItem) graphql.Marshaler { @@ -4832,94 +4920,6 @@ func (ec *executionContext) _OpenSearchIssue(ctx context.Context, sel ast.Select return out } -var resourceTypeFacetItemImplementors = []string{"ResourceTypeFacetItem"} - -func (ec *executionContext) _ResourceTypeFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.ResourceTypeFacetItem) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, resourceTypeFacetItemImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("ResourceTypeFacetItem") - case "resourceType": - out.Values[i] = ec._ResourceTypeFacetItem_resourceType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "count": - out.Values[i] = ec._ResourceTypeFacetItem_count(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var severityFacetItemImplementors = []string{"SeverityFacetItem"} - -func (ec *executionContext) _SeverityFacetItem(ctx context.Context, sel ast.SelectionSet, obj *issue.SeverityFacetItem) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, severityFacetItemImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("SeverityFacetItem") - case "severity": - out.Values[i] = ec._SeverityFacetItem_severity(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "count": - out.Values[i] = ec._SeverityFacetItem_count(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - var sqlInstanceStateIssueImplementors = []string{"SqlInstanceStateIssue", "Issue", "Node"} func (ec *executionContext) _SqlInstanceStateIssue(ctx context.Context, sel ast.SelectionSet, obj *issue.SqlInstanceStateIssue) graphql.Marshaler { @@ -5764,25 +5764,15 @@ func (ec *executionContext) marshalNIssueOrderField2githubᚗcomᚋnaisᚋapiᚋ return v } -func (ec *executionContext) unmarshalNIssueType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueType(ctx context.Context, v any) (issue.IssueType, error) { - var res issue.IssueType - err := res.UnmarshalGQL(v) - return res, graphql.ErrorOnPath(ctx, err) +func (ec *executionContext) marshalNIssueResourceTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueResourceTypeFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.IssueResourceTypeFacetItem) graphql.Marshaler { + return ec._IssueResourceTypeFacetItem(ctx, sel, &v) } -func (ec *executionContext) marshalNIssueType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueType(ctx context.Context, sel ast.SelectionSet, v issue.IssueType) graphql.Marshaler { - return v -} - -func (ec *executionContext) marshalNIssueTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.IssueTypeFacetItem) graphql.Marshaler { - return ec._IssueTypeFacetItem(ctx, sel, &v) -} - -func (ec *executionContext) marshalNIssueTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.IssueTypeFacetItem) graphql.Marshaler { +func (ec *executionContext) marshalNIssueResourceTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueResourceTypeFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.IssueResourceTypeFacetItem) graphql.Marshaler { ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) fc.Result = &v[i] - return ec.marshalNIssueTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItem(ctx, sel, v[i]) + return ec.marshalNIssueResourceTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueResourceTypeFacetItem(ctx, sel, v[i]) }) for _, e := range ret { @@ -5794,25 +5784,15 @@ func (ec *executionContext) marshalNIssueTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋ return ret } -func (ec *executionContext) unmarshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx context.Context, v any) (issue.ResourceType, error) { - var res issue.ResourceType - err := res.UnmarshalGQL(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx context.Context, sel ast.SelectionSet, v issue.ResourceType) graphql.Marshaler { - return v -} - -func (ec *executionContext) marshalNResourceTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.ResourceTypeFacetItem) graphql.Marshaler { - return ec._ResourceTypeFacetItem(ctx, sel, &v) +func (ec *executionContext) marshalNIssueSeverityFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueSeverityFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.IssueSeverityFacetItem) graphql.Marshaler { + return ec._IssueSeverityFacetItem(ctx, sel, &v) } -func (ec *executionContext) marshalNResourceTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.ResourceTypeFacetItem) graphql.Marshaler { +func (ec *executionContext) marshalNIssueSeverityFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueSeverityFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.IssueSeverityFacetItem) graphql.Marshaler { ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) fc.Result = &v[i] - return ec.marshalNResourceTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceTypeFacetItem(ctx, sel, v[i]) + return ec.marshalNIssueSeverityFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueSeverityFacetItem(ctx, sel, v[i]) }) for _, e := range ret { @@ -5824,25 +5804,25 @@ func (ec *executionContext) marshalNResourceTypeFacetItem2ᚕgithubᚗcomᚋnais return ret } -func (ec *executionContext) unmarshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx context.Context, v any) (issue.Severity, error) { - var res issue.Severity +func (ec *executionContext) unmarshalNIssueType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueType(ctx context.Context, v any) (issue.IssueType, error) { + var res issue.IssueType err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx context.Context, sel ast.SelectionSet, v issue.Severity) graphql.Marshaler { +func (ec *executionContext) marshalNIssueType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueType(ctx context.Context, sel ast.SelectionSet, v issue.IssueType) graphql.Marshaler { return v } -func (ec *executionContext) marshalNSeverityFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.SeverityFacetItem) graphql.Marshaler { - return ec._SeverityFacetItem(ctx, sel, &v) +func (ec *executionContext) marshalNIssueTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItem(ctx context.Context, sel ast.SelectionSet, v issue.IssueTypeFacetItem) graphql.Marshaler { + return ec._IssueTypeFacetItem(ctx, sel, &v) } -func (ec *executionContext) marshalNSeverityFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.SeverityFacetItem) graphql.Marshaler { +func (ec *executionContext) marshalNIssueTypeFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []issue.IssueTypeFacetItem) graphql.Marshaler { ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) fc.Result = &v[i] - return ec.marshalNSeverityFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverityFacetItem(ctx, sel, v[i]) + return ec.marshalNIssueTypeFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐIssueTypeFacetItem(ctx, sel, v[i]) }) for _, e := range ret { @@ -5854,6 +5834,26 @@ func (ec *executionContext) marshalNSeverityFacetItem2ᚕgithubᚗcomᚋnaisᚋa return ret } +func (ec *executionContext) unmarshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx context.Context, v any) (issue.ResourceType, error) { + var res issue.ResourceType + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐResourceType(ctx context.Context, sel ast.SelectionSet, v issue.ResourceType) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx context.Context, v any) (issue.Severity, error) { + var res issue.Severity + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNSeverity2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐSeverity(ctx context.Context, sel ast.SelectionSet, v issue.Severity) graphql.Marshaler { + return v +} + func (ec *executionContext) unmarshalNWorkloadProblemType2githubᚗcomᚋnaisᚋapiᚋinternalᚋissueᚐWorkloadProblemType(ctx context.Context, v any) (issue.WorkloadProblemType, error) { var res issue.WorkloadProblemType err := res.UnmarshalGQL(v) diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 5a554d169..dc7837338 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -1171,6 +1171,16 @@ type ComplexityRoot struct { Severities func(childComplexity int) int } + IssueResourceTypeFacetItem struct { + Count func(childComplexity int) int + ResourceType func(childComplexity int) int + } + + IssueSeverityFacetItem struct { + Count func(childComplexity int) int + Severity func(childComplexity int) int + } + IssueTypeFacetItem struct { Count func(childComplexity int) int IssueType func(childComplexity int) int @@ -2075,11 +2085,6 @@ type ComplexityRoot struct { Value func(childComplexity int) int } - ResourceTypeFacetItem struct { - Count func(childComplexity int) int - ResourceType func(childComplexity int) int - } - RestartApplicationPayload struct { Application func(childComplexity int) int } @@ -2545,11 +2550,6 @@ type ComplexityRoot struct { Member func(childComplexity int) int } - SeverityFacetItem struct { - Count func(childComplexity int) int - Severity func(childComplexity int) int - } - SqlDatabase struct { Charset func(childComplexity int) int Collation func(childComplexity int) int @@ -7679,6 +7679,34 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.IssueFacets.Severities(childComplexity), true + case "IssueResourceTypeFacetItem.count": + if e.ComplexityRoot.IssueResourceTypeFacetItem.Count == nil { + break + } + + return e.ComplexityRoot.IssueResourceTypeFacetItem.Count(childComplexity), true + + case "IssueResourceTypeFacetItem.resourceType": + if e.ComplexityRoot.IssueResourceTypeFacetItem.ResourceType == nil { + break + } + + return e.ComplexityRoot.IssueResourceTypeFacetItem.ResourceType(childComplexity), true + + case "IssueSeverityFacetItem.count": + if e.ComplexityRoot.IssueSeverityFacetItem.Count == nil { + break + } + + return e.ComplexityRoot.IssueSeverityFacetItem.Count(childComplexity), true + + case "IssueSeverityFacetItem.severity": + if e.ComplexityRoot.IssueSeverityFacetItem.Severity == nil { + break + } + + return e.ComplexityRoot.IssueSeverityFacetItem.Severity(childComplexity), true + case "IssueTypeFacetItem.count": if e.ComplexityRoot.IssueTypeFacetItem.Count == nil { break @@ -12158,20 +12186,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ResourceLabel.Value(childComplexity), true - case "ResourceTypeFacetItem.count": - if e.ComplexityRoot.ResourceTypeFacetItem.Count == nil { - break - } - - return e.ComplexityRoot.ResourceTypeFacetItem.Count(childComplexity), true - - case "ResourceTypeFacetItem.resourceType": - if e.ComplexityRoot.ResourceTypeFacetItem.ResourceType == nil { - break - } - - return e.ComplexityRoot.ResourceTypeFacetItem.ResourceType(childComplexity), true - case "RestartApplicationPayload.application": if e.ComplexityRoot.RestartApplicationPayload.Application == nil { break @@ -14181,20 +14195,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SetTeamMemberRolePayload.Member(childComplexity), true - case "SeverityFacetItem.count": - if e.ComplexityRoot.SeverityFacetItem.Count == nil { - break - } - - return e.ComplexityRoot.SeverityFacetItem.Count(childComplexity), true - - case "SeverityFacetItem.severity": - if e.ComplexityRoot.SeverityFacetItem.Severity == nil { - break - } - - return e.ComplexityRoot.SeverityFacetItem.Severity(childComplexity), true - case "SqlDatabase.charset": if e.ComplexityRoot.SqlDatabase.Charset == nil { break @@ -23366,12 +23366,12 @@ type IssueFacets { """ Distribution of issues by severity. """ - severities: [SeverityFacetItem!]! + severities: [IssueSeverityFacetItem!]! """ Distribution of issues by resource type. """ - resourceTypes: [ResourceTypeFacetItem!]! + resourceTypes: [IssueResourceTypeFacetItem!]! """ Distribution of issues by issue type. @@ -23382,7 +23382,7 @@ type IssueFacets { """ A single facet item for issue severities. """ -type SeverityFacetItem { +type IssueSeverityFacetItem { "The severity." severity: Severity! @@ -23393,7 +23393,7 @@ type SeverityFacetItem { """ A single facet item for resource types. """ -type ResourceTypeFacetItem { +type IssueResourceTypeFacetItem { "The resource type." resourceType: ResourceType! @@ -34317,6 +34317,26 @@ func (ec *executionContext) childFields_IssueFacets(ctx context.Context, field g return nil, fmt.Errorf("no field named %q was found under type IssueFacets", field.Name) } +func (ec *executionContext) childFields_IssueResourceTypeFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "resourceType": + return ec.fieldContext_IssueResourceTypeFacetItem_resourceType(ctx, field) + case "count": + return ec.fieldContext_IssueResourceTypeFacetItem_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type IssueResourceTypeFacetItem", field.Name) +} + +func (ec *executionContext) childFields_IssueSeverityFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "severity": + return ec.fieldContext_IssueSeverityFacetItem_severity(ctx, field) + case "count": + return ec.fieldContext_IssueSeverityFacetItem_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type IssueSeverityFacetItem", field.Name) +} + func (ec *executionContext) childFields_IssueTypeFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "issueType": @@ -35451,16 +35471,6 @@ func (ec *executionContext) childFields_ResourceLabel(ctx context.Context, field return nil, fmt.Errorf("no field named %q was found under type ResourceLabel", field.Name) } -func (ec *executionContext) childFields_ResourceTypeFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "resourceType": - return ec.fieldContext_ResourceTypeFacetItem_resourceType(ctx, field) - case "count": - return ec.fieldContext_ResourceTypeFacetItem_count(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ResourceTypeFacetItem", field.Name) -} - func (ec *executionContext) childFields_RestartApplicationPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "application": @@ -35929,16 +35939,6 @@ func (ec *executionContext) childFields_SetTeamMemberRolePayload(ctx context.Con return nil, fmt.Errorf("no field named %q was found under type SetTeamMemberRolePayload", field.Name) } -func (ec *executionContext) childFields_SeverityFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "severity": - return ec.fieldContext_SeverityFacetItem_severity(ctx, field) - case "count": - return ec.fieldContext_SeverityFacetItem_count(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type SeverityFacetItem", field.Name) -} - func (ec *executionContext) childFields_SqlDatabase(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": diff --git a/internal/graph/schema/issues.graphqls b/internal/graph/schema/issues.graphqls index 792406311..81d65dbd6 100644 --- a/internal/graph/schema/issues.graphqls +++ b/internal/graph/schema/issues.graphqls @@ -96,12 +96,12 @@ type IssueFacets { """ Distribution of issues by severity. """ - severities: [SeverityFacetItem!]! + severities: [IssueSeverityFacetItem!]! """ Distribution of issues by resource type. """ - resourceTypes: [ResourceTypeFacetItem!]! + resourceTypes: [IssueResourceTypeFacetItem!]! """ Distribution of issues by issue type. @@ -112,7 +112,7 @@ type IssueFacets { """ A single facet item for issue severities. """ -type SeverityFacetItem { +type IssueSeverityFacetItem { "The severity." severity: Severity! @@ -123,7 +123,7 @@ type SeverityFacetItem { """ A single facet item for resource types. """ -type ResourceTypeFacetItem { +type IssueResourceTypeFacetItem { "The resource type." resourceType: ResourceType! diff --git a/internal/issue/facets.go b/internal/issue/facets.go index 8a05290c5..4815ae968 100644 --- a/internal/issue/facets.go +++ b/internal/issue/facets.go @@ -74,19 +74,19 @@ func buildFacets(rows []*issuesql.FacetsForIssuesRow) *IssueFacets { issueTypeCounts[it] += filtered } - severities := make([]SeverityFacetItem, 0, len(severityCounts)) + severities := make([]IssueSeverityFacetItem, 0, len(severityCounts)) for sev, count := range severityCounts { - severities = append(severities, SeverityFacetItem{Severity: sev, Count: count}) + severities = append(severities, IssueSeverityFacetItem{Severity: sev, Count: count}) } - slices.SortFunc(severities, func(a, b SeverityFacetItem) int { + slices.SortFunc(severities, func(a, b IssueSeverityFacetItem) int { return strings.Compare(a.Severity.String(), b.Severity.String()) }) - resourceTypes := make([]ResourceTypeFacetItem, 0, len(resourceTypeCounts)) + resourceTypes := make([]IssueResourceTypeFacetItem, 0, len(resourceTypeCounts)) for rt, count := range resourceTypeCounts { - resourceTypes = append(resourceTypes, ResourceTypeFacetItem{ResourceType: rt, Count: count}) + resourceTypes = append(resourceTypes, IssueResourceTypeFacetItem{ResourceType: rt, Count: count}) } - slices.SortFunc(resourceTypes, func(a, b ResourceTypeFacetItem) int { + slices.SortFunc(resourceTypes, func(a, b IssueResourceTypeFacetItem) int { return strings.Compare(a.ResourceType.String(), b.ResourceType.String()) }) diff --git a/internal/issue/facets_test.go b/internal/issue/facets_test.go index f55b6e5b5..c63f32ee8 100644 --- a/internal/issue/facets_test.go +++ b/internal/issue/facets_test.go @@ -19,20 +19,20 @@ func TestBuildFacets(t *testing.T) { tests := []struct { name string rows []*issuesql.FacetsForIssuesRow - wantSeverities []SeverityFacetItem - wantResourceTypes []ResourceTypeFacetItem + wantSeverities []IssueSeverityFacetItem + wantResourceTypes []IssueResourceTypeFacetItem wantEnvironments []model.StringFacetItem wantIssueTypes []IssueTypeFacetItem }{ { name: "mixed rows: seeded values with zero filtered_count are included", rows: rows, - wantSeverities: []SeverityFacetItem{ + wantSeverities: []IssueSeverityFacetItem{ {Severity: SeverityCritical, Count: 4}, {Severity: SeverityTodo, Count: 0}, {Severity: SeverityWarning, Count: 2}, }, - wantResourceTypes: []ResourceTypeFacetItem{ + wantResourceTypes: []IssueResourceTypeFacetItem{ {ResourceType: ResourceTypeApplication, Count: 4}, {ResourceType: ResourceTypeJob, Count: 2}, {ResourceType: ResourceTypeSQLInstance, Count: 0}, @@ -53,11 +53,11 @@ func TestBuildFacets(t *testing.T) { {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "prod", IssueType: "DEPRECATED_INGRESS", TotalCount: 3, FilteredCount: 3}, {Severity: "WARNING", ResourceType: "JOB", Env: "dev", IssueType: "LAST_RUN_FAILED", TotalCount: 1, FilteredCount: 0}, }, - wantSeverities: []SeverityFacetItem{ + wantSeverities: []IssueSeverityFacetItem{ {Severity: SeverityCritical, Count: 3}, {Severity: SeverityWarning, Count: 0}, }, - wantResourceTypes: []ResourceTypeFacetItem{ + wantResourceTypes: []IssueResourceTypeFacetItem{ {ResourceType: ResourceTypeApplication, Count: 3}, {ResourceType: ResourceTypeJob, Count: 0}, }, @@ -73,8 +73,8 @@ func TestBuildFacets(t *testing.T) { { name: "empty rows returns empty facets", rows: nil, - wantSeverities: []SeverityFacetItem{}, - wantResourceTypes: []ResourceTypeFacetItem{}, + wantSeverities: []IssueSeverityFacetItem{}, + wantResourceTypes: []IssueResourceTypeFacetItem{}, wantEnvironments: []model.StringFacetItem{}, wantIssueTypes: []IssueTypeFacetItem{}, }, diff --git a/internal/issue/model.go b/internal/issue/model.go index 2b4a5b971..9a6e9b10a 100644 --- a/internal/issue/model.go +++ b/internal/issue/model.go @@ -288,18 +288,18 @@ func (c *IssueConnection) GetScope() *IssueScope { return c.scope } func (c *IssueConnection) GetFilter() *IssueFilter { return c.filter } type IssueFacets struct { - Environments []model.StringFacetItem `json:"environments"` - Severities []SeverityFacetItem `json:"severities"` - ResourceTypes []ResourceTypeFacetItem `json:"resourceTypes"` - IssueTypes []IssueTypeFacetItem `json:"issueTypes"` + Environments []model.StringFacetItem `json:"environments"` + Severities []IssueSeverityFacetItem `json:"severities"` + ResourceTypes []IssueResourceTypeFacetItem `json:"resourceTypes"` + IssueTypes []IssueTypeFacetItem `json:"issueTypes"` } -type SeverityFacetItem struct { +type IssueSeverityFacetItem struct { Severity Severity `json:"severity"` Count int `json:"count"` } -type ResourceTypeFacetItem struct { +type IssueResourceTypeFacetItem struct { ResourceType ResourceType `json:"resourceType"` Count int `json:"count"` } From 10724c3e19d8381541d7fb9245376a52c8945291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 11:31:56 +0200 Subject: [PATCH 08/11] refactor(issue): remove IssueScope, use IssueFilter for all issue constraints --- internal/graph/applications.resolvers.go | 14 +-- internal/graph/gengql/issues.generated.go | 119 +++++++++++++++++++++- internal/graph/issues.resolvers.go | 4 +- internal/graph/jobs.resolvers.go | 14 +-- internal/graph/opensearch.resolvers.go | 14 +-- internal/graph/sqlinstance.resolvers.go | 14 +-- internal/graph/valkey.resolvers.go | 14 +-- internal/issue/facets.go | 18 +--- internal/issue/issuesql/issue.sql.go | 34 ++----- internal/issue/model.go | 8 -- internal/issue/queries.go | 19 +--- internal/issue/queries/issue.sql | 20 +--- 12 files changed, 175 insertions(+), 117 deletions(-) diff --git a/internal/graph/applications.resolvers.go b/internal/graph/applications.resolvers.go index e4461d19f..e880f6f39 100644 --- a/internal/graph/applications.resolvers.go +++ b/internal/graph/applications.resolvers.go @@ -81,17 +81,17 @@ func (r *applicationResolver) Issues(ctx context.Context, obj *application.Appli return nil, err } - scope := &issue.IssueScope{ - ResourceName: obj.Name, - ResourceType: issue.ResourceTypeApplication, - Env: obj.EnvironmentName, + rt := issue.ResourceTypeApplication + f := &issue.IssueFilter{ + ResourceName: &obj.Name, + ResourceType: &rt, + Environments: []string{obj.EnvironmentName}, } - var f *issue.IssueFilter if filter != nil { - f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} + f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) } func (r *applicationResolver) History(ctx context.Context, obj *application.Application) ([]*instancegroup.ApplicationHistory, error) { diff --git a/internal/graph/gengql/issues.generated.go b/internal/graph/gengql/issues.generated.go index fb56b878a..65b8569cd 100644 --- a/internal/graph/gengql/issues.generated.go +++ b/internal/graph/gengql/issues.generated.go @@ -145,6 +145,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_id(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -168,6 +169,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_teamEnvironment(ctx con true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ApplicationRestartLoopIssue", @@ -200,6 +202,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_severity(ctx context.Co true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -223,6 +226,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_message(ctx context.Con true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -246,6 +250,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_workload(ctx context.Co true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ApplicationRestartLoopIssue", @@ -278,6 +283,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_restartCount(ctx contex true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_restartCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -301,6 +307,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_lastExitReason(ctx cont true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_lastExitReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -324,6 +331,7 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_lastExitTimestamp(ctx c true, ) } + func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_lastExitTimestamp(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type Time does not have child fields")) } @@ -347,6 +355,7 @@ func (ec *executionContext) _DeprecatedIngressIssue_id(ctx context.Context, fiel true, ) } + func (ec *executionContext) fieldContext_DeprecatedIngressIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -370,6 +379,7 @@ func (ec *executionContext) _DeprecatedIngressIssue_teamEnvironment(ctx context. true, ) } + func (ec *executionContext) fieldContext_DeprecatedIngressIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedIngressIssue", @@ -402,6 +412,7 @@ func (ec *executionContext) _DeprecatedIngressIssue_severity(ctx context.Context true, ) } + func (ec *executionContext) fieldContext_DeprecatedIngressIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -425,6 +436,7 @@ func (ec *executionContext) _DeprecatedIngressIssue_message(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_DeprecatedIngressIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -448,6 +460,7 @@ func (ec *executionContext) _DeprecatedIngressIssue_ingresses(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_DeprecatedIngressIssue_ingresses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -471,6 +484,7 @@ func (ec *executionContext) _DeprecatedIngressIssue_application(ctx context.Cont true, ) } + func (ec *executionContext) fieldContext_DeprecatedIngressIssue_application(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedIngressIssue", @@ -503,6 +517,7 @@ func (ec *executionContext) _DeprecatedRegistryIssue_id(ctx context.Context, fie true, ) } + func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedRegistryIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -526,6 +541,7 @@ func (ec *executionContext) _DeprecatedRegistryIssue_teamEnvironment(ctx context true, ) } + func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedRegistryIssue", @@ -558,6 +574,7 @@ func (ec *executionContext) _DeprecatedRegistryIssue_severity(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedRegistryIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -581,6 +598,7 @@ func (ec *executionContext) _DeprecatedRegistryIssue_message(ctx context.Context true, ) } + func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedRegistryIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -604,6 +622,7 @@ func (ec *executionContext) _DeprecatedRegistryIssue_workload(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedRegistryIssue", @@ -636,6 +655,7 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_id(ctx co true, ) } + func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -659,6 +679,7 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_teamEnvir true, ) } + func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ExternalIngressCriticalVulnerabilityIssue", @@ -691,6 +712,7 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_severity( true, ) } + func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -714,6 +736,7 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_message(c true, ) } + func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -737,6 +760,7 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_workload( true, ) } + func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ExternalIngressCriticalVulnerabilityIssue", @@ -769,6 +793,7 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_cvssScore true, ) } + func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_cvssScore(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type Float does not have child fields")) } @@ -792,6 +817,7 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_ingresses true, ) } + func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_ingresses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -815,6 +841,7 @@ func (ec *executionContext) _FailedSynchronizationIssue_id(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_FailedSynchronizationIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("FailedSynchronizationIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -838,6 +865,7 @@ func (ec *executionContext) _FailedSynchronizationIssue_teamEnvironment(ctx cont true, ) } + func (ec *executionContext) fieldContext_FailedSynchronizationIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "FailedSynchronizationIssue", @@ -870,6 +898,7 @@ func (ec *executionContext) _FailedSynchronizationIssue_severity(ctx context.Con true, ) } + func (ec *executionContext) fieldContext_FailedSynchronizationIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("FailedSynchronizationIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -893,6 +922,7 @@ func (ec *executionContext) _FailedSynchronizationIssue_message(ctx context.Cont true, ) } + func (ec *executionContext) fieldContext_FailedSynchronizationIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("FailedSynchronizationIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -916,6 +946,7 @@ func (ec *executionContext) _FailedSynchronizationIssue_workload(ctx context.Con true, ) } + func (ec *executionContext) fieldContext_FailedSynchronizationIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "FailedSynchronizationIssue", @@ -948,6 +979,7 @@ func (ec *executionContext) _InvalidSpecIssue_id(ctx context.Context, field grap true, ) } + func (ec *executionContext) fieldContext_InvalidSpecIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("InvalidSpecIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -971,6 +1003,7 @@ func (ec *executionContext) _InvalidSpecIssue_teamEnvironment(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_InvalidSpecIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "InvalidSpecIssue", @@ -1003,6 +1036,7 @@ func (ec *executionContext) _InvalidSpecIssue_severity(ctx context.Context, fiel true, ) } + func (ec *executionContext) fieldContext_InvalidSpecIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("InvalidSpecIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1026,6 +1060,7 @@ func (ec *executionContext) _InvalidSpecIssue_message(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_InvalidSpecIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("InvalidSpecIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1049,6 +1084,7 @@ func (ec *executionContext) _InvalidSpecIssue_workload(ctx context.Context, fiel true, ) } + func (ec *executionContext) fieldContext_InvalidSpecIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "InvalidSpecIssue", @@ -1081,6 +1117,7 @@ func (ec *executionContext) _IssueConnection_pageInfo(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_IssueConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1113,6 +1150,7 @@ func (ec *executionContext) _IssueConnection_nodes(ctx context.Context, field gr true, ) } + func (ec *executionContext) fieldContext_IssueConnection_nodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1145,6 +1183,7 @@ func (ec *executionContext) _IssueConnection_edges(ctx context.Context, field gr true, ) } + func (ec *executionContext) fieldContext_IssueConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1177,6 +1216,7 @@ func (ec *executionContext) _IssueConnection_facets(ctx context.Context, field g false, ) } + func (ec *executionContext) fieldContext_IssueConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1209,6 +1249,7 @@ func (ec *executionContext) _IssueEdge_cursor(ctx context.Context, field graphql true, ) } + func (ec *executionContext) fieldContext_IssueEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueEdge", field, false, false, errors.New("field of type Cursor does not have child fields")) } @@ -1232,6 +1273,7 @@ func (ec *executionContext) _IssueEdge_node(ctx context.Context, field graphql.C true, ) } + func (ec *executionContext) fieldContext_IssueEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueEdge", @@ -1264,6 +1306,7 @@ func (ec *executionContext) _IssueFacets_environments(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_IssueFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1296,6 +1339,7 @@ func (ec *executionContext) _IssueFacets_severities(ctx context.Context, field g true, ) } + func (ec *executionContext) fieldContext_IssueFacets_severities(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1328,6 +1372,7 @@ func (ec *executionContext) _IssueFacets_resourceTypes(ctx context.Context, fiel true, ) } + func (ec *executionContext) fieldContext_IssueFacets_resourceTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1360,6 +1405,7 @@ func (ec *executionContext) _IssueFacets_issueTypes(ctx context.Context, field g true, ) } + func (ec *executionContext) fieldContext_IssueFacets_issueTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1392,6 +1438,7 @@ func (ec *executionContext) _IssueResourceTypeFacetItem_resourceType(ctx context true, ) } + func (ec *executionContext) fieldContext_IssueResourceTypeFacetItem_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueResourceTypeFacetItem", field, false, false, errors.New("field of type ResourceType does not have child fields")) } @@ -1415,6 +1462,7 @@ func (ec *executionContext) _IssueResourceTypeFacetItem_count(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_IssueResourceTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueResourceTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -1438,6 +1486,7 @@ func (ec *executionContext) _IssueSeverityFacetItem_severity(ctx context.Context true, ) } + func (ec *executionContext) fieldContext_IssueSeverityFacetItem_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueSeverityFacetItem", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1461,6 +1510,7 @@ func (ec *executionContext) _IssueSeverityFacetItem_count(ctx context.Context, f true, ) } + func (ec *executionContext) fieldContext_IssueSeverityFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueSeverityFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -1484,6 +1534,7 @@ func (ec *executionContext) _IssueTypeFacetItem_issueType(ctx context.Context, f true, ) } + func (ec *executionContext) fieldContext_IssueTypeFacetItem_issueType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueTypeFacetItem", field, false, false, errors.New("field of type IssueType does not have child fields")) } @@ -1507,6 +1558,7 @@ func (ec *executionContext) _IssueTypeFacetItem_count(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_IssueTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -1530,6 +1582,7 @@ func (ec *executionContext) _LastRunFailedIssue_id(ctx context.Context, field gr true, ) } + func (ec *executionContext) fieldContext_LastRunFailedIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("LastRunFailedIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1553,6 +1606,7 @@ func (ec *executionContext) _LastRunFailedIssue_teamEnvironment(ctx context.Cont true, ) } + func (ec *executionContext) fieldContext_LastRunFailedIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "LastRunFailedIssue", @@ -1585,6 +1639,7 @@ func (ec *executionContext) _LastRunFailedIssue_severity(ctx context.Context, fi true, ) } + func (ec *executionContext) fieldContext_LastRunFailedIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("LastRunFailedIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1608,6 +1663,7 @@ func (ec *executionContext) _LastRunFailedIssue_message(ctx context.Context, fie true, ) } + func (ec *executionContext) fieldContext_LastRunFailedIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("LastRunFailedIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1631,6 +1687,7 @@ func (ec *executionContext) _LastRunFailedIssue_job(ctx context.Context, field g true, ) } + func (ec *executionContext) fieldContext_LastRunFailedIssue_job(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "LastRunFailedIssue", @@ -1663,6 +1720,7 @@ func (ec *executionContext) _MissingSbomIssue_id(ctx context.Context, field grap true, ) } + func (ec *executionContext) fieldContext_MissingSbomIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("MissingSbomIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1686,6 +1744,7 @@ func (ec *executionContext) _MissingSbomIssue_teamEnvironment(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_MissingSbomIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "MissingSbomIssue", @@ -1718,6 +1777,7 @@ func (ec *executionContext) _MissingSbomIssue_severity(ctx context.Context, fiel true, ) } + func (ec *executionContext) fieldContext_MissingSbomIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("MissingSbomIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1741,6 +1801,7 @@ func (ec *executionContext) _MissingSbomIssue_message(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_MissingSbomIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("MissingSbomIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1764,6 +1825,7 @@ func (ec *executionContext) _MissingSbomIssue_workload(ctx context.Context, fiel true, ) } + func (ec *executionContext) fieldContext_MissingSbomIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "MissingSbomIssue", @@ -1796,6 +1858,7 @@ func (ec *executionContext) _NoRunningInstancesIssue_id(ctx context.Context, fie true, ) } + func (ec *executionContext) fieldContext_NoRunningInstancesIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("NoRunningInstancesIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1819,6 +1882,7 @@ func (ec *executionContext) _NoRunningInstancesIssue_teamEnvironment(ctx context true, ) } + func (ec *executionContext) fieldContext_NoRunningInstancesIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "NoRunningInstancesIssue", @@ -1851,6 +1915,7 @@ func (ec *executionContext) _NoRunningInstancesIssue_severity(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_NoRunningInstancesIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("NoRunningInstancesIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1874,6 +1939,7 @@ func (ec *executionContext) _NoRunningInstancesIssue_message(ctx context.Context true, ) } + func (ec *executionContext) fieldContext_NoRunningInstancesIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("NoRunningInstancesIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1897,6 +1963,7 @@ func (ec *executionContext) _NoRunningInstancesIssue_workload(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_NoRunningInstancesIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "NoRunningInstancesIssue", @@ -1929,6 +1996,7 @@ func (ec *executionContext) _OpenSearchIssue_id(ctx context.Context, field graph true, ) } + func (ec *executionContext) fieldContext_OpenSearchIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1952,6 +2020,7 @@ func (ec *executionContext) _OpenSearchIssue_teamEnvironment(ctx context.Context true, ) } + func (ec *executionContext) fieldContext_OpenSearchIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "OpenSearchIssue", @@ -1984,6 +2053,7 @@ func (ec *executionContext) _OpenSearchIssue_severity(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_OpenSearchIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2007,6 +2077,7 @@ func (ec *executionContext) _OpenSearchIssue_message(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_OpenSearchIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2030,6 +2101,7 @@ func (ec *executionContext) _OpenSearchIssue_openSearch(ctx context.Context, fie true, ) } + func (ec *executionContext) fieldContext_OpenSearchIssue_openSearch(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "OpenSearchIssue", @@ -2062,6 +2134,7 @@ func (ec *executionContext) _OpenSearchIssue_event(ctx context.Context, field gr true, ) } + func (ec *executionContext) fieldContext_OpenSearchIssue_event(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2085,6 +2158,7 @@ func (ec *executionContext) _SqlInstanceStateIssue_id(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_SqlInstanceStateIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2108,6 +2182,7 @@ func (ec *executionContext) _SqlInstanceStateIssue_teamEnvironment(ctx context.C true, ) } + func (ec *executionContext) fieldContext_SqlInstanceStateIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceStateIssue", @@ -2140,6 +2215,7 @@ func (ec *executionContext) _SqlInstanceStateIssue_severity(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_SqlInstanceStateIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2163,6 +2239,7 @@ func (ec *executionContext) _SqlInstanceStateIssue_message(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_SqlInstanceStateIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2186,6 +2263,7 @@ func (ec *executionContext) _SqlInstanceStateIssue_state(ctx context.Context, fi true, ) } + func (ec *executionContext) fieldContext_SqlInstanceStateIssue_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type SqlInstanceState does not have child fields")) } @@ -2209,6 +2287,7 @@ func (ec *executionContext) _SqlInstanceStateIssue_sqlInstance(ctx context.Conte true, ) } + func (ec *executionContext) fieldContext_SqlInstanceStateIssue_sqlInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceStateIssue", @@ -2241,6 +2320,7 @@ func (ec *executionContext) _SqlInstanceVersionIssue_id(ctx context.Context, fie true, ) } + func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceVersionIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2264,6 +2344,7 @@ func (ec *executionContext) _SqlInstanceVersionIssue_teamEnvironment(ctx context true, ) } + func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceVersionIssue", @@ -2296,6 +2377,7 @@ func (ec *executionContext) _SqlInstanceVersionIssue_severity(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceVersionIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2319,6 +2401,7 @@ func (ec *executionContext) _SqlInstanceVersionIssue_message(ctx context.Context true, ) } + func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceVersionIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2342,6 +2425,7 @@ func (ec *executionContext) _SqlInstanceVersionIssue_sqlInstance(ctx context.Con true, ) } + func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_sqlInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceVersionIssue", @@ -2374,6 +2458,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_id(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2397,6 +2482,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_teamEnvironment(ctx cont true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "UnleashReleaseChannelIssue", @@ -2429,6 +2515,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_severity(ctx context.Con true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2452,6 +2539,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_message(ctx context.Cont true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2475,6 +2563,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_unleash(ctx context.Cont true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_unleash(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "UnleashReleaseChannelIssue", @@ -2507,6 +2596,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_channelName(ctx context. true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_channelName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2530,6 +2620,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_majorVersion(ctx context true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_majorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -2553,6 +2644,7 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_currentMajorVersion(ctx true, ) } + func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_currentMajorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -2576,6 +2668,7 @@ func (ec *executionContext) _ValkeyIssue_id(ctx context.Context, field graphql.C true, ) } + func (ec *executionContext) fieldContext_ValkeyIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2599,6 +2692,7 @@ func (ec *executionContext) _ValkeyIssue_teamEnvironment(ctx context.Context, fi true, ) } + func (ec *executionContext) fieldContext_ValkeyIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ValkeyIssue", @@ -2631,6 +2725,7 @@ func (ec *executionContext) _ValkeyIssue_severity(ctx context.Context, field gra true, ) } + func (ec *executionContext) fieldContext_ValkeyIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2654,6 +2749,7 @@ func (ec *executionContext) _ValkeyIssue_message(ctx context.Context, field grap true, ) } + func (ec *executionContext) fieldContext_ValkeyIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2677,6 +2773,7 @@ func (ec *executionContext) _ValkeyIssue_valkey(ctx context.Context, field graph true, ) } + func (ec *executionContext) fieldContext_ValkeyIssue_valkey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ValkeyIssue", @@ -2709,6 +2806,7 @@ func (ec *executionContext) _ValkeyIssue_event(ctx context.Context, field graphq true, ) } + func (ec *executionContext) fieldContext_ValkeyIssue_event(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2732,6 +2830,7 @@ func (ec *executionContext) _VulnerableImageIssue_id(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_VulnerableImageIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2755,6 +2854,7 @@ func (ec *executionContext) _VulnerableImageIssue_teamEnvironment(ctx context.Co true, ) } + func (ec *executionContext) fieldContext_VulnerableImageIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "VulnerableImageIssue", @@ -2787,6 +2887,7 @@ func (ec *executionContext) _VulnerableImageIssue_severity(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_VulnerableImageIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2810,6 +2911,7 @@ func (ec *executionContext) _VulnerableImageIssue_message(ctx context.Context, f true, ) } + func (ec *executionContext) fieldContext_VulnerableImageIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2833,6 +2935,7 @@ func (ec *executionContext) _VulnerableImageIssue_workload(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_VulnerableImageIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "VulnerableImageIssue", @@ -2865,6 +2968,7 @@ func (ec *executionContext) _VulnerableImageIssue_riskScore(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_VulnerableImageIssue_riskScore(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -2888,6 +2992,7 @@ func (ec *executionContext) _VulnerableImageIssue_critical(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_VulnerableImageIssue_critical(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -2911,6 +3016,7 @@ func (ec *executionContext) _WorkloadProblemIssue_id(ctx context.Context, field true, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2934,6 +3040,7 @@ func (ec *executionContext) _WorkloadProblemIssue_teamEnvironment(ctx context.Co true, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "WorkloadProblemIssue", @@ -2966,6 +3073,7 @@ func (ec *executionContext) _WorkloadProblemIssue_severity(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2989,6 +3097,7 @@ func (ec *executionContext) _WorkloadProblemIssue_message(ctx context.Context, f true, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -3012,6 +3121,7 @@ func (ec *executionContext) _WorkloadProblemIssue_workload(ctx context.Context, true, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "WorkloadProblemIssue", @@ -3044,6 +3154,7 @@ func (ec *executionContext) _WorkloadProblemIssue_problemType(ctx context.Contex true, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_problemType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type WorkloadProblemType does not have child fields")) } @@ -3067,6 +3178,7 @@ func (ec *executionContext) _WorkloadProblemIssue_source(ctx context.Context, fi false, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_source(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -3090,6 +3202,7 @@ func (ec *executionContext) _WorkloadProblemIssue_endOfLife(ctx context.Context, false, ) } + func (ec *executionContext) fieldContext_WorkloadProblemIssue_endOfLife(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type Date does not have child fields")) } @@ -5891,7 +6004,7 @@ func (ec *executionContext) unmarshalOIssueType2ᚖgithubᚗcomᚋnaisᚋapiᚋi if v == nil { return nil, nil } - var res = new(issue.IssueType) + res := new(issue.IssueType) err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } @@ -5915,7 +6028,7 @@ func (ec *executionContext) unmarshalOResourceType2ᚖgithubᚗcomᚋnaisᚋapi if v == nil { return nil, nil } - var res = new(issue.ResourceType) + res := new(issue.ResourceType) err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } @@ -5931,7 +6044,7 @@ func (ec *executionContext) unmarshalOSeverity2ᚖgithubᚗcomᚋnaisᚋapiᚋin if v == nil { return nil, nil } - var res = new(issue.Severity) + res := new(issue.Severity) err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } diff --git a/internal/graph/issues.resolvers.go b/internal/graph/issues.resolvers.go index 558894d1f..4ccb749bc 100644 --- a/internal/graph/issues.resolvers.go +++ b/internal/graph/issues.resolvers.go @@ -69,7 +69,7 @@ func (r *invalidSpecIssueResolver) Workload(ctx context.Context, obj *issue.Inva } func (r *issueConnectionResolver) Facets(ctx context.Context, obj *issue.IssueConnection) (*issue.IssueFacets, error) { - return issue.ComputeFacets(ctx, obj.GetTeamSlug(), obj.GetScope(), obj.GetFilter()) + return issue.ComputeFacets(ctx, obj.GetTeamSlug(), obj.GetFilter()) } func (r *lastRunFailedIssueResolver) TeamEnvironment(ctx context.Context, obj *issue.LastRunFailedIssue) (*team.TeamEnvironment, error) { @@ -126,7 +126,7 @@ func (r *teamResolver) Issues(ctx context.Context, obj *team.Team, first *int, a return nil, err } - return issue.ListIssues(ctx, obj.Slug, page, orderBy, nil, filter) + return issue.ListIssues(ctx, obj.Slug, page, orderBy, filter) } func (r *unleashReleaseChannelIssueResolver) TeamEnvironment(ctx context.Context, obj *issue.UnleashReleaseChannelIssue) (*team.TeamEnvironment, error) { diff --git a/internal/graph/jobs.resolvers.go b/internal/graph/jobs.resolvers.go index ed17c7def..e1db0fdff 100644 --- a/internal/graph/jobs.resolvers.go +++ b/internal/graph/jobs.resolvers.go @@ -79,17 +79,17 @@ func (r *jobResolver) Issues(ctx context.Context, obj *job.Job, first *int, afte return nil, err } - scope := &issue.IssueScope{ - ResourceName: obj.Name, - ResourceType: issue.ResourceTypeJob, - Env: obj.EnvironmentName, + rt := issue.ResourceTypeJob + f := &issue.IssueFilter{ + ResourceName: &obj.Name, + ResourceType: &rt, + Environments: []string{obj.EnvironmentName}, } - var f *issue.IssueFilter if filter != nil { - f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} + f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) } func (r *jobConnectionResolver) Facets(ctx context.Context, obj *pagination.FacetableConnection[*job.Job, *job.TeamJobsFilter]) (*job.JobFacets, error) { diff --git a/internal/graph/opensearch.resolvers.go b/internal/graph/opensearch.resolvers.go index 06e8dd9ac..73751e2a5 100644 --- a/internal/graph/opensearch.resolvers.go +++ b/internal/graph/opensearch.resolvers.go @@ -85,17 +85,17 @@ func (r *openSearchResolver) Issues(ctx context.Context, obj *opensearch.OpenSea return nil, err } - scope := &issue.IssueScope{ - ResourceName: obj.Name, - ResourceType: issue.ResourceTypeOpensearch, - Env: obj.EnvironmentName, + rt := issue.ResourceTypeOpensearch + f := &issue.IssueFilter{ + ResourceName: &obj.Name, + ResourceType: &rt, + Environments: []string{obj.EnvironmentName}, } - var f *issue.IssueFilter if filter != nil { - f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} + f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) } func (r *openSearchAccessResolver) Workload(ctx context.Context, obj *opensearch.OpenSearchAccess) (workload.Workload, error) { diff --git a/internal/graph/sqlinstance.resolvers.go b/internal/graph/sqlinstance.resolvers.go index 71883ff46..0bb4136fb 100644 --- a/internal/graph/sqlinstance.resolvers.go +++ b/internal/graph/sqlinstance.resolvers.go @@ -102,17 +102,17 @@ func (r *sqlInstanceResolver) Issues(ctx context.Context, obj *sqlinstance.SQLIn return nil, err } - scope := &issue.IssueScope{ - ResourceName: obj.Name, - ResourceType: issue.ResourceTypeSQLInstance, - Env: obj.EnvironmentName, + rt := issue.ResourceTypeSQLInstance + f := &issue.IssueFilter{ + ResourceName: &obj.Name, + ResourceType: &rt, + Environments: []string{obj.EnvironmentName}, } - var f *issue.IssueFilter if filter != nil { - f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} + f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) } func (r *sqlInstanceResolver) AuditLog(ctx context.Context, obj *sqlinstance.SQLInstance) (*sqlinstance.AuditLog, error) { diff --git a/internal/graph/valkey.resolvers.go b/internal/graph/valkey.resolvers.go index a276b6973..bce01f632 100644 --- a/internal/graph/valkey.resolvers.go +++ b/internal/graph/valkey.resolvers.go @@ -100,17 +100,17 @@ func (r *valkeyResolver) Issues(ctx context.Context, obj *valkey.Valkey, first * return nil, err } - scope := &issue.IssueScope{ - ResourceName: obj.Name, - ResourceType: issue.ResourceTypeValkey, - Env: obj.EnvironmentName, + rt := issue.ResourceTypeValkey + f := &issue.IssueFilter{ + ResourceName: &obj.Name, + ResourceType: &rt, + Environments: []string{obj.EnvironmentName}, } - var f *issue.IssueFilter if filter != nil { - f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} + f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) } func (r *valkeyAccessResolver) Workload(ctx context.Context, obj *valkey.ValkeyAccess) (workload.Workload, error) { diff --git a/internal/issue/facets.go b/internal/issue/facets.go index 4815ae968..adecea11c 100644 --- a/internal/issue/facets.go +++ b/internal/issue/facets.go @@ -10,25 +10,17 @@ import ( "github.com/nais/api/internal/slug" ) -func ComputeFacets(ctx context.Context, teamSlug slug.Slug, scope *IssueScope, filter *IssueFilter) (*IssueFacets, error) { +func ComputeFacets(ctx context.Context, teamSlug slug.Slug, filter *IssueFilter) (*IssueFacets, error) { params := issuesql.FacetsForIssuesParams{ Team: teamSlug.String(), } - if scope != nil { - params.ScopeResourceName = &scope.ResourceName - params.ScopeResourceType = (*string)(&scope.ResourceType) - params.ScopeEnv = &scope.Env - } - if filter != nil { - if scope == nil { - if len(filter.Environments) > 0 { - params.Env = filter.Environments - } - params.FilterResourceType = (*string)(filter.ResourceType) - params.FilterResourceName = filter.ResourceName + if len(filter.Environments) > 0 { + params.Env = filter.Environments } + params.ResourceType = (*string)(filter.ResourceType) + params.ResourceName = filter.ResourceName params.IssueType = (*string)(filter.IssueType) if filter.Severity != nil { params.Severity = new(issuesql.SeverityLevel(*filter.Severity)) diff --git a/internal/issue/issuesql/issue.sql.go b/internal/issue/issuesql/issue.sql.go index a38da0029..123a432a3 100644 --- a/internal/issue/issuesql/issue.sql.go +++ b/internal/issue/issuesql/issue.sql.go @@ -44,18 +44,6 @@ FROM issues WHERE team = $6 - AND ( - $7::TEXT IS NULL - OR resource_type = $7::TEXT - ) - AND ( - $8::TEXT IS NULL - OR resource_name = $8::TEXT - ) - AND ( - $9::TEXT IS NULL - OR env = $9::TEXT - ) GROUP BY severity, resource_type, @@ -69,15 +57,12 @@ ORDER BY ` type FacetsForIssuesParams struct { - Env []string - IssueType *string - Severity *SeverityLevel - FilterResourceType *string - FilterResourceName *string - Team string - ScopeResourceType *string - ScopeResourceName *string - ScopeEnv *string + Env []string + IssueType *string + Severity *SeverityLevel + ResourceType *string + ResourceName *string + Team string } type FacetsForIssuesRow struct { @@ -94,12 +79,9 @@ func (q *Queries) FacetsForIssues(ctx context.Context, arg FacetsForIssuesParams arg.Env, arg.IssueType, arg.Severity, - arg.FilterResourceType, - arg.FilterResourceName, + arg.ResourceType, + arg.ResourceName, arg.Team, - arg.ScopeResourceType, - arg.ScopeResourceName, - arg.ScopeEnv, ) if err != nil { return nil, err diff --git a/internal/issue/model.go b/internal/issue/model.go index 9a6e9b10a..4cef50da8 100644 --- a/internal/issue/model.go +++ b/internal/issue/model.go @@ -269,22 +269,14 @@ type ( IssueEdge = pagination.Edge[Issue] ) -type IssueScope struct { - ResourceName string - ResourceType ResourceType - Env string -} - type IssueConnection struct { pagination.Connection[Issue] teamSlug slug.Slug - scope *IssueScope filter *IssueFilter } func (c *IssueConnection) GetTeamSlug() slug.Slug { return c.teamSlug } -func (c *IssueConnection) GetScope() *IssueScope { return c.scope } func (c *IssueConnection) GetFilter() *IssueFilter { return c.filter } type IssueFacets struct { diff --git a/internal/issue/queries.go b/internal/issue/queries.go index ad1ab7401..cc9da30c6 100644 --- a/internal/issue/queries.go +++ b/internal/issue/queries.go @@ -43,7 +43,7 @@ func GetByIdent(ctx context.Context, id ident.Ident) (Issue, error) { return convert(issue) } -func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, scope *IssueScope, filter *IssueFilter) (*IssueConnection, error) { +func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, filter *IssueFilter) (*IssueConnection, error) { params := issuesql.ListIssuesParams{ Team: teamSlug.String(), Offset: page.Offset(), @@ -51,20 +51,12 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina OrderBy: orderBy.String(), } - if scope != nil { - params.ResourceName = &scope.ResourceName - params.ResourceType = (*string)(&scope.ResourceType) - params.Env = []string{scope.Env} - } - if filter != nil { - if scope == nil { - if len(filter.Environments) > 0 { - params.Env = filter.Environments - } - params.ResourceType = (*string)(filter.ResourceType) - params.ResourceName = filter.ResourceName + if len(filter.Environments) > 0 { + params.Env = filter.Environments } + params.ResourceType = (*string)(filter.ResourceType) + params.ResourceName = filter.ResourceName params.IssueType = (*string)(filter.IssueType) if filter.Severity != nil { params.Severity = new(issuesql.SeverityLevel(*filter.Severity)) @@ -103,7 +95,6 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina return &IssueConnection{ Connection: *conn, teamSlug: teamSlug, - scope: scope, filter: filter, }, nil } diff --git a/internal/issue/queries/issue.sql b/internal/issue/queries/issue.sql index 184735412..7094ad820 100644 --- a/internal/issue/queries/issue.sql +++ b/internal/issue/queries/issue.sql @@ -115,30 +115,18 @@ SELECT OR severity = sqlc.narg('severity')::severity_level ) AND ( - sqlc.narg('filter_resource_type')::TEXT IS NULL - OR resource_type = sqlc.narg('filter_resource_type')::TEXT + sqlc.narg('resource_type')::TEXT IS NULL + OR resource_type = sqlc.narg('resource_type')::TEXT ) AND ( - sqlc.narg('filter_resource_name')::TEXT IS NULL - OR resource_name = sqlc.narg('filter_resource_name')::TEXT + sqlc.narg('resource_name')::TEXT IS NULL + OR resource_name = sqlc.narg('resource_name')::TEXT ) ) AS filtered_count FROM issues WHERE team = @team - AND ( - sqlc.narg('scope_resource_type')::TEXT IS NULL - OR resource_type = sqlc.narg('scope_resource_type')::TEXT - ) - AND ( - sqlc.narg('scope_resource_name')::TEXT IS NULL - OR resource_name = sqlc.narg('scope_resource_name')::TEXT - ) - AND ( - sqlc.narg('scope_env')::TEXT IS NULL - OR env = sqlc.narg('scope_env')::TEXT - ) GROUP BY severity, resource_type, From 186ac2f095a59cb6138233864e34febd0cf776dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 11:33:46 +0200 Subject: [PATCH 09/11] refactor: remove unnecessary blank lines and optimize variable declarations in issues.generated.go --- internal/graph/gengql/issues.generated.go | 119 +--------------------- 1 file changed, 3 insertions(+), 116 deletions(-) diff --git a/internal/graph/gengql/issues.generated.go b/internal/graph/gengql/issues.generated.go index 65b8569cd..fb56b878a 100644 --- a/internal/graph/gengql/issues.generated.go +++ b/internal/graph/gengql/issues.generated.go @@ -145,7 +145,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_id(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -169,7 +168,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_teamEnvironment(ctx con true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ApplicationRestartLoopIssue", @@ -202,7 +200,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_severity(ctx context.Co true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -226,7 +223,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_message(ctx context.Con true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -250,7 +246,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_workload(ctx context.Co true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ApplicationRestartLoopIssue", @@ -283,7 +278,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_restartCount(ctx contex true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_restartCount(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -307,7 +301,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_lastExitReason(ctx cont true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_lastExitReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -331,7 +324,6 @@ func (ec *executionContext) _ApplicationRestartLoopIssue_lastExitTimestamp(ctx c true, ) } - func (ec *executionContext) fieldContext_ApplicationRestartLoopIssue_lastExitTimestamp(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ApplicationRestartLoopIssue", field, false, false, errors.New("field of type Time does not have child fields")) } @@ -355,7 +347,6 @@ func (ec *executionContext) _DeprecatedIngressIssue_id(ctx context.Context, fiel true, ) } - func (ec *executionContext) fieldContext_DeprecatedIngressIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -379,7 +370,6 @@ func (ec *executionContext) _DeprecatedIngressIssue_teamEnvironment(ctx context. true, ) } - func (ec *executionContext) fieldContext_DeprecatedIngressIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedIngressIssue", @@ -412,7 +402,6 @@ func (ec *executionContext) _DeprecatedIngressIssue_severity(ctx context.Context true, ) } - func (ec *executionContext) fieldContext_DeprecatedIngressIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -436,7 +425,6 @@ func (ec *executionContext) _DeprecatedIngressIssue_message(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_DeprecatedIngressIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -460,7 +448,6 @@ func (ec *executionContext) _DeprecatedIngressIssue_ingresses(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_DeprecatedIngressIssue_ingresses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedIngressIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -484,7 +471,6 @@ func (ec *executionContext) _DeprecatedIngressIssue_application(ctx context.Cont true, ) } - func (ec *executionContext) fieldContext_DeprecatedIngressIssue_application(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedIngressIssue", @@ -517,7 +503,6 @@ func (ec *executionContext) _DeprecatedRegistryIssue_id(ctx context.Context, fie true, ) } - func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedRegistryIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -541,7 +526,6 @@ func (ec *executionContext) _DeprecatedRegistryIssue_teamEnvironment(ctx context true, ) } - func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedRegistryIssue", @@ -574,7 +558,6 @@ func (ec *executionContext) _DeprecatedRegistryIssue_severity(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedRegistryIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -598,7 +581,6 @@ func (ec *executionContext) _DeprecatedRegistryIssue_message(ctx context.Context true, ) } - func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("DeprecatedRegistryIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -622,7 +604,6 @@ func (ec *executionContext) _DeprecatedRegistryIssue_workload(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_DeprecatedRegistryIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "DeprecatedRegistryIssue", @@ -655,7 +636,6 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_id(ctx co true, ) } - func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -679,7 +659,6 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_teamEnvir true, ) } - func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ExternalIngressCriticalVulnerabilityIssue", @@ -712,7 +691,6 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_severity( true, ) } - func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -736,7 +714,6 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_message(c true, ) } - func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -760,7 +737,6 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_workload( true, ) } - func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ExternalIngressCriticalVulnerabilityIssue", @@ -793,7 +769,6 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_cvssScore true, ) } - func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_cvssScore(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type Float does not have child fields")) } @@ -817,7 +792,6 @@ func (ec *executionContext) _ExternalIngressCriticalVulnerabilityIssue_ingresses true, ) } - func (ec *executionContext) fieldContext_ExternalIngressCriticalVulnerabilityIssue_ingresses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ExternalIngressCriticalVulnerabilityIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -841,7 +815,6 @@ func (ec *executionContext) _FailedSynchronizationIssue_id(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_FailedSynchronizationIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("FailedSynchronizationIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -865,7 +838,6 @@ func (ec *executionContext) _FailedSynchronizationIssue_teamEnvironment(ctx cont true, ) } - func (ec *executionContext) fieldContext_FailedSynchronizationIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "FailedSynchronizationIssue", @@ -898,7 +870,6 @@ func (ec *executionContext) _FailedSynchronizationIssue_severity(ctx context.Con true, ) } - func (ec *executionContext) fieldContext_FailedSynchronizationIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("FailedSynchronizationIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -922,7 +893,6 @@ func (ec *executionContext) _FailedSynchronizationIssue_message(ctx context.Cont true, ) } - func (ec *executionContext) fieldContext_FailedSynchronizationIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("FailedSynchronizationIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -946,7 +916,6 @@ func (ec *executionContext) _FailedSynchronizationIssue_workload(ctx context.Con true, ) } - func (ec *executionContext) fieldContext_FailedSynchronizationIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "FailedSynchronizationIssue", @@ -979,7 +948,6 @@ func (ec *executionContext) _InvalidSpecIssue_id(ctx context.Context, field grap true, ) } - func (ec *executionContext) fieldContext_InvalidSpecIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("InvalidSpecIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1003,7 +971,6 @@ func (ec *executionContext) _InvalidSpecIssue_teamEnvironment(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_InvalidSpecIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "InvalidSpecIssue", @@ -1036,7 +1003,6 @@ func (ec *executionContext) _InvalidSpecIssue_severity(ctx context.Context, fiel true, ) } - func (ec *executionContext) fieldContext_InvalidSpecIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("InvalidSpecIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1060,7 +1026,6 @@ func (ec *executionContext) _InvalidSpecIssue_message(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_InvalidSpecIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("InvalidSpecIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1084,7 +1049,6 @@ func (ec *executionContext) _InvalidSpecIssue_workload(ctx context.Context, fiel true, ) } - func (ec *executionContext) fieldContext_InvalidSpecIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "InvalidSpecIssue", @@ -1117,7 +1081,6 @@ func (ec *executionContext) _IssueConnection_pageInfo(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_IssueConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1150,7 +1113,6 @@ func (ec *executionContext) _IssueConnection_nodes(ctx context.Context, field gr true, ) } - func (ec *executionContext) fieldContext_IssueConnection_nodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1183,7 +1145,6 @@ func (ec *executionContext) _IssueConnection_edges(ctx context.Context, field gr true, ) } - func (ec *executionContext) fieldContext_IssueConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1216,7 +1177,6 @@ func (ec *executionContext) _IssueConnection_facets(ctx context.Context, field g false, ) } - func (ec *executionContext) fieldContext_IssueConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueConnection", @@ -1249,7 +1209,6 @@ func (ec *executionContext) _IssueEdge_cursor(ctx context.Context, field graphql true, ) } - func (ec *executionContext) fieldContext_IssueEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueEdge", field, false, false, errors.New("field of type Cursor does not have child fields")) } @@ -1273,7 +1232,6 @@ func (ec *executionContext) _IssueEdge_node(ctx context.Context, field graphql.C true, ) } - func (ec *executionContext) fieldContext_IssueEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueEdge", @@ -1306,7 +1264,6 @@ func (ec *executionContext) _IssueFacets_environments(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_IssueFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1339,7 +1296,6 @@ func (ec *executionContext) _IssueFacets_severities(ctx context.Context, field g true, ) } - func (ec *executionContext) fieldContext_IssueFacets_severities(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1372,7 +1328,6 @@ func (ec *executionContext) _IssueFacets_resourceTypes(ctx context.Context, fiel true, ) } - func (ec *executionContext) fieldContext_IssueFacets_resourceTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1405,7 +1360,6 @@ func (ec *executionContext) _IssueFacets_issueTypes(ctx context.Context, field g true, ) } - func (ec *executionContext) fieldContext_IssueFacets_issueTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "IssueFacets", @@ -1438,7 +1392,6 @@ func (ec *executionContext) _IssueResourceTypeFacetItem_resourceType(ctx context true, ) } - func (ec *executionContext) fieldContext_IssueResourceTypeFacetItem_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueResourceTypeFacetItem", field, false, false, errors.New("field of type ResourceType does not have child fields")) } @@ -1462,7 +1415,6 @@ func (ec *executionContext) _IssueResourceTypeFacetItem_count(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_IssueResourceTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueResourceTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -1486,7 +1438,6 @@ func (ec *executionContext) _IssueSeverityFacetItem_severity(ctx context.Context true, ) } - func (ec *executionContext) fieldContext_IssueSeverityFacetItem_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueSeverityFacetItem", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1510,7 +1461,6 @@ func (ec *executionContext) _IssueSeverityFacetItem_count(ctx context.Context, f true, ) } - func (ec *executionContext) fieldContext_IssueSeverityFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueSeverityFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -1534,7 +1484,6 @@ func (ec *executionContext) _IssueTypeFacetItem_issueType(ctx context.Context, f true, ) } - func (ec *executionContext) fieldContext_IssueTypeFacetItem_issueType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueTypeFacetItem", field, false, false, errors.New("field of type IssueType does not have child fields")) } @@ -1558,7 +1507,6 @@ func (ec *executionContext) _IssueTypeFacetItem_count(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_IssueTypeFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("IssueTypeFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -1582,7 +1530,6 @@ func (ec *executionContext) _LastRunFailedIssue_id(ctx context.Context, field gr true, ) } - func (ec *executionContext) fieldContext_LastRunFailedIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("LastRunFailedIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1606,7 +1553,6 @@ func (ec *executionContext) _LastRunFailedIssue_teamEnvironment(ctx context.Cont true, ) } - func (ec *executionContext) fieldContext_LastRunFailedIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "LastRunFailedIssue", @@ -1639,7 +1585,6 @@ func (ec *executionContext) _LastRunFailedIssue_severity(ctx context.Context, fi true, ) } - func (ec *executionContext) fieldContext_LastRunFailedIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("LastRunFailedIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1663,7 +1608,6 @@ func (ec *executionContext) _LastRunFailedIssue_message(ctx context.Context, fie true, ) } - func (ec *executionContext) fieldContext_LastRunFailedIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("LastRunFailedIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1687,7 +1631,6 @@ func (ec *executionContext) _LastRunFailedIssue_job(ctx context.Context, field g true, ) } - func (ec *executionContext) fieldContext_LastRunFailedIssue_job(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "LastRunFailedIssue", @@ -1720,7 +1663,6 @@ func (ec *executionContext) _MissingSbomIssue_id(ctx context.Context, field grap true, ) } - func (ec *executionContext) fieldContext_MissingSbomIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("MissingSbomIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1744,7 +1686,6 @@ func (ec *executionContext) _MissingSbomIssue_teamEnvironment(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_MissingSbomIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "MissingSbomIssue", @@ -1777,7 +1718,6 @@ func (ec *executionContext) _MissingSbomIssue_severity(ctx context.Context, fiel true, ) } - func (ec *executionContext) fieldContext_MissingSbomIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("MissingSbomIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1801,7 +1741,6 @@ func (ec *executionContext) _MissingSbomIssue_message(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_MissingSbomIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("MissingSbomIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1825,7 +1764,6 @@ func (ec *executionContext) _MissingSbomIssue_workload(ctx context.Context, fiel true, ) } - func (ec *executionContext) fieldContext_MissingSbomIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "MissingSbomIssue", @@ -1858,7 +1796,6 @@ func (ec *executionContext) _NoRunningInstancesIssue_id(ctx context.Context, fie true, ) } - func (ec *executionContext) fieldContext_NoRunningInstancesIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("NoRunningInstancesIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -1882,7 +1819,6 @@ func (ec *executionContext) _NoRunningInstancesIssue_teamEnvironment(ctx context true, ) } - func (ec *executionContext) fieldContext_NoRunningInstancesIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "NoRunningInstancesIssue", @@ -1915,7 +1851,6 @@ func (ec *executionContext) _NoRunningInstancesIssue_severity(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_NoRunningInstancesIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("NoRunningInstancesIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -1939,7 +1874,6 @@ func (ec *executionContext) _NoRunningInstancesIssue_message(ctx context.Context true, ) } - func (ec *executionContext) fieldContext_NoRunningInstancesIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("NoRunningInstancesIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -1963,7 +1897,6 @@ func (ec *executionContext) _NoRunningInstancesIssue_workload(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_NoRunningInstancesIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "NoRunningInstancesIssue", @@ -1996,7 +1929,6 @@ func (ec *executionContext) _OpenSearchIssue_id(ctx context.Context, field graph true, ) } - func (ec *executionContext) fieldContext_OpenSearchIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2020,7 +1952,6 @@ func (ec *executionContext) _OpenSearchIssue_teamEnvironment(ctx context.Context true, ) } - func (ec *executionContext) fieldContext_OpenSearchIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "OpenSearchIssue", @@ -2053,7 +1984,6 @@ func (ec *executionContext) _OpenSearchIssue_severity(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_OpenSearchIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2077,7 +2007,6 @@ func (ec *executionContext) _OpenSearchIssue_message(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_OpenSearchIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2101,7 +2030,6 @@ func (ec *executionContext) _OpenSearchIssue_openSearch(ctx context.Context, fie true, ) } - func (ec *executionContext) fieldContext_OpenSearchIssue_openSearch(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "OpenSearchIssue", @@ -2134,7 +2062,6 @@ func (ec *executionContext) _OpenSearchIssue_event(ctx context.Context, field gr true, ) } - func (ec *executionContext) fieldContext_OpenSearchIssue_event(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("OpenSearchIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2158,7 +2085,6 @@ func (ec *executionContext) _SqlInstanceStateIssue_id(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_SqlInstanceStateIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2182,7 +2108,6 @@ func (ec *executionContext) _SqlInstanceStateIssue_teamEnvironment(ctx context.C true, ) } - func (ec *executionContext) fieldContext_SqlInstanceStateIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceStateIssue", @@ -2215,7 +2140,6 @@ func (ec *executionContext) _SqlInstanceStateIssue_severity(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_SqlInstanceStateIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2239,7 +2163,6 @@ func (ec *executionContext) _SqlInstanceStateIssue_message(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_SqlInstanceStateIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2263,7 +2186,6 @@ func (ec *executionContext) _SqlInstanceStateIssue_state(ctx context.Context, fi true, ) } - func (ec *executionContext) fieldContext_SqlInstanceStateIssue_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceStateIssue", field, false, false, errors.New("field of type SqlInstanceState does not have child fields")) } @@ -2287,7 +2209,6 @@ func (ec *executionContext) _SqlInstanceStateIssue_sqlInstance(ctx context.Conte true, ) } - func (ec *executionContext) fieldContext_SqlInstanceStateIssue_sqlInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceStateIssue", @@ -2320,7 +2241,6 @@ func (ec *executionContext) _SqlInstanceVersionIssue_id(ctx context.Context, fie true, ) } - func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceVersionIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2344,7 +2264,6 @@ func (ec *executionContext) _SqlInstanceVersionIssue_teamEnvironment(ctx context true, ) } - func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceVersionIssue", @@ -2377,7 +2296,6 @@ func (ec *executionContext) _SqlInstanceVersionIssue_severity(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceVersionIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2401,7 +2319,6 @@ func (ec *executionContext) _SqlInstanceVersionIssue_message(ctx context.Context true, ) } - func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("SqlInstanceVersionIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2425,7 +2342,6 @@ func (ec *executionContext) _SqlInstanceVersionIssue_sqlInstance(ctx context.Con true, ) } - func (ec *executionContext) fieldContext_SqlInstanceVersionIssue_sqlInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "SqlInstanceVersionIssue", @@ -2458,7 +2374,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_id(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2482,7 +2397,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_teamEnvironment(ctx cont true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "UnleashReleaseChannelIssue", @@ -2515,7 +2429,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_severity(ctx context.Con true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2539,7 +2452,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_message(ctx context.Cont true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2563,7 +2475,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_unleash(ctx context.Cont true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_unleash(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "UnleashReleaseChannelIssue", @@ -2596,7 +2507,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_channelName(ctx context. true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_channelName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2620,7 +2530,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_majorVersion(ctx context true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_majorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -2644,7 +2553,6 @@ func (ec *executionContext) _UnleashReleaseChannelIssue_currentMajorVersion(ctx true, ) } - func (ec *executionContext) fieldContext_UnleashReleaseChannelIssue_currentMajorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("UnleashReleaseChannelIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -2668,7 +2576,6 @@ func (ec *executionContext) _ValkeyIssue_id(ctx context.Context, field graphql.C true, ) } - func (ec *executionContext) fieldContext_ValkeyIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2692,7 +2599,6 @@ func (ec *executionContext) _ValkeyIssue_teamEnvironment(ctx context.Context, fi true, ) } - func (ec *executionContext) fieldContext_ValkeyIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ValkeyIssue", @@ -2725,7 +2631,6 @@ func (ec *executionContext) _ValkeyIssue_severity(ctx context.Context, field gra true, ) } - func (ec *executionContext) fieldContext_ValkeyIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2749,7 +2654,6 @@ func (ec *executionContext) _ValkeyIssue_message(ctx context.Context, field grap true, ) } - func (ec *executionContext) fieldContext_ValkeyIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2773,7 +2677,6 @@ func (ec *executionContext) _ValkeyIssue_valkey(ctx context.Context, field graph true, ) } - func (ec *executionContext) fieldContext_ValkeyIssue_valkey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "ValkeyIssue", @@ -2806,7 +2709,6 @@ func (ec *executionContext) _ValkeyIssue_event(ctx context.Context, field graphq true, ) } - func (ec *executionContext) fieldContext_ValkeyIssue_event(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("ValkeyIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2830,7 +2732,6 @@ func (ec *executionContext) _VulnerableImageIssue_id(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_VulnerableImageIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -2854,7 +2755,6 @@ func (ec *executionContext) _VulnerableImageIssue_teamEnvironment(ctx context.Co true, ) } - func (ec *executionContext) fieldContext_VulnerableImageIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "VulnerableImageIssue", @@ -2887,7 +2787,6 @@ func (ec *executionContext) _VulnerableImageIssue_severity(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_VulnerableImageIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -2911,7 +2810,6 @@ func (ec *executionContext) _VulnerableImageIssue_message(ctx context.Context, f true, ) } - func (ec *executionContext) fieldContext_VulnerableImageIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -2935,7 +2833,6 @@ func (ec *executionContext) _VulnerableImageIssue_workload(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_VulnerableImageIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "VulnerableImageIssue", @@ -2968,7 +2865,6 @@ func (ec *executionContext) _VulnerableImageIssue_riskScore(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_VulnerableImageIssue_riskScore(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -2992,7 +2888,6 @@ func (ec *executionContext) _VulnerableImageIssue_critical(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_VulnerableImageIssue_critical(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("VulnerableImageIssue", field, false, false, errors.New("field of type Int does not have child fields")) } @@ -3016,7 +2911,6 @@ func (ec *executionContext) _WorkloadProblemIssue_id(ctx context.Context, field true, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type ID does not have child fields")) } @@ -3040,7 +2934,6 @@ func (ec *executionContext) _WorkloadProblemIssue_teamEnvironment(ctx context.Co true, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "WorkloadProblemIssue", @@ -3073,7 +2966,6 @@ func (ec *executionContext) _WorkloadProblemIssue_severity(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_severity(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type Severity does not have child fields")) } @@ -3097,7 +2989,6 @@ func (ec *executionContext) _WorkloadProblemIssue_message(ctx context.Context, f true, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -3121,7 +3012,6 @@ func (ec *executionContext) _WorkloadProblemIssue_workload(ctx context.Context, true, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_workload(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "WorkloadProblemIssue", @@ -3154,7 +3044,6 @@ func (ec *executionContext) _WorkloadProblemIssue_problemType(ctx context.Contex true, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_problemType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type WorkloadProblemType does not have child fields")) } @@ -3178,7 +3067,6 @@ func (ec *executionContext) _WorkloadProblemIssue_source(ctx context.Context, fi false, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_source(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type String does not have child fields")) } @@ -3202,7 +3090,6 @@ func (ec *executionContext) _WorkloadProblemIssue_endOfLife(ctx context.Context, false, ) } - func (ec *executionContext) fieldContext_WorkloadProblemIssue_endOfLife(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("WorkloadProblemIssue", field, false, false, errors.New("field of type Date does not have child fields")) } @@ -6004,7 +5891,7 @@ func (ec *executionContext) unmarshalOIssueType2ᚖgithubᚗcomᚋnaisᚋapiᚋi if v == nil { return nil, nil } - res := new(issue.IssueType) + var res = new(issue.IssueType) err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } @@ -6028,7 +5915,7 @@ func (ec *executionContext) unmarshalOResourceType2ᚖgithubᚗcomᚋnaisᚋapi if v == nil { return nil, nil } - res := new(issue.ResourceType) + var res = new(issue.ResourceType) err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } @@ -6044,7 +5931,7 @@ func (ec *executionContext) unmarshalOSeverity2ᚖgithubᚗcomᚋnaisᚋapiᚋin if v == nil { return nil, nil } - res := new(issue.Severity) + var res = new(issue.Severity) err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } From 31947d67341c532c880d9961eeaa78ce52f8bf6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 11:49:00 +0200 Subject: [PATCH 10/11] Revert "refactor(issue): remove IssueScope, use IssueFilter for all issue constraints" This reverts commit 10724c3e19d8381541d7fb9245376a52c8945291. --- internal/graph/applications.resolvers.go | 14 +++++----- internal/graph/issues.resolvers.go | 4 +-- internal/graph/jobs.resolvers.go | 14 +++++----- internal/graph/opensearch.resolvers.go | 14 +++++----- internal/graph/sqlinstance.resolvers.go | 14 +++++----- internal/graph/valkey.resolvers.go | 14 +++++----- internal/issue/facets.go | 18 +++++++++---- internal/issue/issuesql/issue.sql.go | 34 ++++++++++++++++++------ internal/issue/model.go | 8 ++++++ internal/issue/queries.go | 19 +++++++++---- internal/issue/queries/issue.sql | 20 +++++++++++--- 11 files changed, 114 insertions(+), 59 deletions(-) diff --git a/internal/graph/applications.resolvers.go b/internal/graph/applications.resolvers.go index e880f6f39..e4461d19f 100644 --- a/internal/graph/applications.resolvers.go +++ b/internal/graph/applications.resolvers.go @@ -81,17 +81,17 @@ func (r *applicationResolver) Issues(ctx context.Context, obj *application.Appli return nil, err } - rt := issue.ResourceTypeApplication - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &rt, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeApplication, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *applicationResolver) History(ctx context.Context, obj *application.Application) ([]*instancegroup.ApplicationHistory, error) { diff --git a/internal/graph/issues.resolvers.go b/internal/graph/issues.resolvers.go index 4ccb749bc..558894d1f 100644 --- a/internal/graph/issues.resolvers.go +++ b/internal/graph/issues.resolvers.go @@ -69,7 +69,7 @@ func (r *invalidSpecIssueResolver) Workload(ctx context.Context, obj *issue.Inva } func (r *issueConnectionResolver) Facets(ctx context.Context, obj *issue.IssueConnection) (*issue.IssueFacets, error) { - return issue.ComputeFacets(ctx, obj.GetTeamSlug(), obj.GetFilter()) + return issue.ComputeFacets(ctx, obj.GetTeamSlug(), obj.GetScope(), obj.GetFilter()) } func (r *lastRunFailedIssueResolver) TeamEnvironment(ctx context.Context, obj *issue.LastRunFailedIssue) (*team.TeamEnvironment, error) { @@ -126,7 +126,7 @@ func (r *teamResolver) Issues(ctx context.Context, obj *team.Team, first *int, a return nil, err } - return issue.ListIssues(ctx, obj.Slug, page, orderBy, filter) + return issue.ListIssues(ctx, obj.Slug, page, orderBy, nil, filter) } func (r *unleashReleaseChannelIssueResolver) TeamEnvironment(ctx context.Context, obj *issue.UnleashReleaseChannelIssue) (*team.TeamEnvironment, error) { diff --git a/internal/graph/jobs.resolvers.go b/internal/graph/jobs.resolvers.go index e1db0fdff..ed17c7def 100644 --- a/internal/graph/jobs.resolvers.go +++ b/internal/graph/jobs.resolvers.go @@ -79,17 +79,17 @@ func (r *jobResolver) Issues(ctx context.Context, obj *job.Job, first *int, afte return nil, err } - rt := issue.ResourceTypeJob - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &rt, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeJob, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *jobConnectionResolver) Facets(ctx context.Context, obj *pagination.FacetableConnection[*job.Job, *job.TeamJobsFilter]) (*job.JobFacets, error) { diff --git a/internal/graph/opensearch.resolvers.go b/internal/graph/opensearch.resolvers.go index 73751e2a5..06e8dd9ac 100644 --- a/internal/graph/opensearch.resolvers.go +++ b/internal/graph/opensearch.resolvers.go @@ -85,17 +85,17 @@ func (r *openSearchResolver) Issues(ctx context.Context, obj *opensearch.OpenSea return nil, err } - rt := issue.ResourceTypeOpensearch - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &rt, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeOpensearch, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *openSearchAccessResolver) Workload(ctx context.Context, obj *opensearch.OpenSearchAccess) (workload.Workload, error) { diff --git a/internal/graph/sqlinstance.resolvers.go b/internal/graph/sqlinstance.resolvers.go index 0bb4136fb..71883ff46 100644 --- a/internal/graph/sqlinstance.resolvers.go +++ b/internal/graph/sqlinstance.resolvers.go @@ -102,17 +102,17 @@ func (r *sqlInstanceResolver) Issues(ctx context.Context, obj *sqlinstance.SQLIn return nil, err } - rt := issue.ResourceTypeSQLInstance - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &rt, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeSQLInstance, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *sqlInstanceResolver) AuditLog(ctx context.Context, obj *sqlinstance.SQLInstance) (*sqlinstance.AuditLog, error) { diff --git a/internal/graph/valkey.resolvers.go b/internal/graph/valkey.resolvers.go index bce01f632..a276b6973 100644 --- a/internal/graph/valkey.resolvers.go +++ b/internal/graph/valkey.resolvers.go @@ -100,17 +100,17 @@ func (r *valkeyResolver) Issues(ctx context.Context, obj *valkey.Valkey, first * return nil, err } - rt := issue.ResourceTypeValkey - f := &issue.IssueFilter{ - ResourceName: &obj.Name, - ResourceType: &rt, - Environments: []string{obj.EnvironmentName}, + scope := &issue.IssueScope{ + ResourceName: obj.Name, + ResourceType: issue.ResourceTypeValkey, + Env: obj.EnvironmentName, } + var f *issue.IssueFilter if filter != nil { - f.ResourceIssueFilter = issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType} + f = &issue.IssueFilter{ResourceIssueFilter: issue.ResourceIssueFilter{Severity: filter.Severity, IssueType: filter.IssueType}} } - return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, f) + return issue.ListIssues(ctx, obj.TeamSlug, page, orderBy, scope, f) } func (r *valkeyAccessResolver) Workload(ctx context.Context, obj *valkey.ValkeyAccess) (workload.Workload, error) { diff --git a/internal/issue/facets.go b/internal/issue/facets.go index adecea11c..4815ae968 100644 --- a/internal/issue/facets.go +++ b/internal/issue/facets.go @@ -10,17 +10,25 @@ import ( "github.com/nais/api/internal/slug" ) -func ComputeFacets(ctx context.Context, teamSlug slug.Slug, filter *IssueFilter) (*IssueFacets, error) { +func ComputeFacets(ctx context.Context, teamSlug slug.Slug, scope *IssueScope, filter *IssueFilter) (*IssueFacets, error) { params := issuesql.FacetsForIssuesParams{ Team: teamSlug.String(), } + if scope != nil { + params.ScopeResourceName = &scope.ResourceName + params.ScopeResourceType = (*string)(&scope.ResourceType) + params.ScopeEnv = &scope.Env + } + if filter != nil { - if len(filter.Environments) > 0 { - params.Env = filter.Environments + if scope == nil { + if len(filter.Environments) > 0 { + params.Env = filter.Environments + } + params.FilterResourceType = (*string)(filter.ResourceType) + params.FilterResourceName = filter.ResourceName } - params.ResourceType = (*string)(filter.ResourceType) - params.ResourceName = filter.ResourceName params.IssueType = (*string)(filter.IssueType) if filter.Severity != nil { params.Severity = new(issuesql.SeverityLevel(*filter.Severity)) diff --git a/internal/issue/issuesql/issue.sql.go b/internal/issue/issuesql/issue.sql.go index 123a432a3..a38da0029 100644 --- a/internal/issue/issuesql/issue.sql.go +++ b/internal/issue/issuesql/issue.sql.go @@ -44,6 +44,18 @@ FROM issues WHERE team = $6 + AND ( + $7::TEXT IS NULL + OR resource_type = $7::TEXT + ) + AND ( + $8::TEXT IS NULL + OR resource_name = $8::TEXT + ) + AND ( + $9::TEXT IS NULL + OR env = $9::TEXT + ) GROUP BY severity, resource_type, @@ -57,12 +69,15 @@ ORDER BY ` type FacetsForIssuesParams struct { - Env []string - IssueType *string - Severity *SeverityLevel - ResourceType *string - ResourceName *string - Team string + Env []string + IssueType *string + Severity *SeverityLevel + FilterResourceType *string + FilterResourceName *string + Team string + ScopeResourceType *string + ScopeResourceName *string + ScopeEnv *string } type FacetsForIssuesRow struct { @@ -79,9 +94,12 @@ func (q *Queries) FacetsForIssues(ctx context.Context, arg FacetsForIssuesParams arg.Env, arg.IssueType, arg.Severity, - arg.ResourceType, - arg.ResourceName, + arg.FilterResourceType, + arg.FilterResourceName, arg.Team, + arg.ScopeResourceType, + arg.ScopeResourceName, + arg.ScopeEnv, ) if err != nil { return nil, err diff --git a/internal/issue/model.go b/internal/issue/model.go index 4cef50da8..9a6e9b10a 100644 --- a/internal/issue/model.go +++ b/internal/issue/model.go @@ -269,14 +269,22 @@ type ( IssueEdge = pagination.Edge[Issue] ) +type IssueScope struct { + ResourceName string + ResourceType ResourceType + Env string +} + type IssueConnection struct { pagination.Connection[Issue] teamSlug slug.Slug + scope *IssueScope filter *IssueFilter } func (c *IssueConnection) GetTeamSlug() slug.Slug { return c.teamSlug } +func (c *IssueConnection) GetScope() *IssueScope { return c.scope } func (c *IssueConnection) GetFilter() *IssueFilter { return c.filter } type IssueFacets struct { diff --git a/internal/issue/queries.go b/internal/issue/queries.go index cc9da30c6..ad1ab7401 100644 --- a/internal/issue/queries.go +++ b/internal/issue/queries.go @@ -43,7 +43,7 @@ func GetByIdent(ctx context.Context, id ident.Ident) (Issue, error) { return convert(issue) } -func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, filter *IssueFilter) (*IssueConnection, error) { +func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *IssueOrder, scope *IssueScope, filter *IssueFilter) (*IssueConnection, error) { params := issuesql.ListIssuesParams{ Team: teamSlug.String(), Offset: page.Offset(), @@ -51,12 +51,20 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina OrderBy: orderBy.String(), } + if scope != nil { + params.ResourceName = &scope.ResourceName + params.ResourceType = (*string)(&scope.ResourceType) + params.Env = []string{scope.Env} + } + if filter != nil { - if len(filter.Environments) > 0 { - params.Env = filter.Environments + if scope == nil { + if len(filter.Environments) > 0 { + params.Env = filter.Environments + } + params.ResourceType = (*string)(filter.ResourceType) + params.ResourceName = filter.ResourceName } - params.ResourceType = (*string)(filter.ResourceType) - params.ResourceName = filter.ResourceName params.IssueType = (*string)(filter.IssueType) if filter.Severity != nil { params.Severity = new(issuesql.SeverityLevel(*filter.Severity)) @@ -95,6 +103,7 @@ func ListIssues(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagina return &IssueConnection{ Connection: *conn, teamSlug: teamSlug, + scope: scope, filter: filter, }, nil } diff --git a/internal/issue/queries/issue.sql b/internal/issue/queries/issue.sql index 7094ad820..184735412 100644 --- a/internal/issue/queries/issue.sql +++ b/internal/issue/queries/issue.sql @@ -115,18 +115,30 @@ SELECT OR severity = sqlc.narg('severity')::severity_level ) AND ( - sqlc.narg('resource_type')::TEXT IS NULL - OR resource_type = sqlc.narg('resource_type')::TEXT + sqlc.narg('filter_resource_type')::TEXT IS NULL + OR resource_type = sqlc.narg('filter_resource_type')::TEXT ) AND ( - sqlc.narg('resource_name')::TEXT IS NULL - OR resource_name = sqlc.narg('resource_name')::TEXT + sqlc.narg('filter_resource_name')::TEXT IS NULL + OR resource_name = sqlc.narg('filter_resource_name')::TEXT ) ) AS filtered_count FROM issues WHERE team = @team + AND ( + sqlc.narg('scope_resource_type')::TEXT IS NULL + OR resource_type = sqlc.narg('scope_resource_type')::TEXT + ) + AND ( + sqlc.narg('scope_resource_name')::TEXT IS NULL + OR resource_name = sqlc.narg('scope_resource_name')::TEXT + ) + AND ( + sqlc.narg('scope_env')::TEXT IS NULL + OR env = sqlc.narg('scope_env')::TEXT + ) GROUP BY severity, resource_type, From a8cc3f2d3ccf60aeb1e1def0d3e8aabe71f618d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bj=C3=B8rnstad?= Date: Wed, 1 Jul 2026 12:01:12 +0200 Subject: [PATCH 11/11] fix(issue): remove unused total_count from FacetsForIssues query --- internal/issue/facets_test.go | 12 ++++++------ internal/issue/issuesql/issue.sql.go | 3 --- internal/issue/queries/issue.sql | 1 - 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/internal/issue/facets_test.go b/internal/issue/facets_test.go index c63f32ee8..f2eb4430f 100644 --- a/internal/issue/facets_test.go +++ b/internal/issue/facets_test.go @@ -10,10 +10,10 @@ import ( func TestBuildFacets(t *testing.T) { rows := []*issuesql.FacetsForIssuesRow{ - {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "prod", IssueType: "DEPRECATED_INGRESS", TotalCount: 3, FilteredCount: 3}, - {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "dev", IssueType: "DEPRECATED_INGRESS", TotalCount: 1, FilteredCount: 1}, - {Severity: "WARNING", ResourceType: "JOB", Env: "prod", IssueType: "LAST_RUN_FAILED", TotalCount: 2, FilteredCount: 2}, - {Severity: "TODO", ResourceType: "SQLINSTANCE", Env: "prod", IssueType: "SQLINSTANCE_VERSION", TotalCount: 1, FilteredCount: 0}, + {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "prod", IssueType: "DEPRECATED_INGRESS", FilteredCount: 3}, + {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "dev", IssueType: "DEPRECATED_INGRESS", FilteredCount: 1}, + {Severity: "WARNING", ResourceType: "JOB", Env: "prod", IssueType: "LAST_RUN_FAILED", FilteredCount: 2}, + {Severity: "TODO", ResourceType: "SQLINSTANCE", Env: "prod", IssueType: "SQLINSTANCE_VERSION", FilteredCount: 0}, } tests := []struct { @@ -50,8 +50,8 @@ func TestBuildFacets(t *testing.T) { { name: "with filter: TODO row has filtered_count=0 but is still seeded", rows: []*issuesql.FacetsForIssuesRow{ - {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "prod", IssueType: "DEPRECATED_INGRESS", TotalCount: 3, FilteredCount: 3}, - {Severity: "WARNING", ResourceType: "JOB", Env: "dev", IssueType: "LAST_RUN_FAILED", TotalCount: 1, FilteredCount: 0}, + {Severity: "CRITICAL", ResourceType: "APPLICATION", Env: "prod", IssueType: "DEPRECATED_INGRESS", FilteredCount: 3}, + {Severity: "WARNING", ResourceType: "JOB", Env: "dev", IssueType: "LAST_RUN_FAILED", FilteredCount: 0}, }, wantSeverities: []IssueSeverityFacetItem{ {Severity: SeverityCritical, Count: 3}, diff --git a/internal/issue/issuesql/issue.sql.go b/internal/issue/issuesql/issue.sql.go index a38da0029..3aae4a915 100644 --- a/internal/issue/issuesql/issue.sql.go +++ b/internal/issue/issuesql/issue.sql.go @@ -16,7 +16,6 @@ SELECT resource_type, env, issue_type, - COUNT(*) AS total_count, COUNT(*) FILTER ( WHERE ( @@ -85,7 +84,6 @@ type FacetsForIssuesRow struct { ResourceType string Env string IssueType string - TotalCount int64 FilteredCount int64 } @@ -113,7 +111,6 @@ func (q *Queries) FacetsForIssues(ctx context.Context, arg FacetsForIssuesParams &i.ResourceType, &i.Env, &i.IssueType, - &i.TotalCount, &i.FilteredCount, ); err != nil { return nil, err diff --git a/internal/issue/queries/issue.sql b/internal/issue/queries/issue.sql index 184735412..68e68f9f4 100644 --- a/internal/issue/queries/issue.sql +++ b/internal/issue/queries/issue.sql @@ -99,7 +99,6 @@ SELECT resource_type, env, issue_type, - COUNT(*) AS total_count, COUNT(*) FILTER ( WHERE (