Skip to content

Commit

Permalink
feat: add sort options in runs and projects list api (#1381)
Browse files Browse the repository at this point in the history
* feat: add sort options in runs and projects list api

* feat: add sort options in runs and projects list api

* feat: add sort options in runs and projects list api
  • Loading branch information
ffforest authored Jan 15, 2025
1 parent a062c84 commit 7682e8c
Showing 20 changed files with 206 additions and 42 deletions.
36 changes: 32 additions & 4 deletions api/openapispec/docs.go
Original file line number Diff line number Diff line change
@@ -1046,6 +1046,18 @@ const docTemplate = `{
"description": "The size of the page. Default to 10",
"name": "pageSize",
"in": "query"
},
{
"type": "string",
"description": "Which field to sort the list by. Default to id",
"name": "sortBy",
"in": "query"
},
{
"type": "boolean",
"description": "Whether to sort the list in ascending order. Default to false",
"name": "ascending",
"in": "query"
}
],
"responses": {
@@ -1649,6 +1661,18 @@ const docTemplate = `{
"description": "The size of the page. Default to 10",
"name": "pageSize",
"in": "query"
},
{
"type": "string",
"description": "Which field to sort the list by. Default to id",
"name": "sortBy",
"in": "query"
},
{
"type": "boolean",
"description": "Whether to sort the list in ascending order. Default to false",
"name": "ascending",
"in": "query"
}
],
"responses": {
@@ -3866,18 +3890,18 @@ const docTemplate = `{
"constant.SourceProviderType": {
"type": "string",
"enum": [
"git",
"git",
"github",
"oci",
"local"
"local",
"git"
],
"x-enum-varnames": [
"DefaultSourceType",
"SourceProviderTypeGit",
"SourceProviderTypeGithub",
"SourceProviderTypeOCI",
"SourceProviderTypeLocal"
"SourceProviderTypeLocal",
"DefaultSourceType"
]
},
"constant.StackState": {
@@ -4277,6 +4301,10 @@ const docTemplate = `{
"description": "ResourceType is the type of the resource.",
"type": "string"
},
"resourceURN": {
"description": "ResourceURN is the urn of the resource.",
"type": "string"
},
"status": {
"description": "Status is the status of the resource.",
"type": "string"
36 changes: 32 additions & 4 deletions api/openapispec/swagger.json
Original file line number Diff line number Diff line change
@@ -1035,6 +1035,18 @@
"description": "The size of the page. Default to 10",
"name": "pageSize",
"in": "query"
},
{
"type": "string",
"description": "Which field to sort the list by. Default to id",
"name": "sortBy",
"in": "query"
},
{
"type": "boolean",
"description": "Whether to sort the list in ascending order. Default to false",
"name": "ascending",
"in": "query"
}
],
"responses": {
@@ -1638,6 +1650,18 @@
"description": "The size of the page. Default to 10",
"name": "pageSize",
"in": "query"
},
{
"type": "string",
"description": "Which field to sort the list by. Default to id",
"name": "sortBy",
"in": "query"
},
{
"type": "boolean",
"description": "Whether to sort the list in ascending order. Default to false",
"name": "ascending",
"in": "query"
}
],
"responses": {
@@ -3855,18 +3879,18 @@
"constant.SourceProviderType": {
"type": "string",
"enum": [
"git",
"git",
"github",
"oci",
"local"
"local",
"git"
],
"x-enum-varnames": [
"DefaultSourceType",
"SourceProviderTypeGit",
"SourceProviderTypeGithub",
"SourceProviderTypeOCI",
"SourceProviderTypeLocal"
"SourceProviderTypeLocal",
"DefaultSourceType"
]
},
"constant.StackState": {
@@ -4266,6 +4290,10 @@
"description": "ResourceType is the type of the resource.",
"type": "string"
},
"resourceURN": {
"description": "ResourceURN is the urn of the resource.",
"type": "string"
},
"status": {
"description": "Status is the status of the resource.",
"type": "string"
23 changes: 21 additions & 2 deletions api/openapispec/swagger.yaml
Original file line number Diff line number Diff line change
@@ -30,17 +30,17 @@ definitions:
constant.SourceProviderType:
enum:
- git
- git
- github
- oci
- local
- git
type: string
x-enum-varnames:
- DefaultSourceType
- SourceProviderTypeGit
- SourceProviderTypeGithub
- SourceProviderTypeOCI
- SourceProviderTypeLocal
- DefaultSourceType
constant.StackState:
enum:
- UnSynced
@@ -325,6 +325,9 @@ definitions:
resourceType:
description: ResourceType is the type of the resource.
type: string
resourceURN:
description: ResourceURN is the urn of the resource.
type: string
status:
description: Status is the status of the resource.
type: string
@@ -2086,6 +2089,14 @@ paths:
in: query
name: pageSize
type: integer
- description: Which field to sort the list by. Default to id
in: query
name: sortBy
type: string
- description: Whether to sort the list in ascending order. Default to false
in: query
name: ascending
type: boolean
produces:
- application/json
responses:
@@ -2478,6 +2489,14 @@ paths:
in: query
name: pageSize
type: integer
- description: Which field to sort the list by. Default to id
in: query
name: sortBy
type: string
- description: Whether to sort the list in ascending order. Default to false
in: query
name: ascending
type: boolean
produces:
- application/json
responses:
4 changes: 4 additions & 0 deletions pkg/domain/constant/global.go
Original file line number Diff line number Diff line change
@@ -27,6 +27,10 @@ const (
ResourcePageSizeLarge = 1000
CommonPageDefault = 1
CommonPageSizeDefault = 10
SortByCreateTimestamp = "createTimestamp"
SortByModifiedTimestamp = "modifiedTimestamp"
SortByName = "name"
SortByID = "id"
)

var (
5 changes: 5 additions & 0 deletions pkg/domain/entity/types.go
Original file line number Diff line number Diff line change
@@ -4,3 +4,8 @@ type Pagination struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
}

type SortOptions struct {
Field string
Ascending bool
}
4 changes: 2 additions & 2 deletions pkg/domain/repository/repository.go
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ type ProjectRepository interface {
// GetByName retrieves a project by its name.
GetByName(ctx context.Context, name string) (*entity.Project, error)
// List retrieves all existing projects.
List(ctx context.Context, filter *entity.ProjectFilter) (*entity.ProjectListResult, error)
List(ctx context.Context, filter *entity.ProjectFilter, sortOptions *entity.SortOptions) (*entity.ProjectListResult, error)
}

// StackRepository is an interface that defines the repository operations
@@ -150,5 +150,5 @@ type RunRepository interface {
// Get retrieves a run by its ID.
Get(ctx context.Context, id uint) (*entity.Run, error)
// List retrieves all existing run.
List(ctx context.Context, filter *entity.RunFilter) (*entity.RunListResult, error)
List(ctx context.Context, filter *entity.RunFilter, sortOptions *entity.SortOptions) (*entity.RunListResult, error)
}
9 changes: 8 additions & 1 deletion pkg/infra/persistence/project.go
Original file line number Diff line number Diff line change
@@ -110,13 +110,20 @@ func (r *projectRepository) GetByName(ctx context.Context, name string) (*entity
}

// List retrieves all projects.
func (r *projectRepository) List(ctx context.Context, filter *entity.ProjectFilter) (*entity.ProjectListResult, error) {
func (r *projectRepository) List(ctx context.Context, filter *entity.ProjectFilter, sortOptions *entity.SortOptions) (*entity.ProjectListResult, error) {
var dataModel []ProjectModel
projectEntityList := make([]*entity.Project, 0)
pattern, args := GetProjectQuery(filter)

sortArgs := sortOptions.Field
if !sortOptions.Ascending {
sortArgs += " DESC"
}

searchResult := r.db.WithContext(ctx).
Preload("Source").
Preload("Organization").
Order(sortArgs).
Where(pattern, args...)

// Get total rows
4 changes: 3 additions & 1 deletion pkg/infra/persistence/project_test.go
Original file line number Diff line number Diff line change
@@ -162,7 +162,7 @@ func TestProjectRepository(t *testing.T) {
sqlmock.NewRows([]string{"count"}).
AddRow(2))

sqlMock.ExpectQuery("SELECT .* FROM `project` .* IS NULL LIMIT").
sqlMock.ExpectQuery("SELECT .* FROM `project` .* IS NULL .* LIMIT").
WillReturnRows(
sqlmock.NewRows([]string{"id", "name", "path", "Organization__id", "Organization__name", "Organization__owners", "Source__id", "Source__remote", "Source__source_provider"}).
AddRow(expectedID, expectedName, expectedPath, 1, "mockedOrg", expectedOrgOwners, 1, "https://github.com/test/repo", constant.SourceProviderTypeGithub).
@@ -173,6 +173,8 @@ func TestProjectRepository(t *testing.T) {
Page: constant.CommonPageDefault,
PageSize: constant.CommonPageSizeDefault,
},
}, &entity.SortOptions{
Field: constant.SortByID,
})
require.NoError(t, err)
require.Len(t, actual.Projects, 2)
9 changes: 8 additions & 1 deletion pkg/infra/persistence/run.go
Original file line number Diff line number Diff line change
@@ -96,15 +96,22 @@ func (r *runRepository) Get(ctx context.Context, id uint) (*entity.Run, error) {
}

// List retrieves all runs.
func (r *runRepository) List(ctx context.Context, filter *entity.RunFilter) (*entity.RunListResult, error) {
func (r *runRepository) List(ctx context.Context, filter *entity.RunFilter, sortOptions *entity.SortOptions) (*entity.RunListResult, error) {
var dataModel []RunModel
runEntityList := make([]*entity.Run, 0)
pattern, args := GetRunQuery(filter)

sortArgs := sortOptions.Field
if !sortOptions.Ascending {
sortArgs += " DESC"
}

searchResult := r.db.WithContext(ctx).
Preload("Stack").Preload("Stack.Project").
Joins("JOIN stack ON stack.id = run.stack_id").
Joins("JOIN project ON project.id = stack.project_id").
Joins("JOIN workspace ON workspace.name = run.workspace").
Order(sortArgs).
Where(pattern, args...)

// Get total rows
4 changes: 2 additions & 2 deletions pkg/server/handler/module/handler.go
Original file line number Diff line number Diff line change
@@ -97,7 +97,7 @@ func (h *Handler) DeleteModule() http.HandlerFunc {
// @Failure 429 {object} error "Too Many Requests"
// @Failure 404 {object} error "Not Found"
// @Failure 500 {object} error "Internal Server Error"
// @Router /api/v1/modules/{moduleName} [put]
// @Router /api/v1/modules/{moduleName} [put]
func (h *Handler) UpdateModule() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Getting stuff from context.
@@ -139,7 +139,7 @@ func (h *Handler) UpdateModule() http.HandlerFunc {
// @Failure 429 {object} error "Too Many Requests"
// @Failure 404 {object} error "Not Found"
// @Failure 500 {object} error "Internal Server Error"
// @Router /api/v1/modules/{moduleName} [get]
// @Router /api/v1/modules/{moduleName} [get]
func (h *Handler) GetModule() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Getting stuff from context.
6 changes: 4 additions & 2 deletions pkg/server/handler/project/handler.go
Original file line number Diff line number Diff line change
@@ -174,6 +174,8 @@ func (h *Handler) GetProject() http.HandlerFunc {
// @Param fuzzyName query string false "Fuzzy match project name to filter project list by."
// @Param page query uint false "The current page to fetch. Default to 1"
// @Param pageSize query uint false "The size of the page. Default to 10"
// @Param sortBy query string false "Which field to sort the list by. Default to id"
// @Param ascending query bool false "Whether to sort the list in ascending order. Default to false"
// @Success 200 {object} handler.Response{data=[]response.PaginatedProjectResponse} "Success"
// @Failure 400 {object} error "Bad Request"
// @Failure 401 {object} error "Unauthorized"
@@ -189,13 +191,13 @@ func (h *Handler) ListProjects() http.HandlerFunc {
logger.Info("Listing project...")

query := r.URL.Query()
filter, err := h.projectManager.BuildProjectFilter(ctx, &query)
filter, projectSortOptions, err := h.projectManager.BuildProjectFilterAndSortOptions(ctx, &query)
if err != nil {
render.Render(w, r, handler.FailureResponse(ctx, err))
return
}

projectEntities, err := h.projectManager.ListProjects(ctx, filter)
projectEntities, err := h.projectManager.ListProjects(ctx, filter, projectSortOptions)
if err != nil {
render.Render(w, r, handler.FailureResponse(ctx, err))
return
1 change: 0 additions & 1 deletion pkg/server/handler/stack/handler.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//nolint:dupl
package stack

import (
7 changes: 4 additions & 3 deletions pkg/server/handler/stack/run.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//nolint:dupl
package stack

import (
@@ -87,6 +86,8 @@ func (h *Handler) GetRunResult() http.HandlerFunc {
// @Param endTime query string false "EndTime to filter runs by. Default to all. Format: RFC3339"
// @Param page query uint false "The current page to fetch. Default to 1"
// @Param pageSize query uint false "The size of the page. Default to 10"
// @Param sortBy query string false "Which field to sort the list by. Default to id"
// @Param ascending query bool false "Whether to sort the list in ascending order. Default to false"
// @Success 200 {object} handler.Response{data=response.PaginatedRunResponse} "Success"
// @Failure 400 {object} error "Bad Request"
// @Failure 401 {object} error "Unauthorized"
@@ -102,14 +103,14 @@ func (h *Handler) ListRuns() http.HandlerFunc {
logger.Info("Listing runs...")

query := r.URL.Query()
filter, err := h.stackManager.BuildRunFilter(ctx, &query)
filter, runSortOptions, err := h.stackManager.BuildRunFilterAndSortOptions(ctx, &query)
if err != nil {
render.Render(w, r, handler.FailureResponse(ctx, err))
return
}

// List runs
runEntities, err := h.stackManager.ListRuns(ctx, filter)
runEntities, err := h.stackManager.ListRuns(ctx, filter, runSortOptions)
if err != nil {
render.Render(w, r, handler.FailureResponse(ctx, err))
return
2 changes: 1 addition & 1 deletion pkg/server/handler/workspace/configs.go
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@ func (h *Handler) UpdateWorkspaceConfigs() http.HandlerFunc {
// @Failure 429 {object} error "Too Many Requests"
// @Failure 404 {object} error "Not Found"
// @Failure 500 {object} error "Internal Server Error"
// @Router /api/v1/workspaces/{workspaceID}/configs/mod-deps [post]
// @Router /api/v1/workspaces/{workspaceID}/configs/mod-deps [post]
func (h *Handler) CreateWorkspaceModDeps() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// Getting stuff from context.
Loading

0 comments on commit 7682e8c

Please sign in to comment.