Skip to content

Commit cd9c342

Browse files
fix(server): fix pagination for GetAllProjects to use limit and offset param [VIZ-2271] (#1845)
1 parent 8169a54 commit cd9c342

File tree

4 files changed

+86
-5
lines changed

4 files changed

+86
-5
lines changed

server/internal/adapter/internalapi/server.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,33 @@ func (s server) GetAllProjects(ctx context.Context, req *pb.GetAllProjectsReques
123123
}
124124
}
125125

126-
pagination := internalapimodel.ToProjectPagination(req.Pagination)
126+
maxLimit := int64(100)
127+
if req.Pagination.Limit != nil && *req.Pagination.Limit > maxLimit {
128+
req.Pagination.Limit = &maxLimit
129+
}
127130

128131
// Parse the sort type from the request
129132
sort := internalapimodel.ToProjectSortType(req.Sort)
130133

134+
var pagination *usecasex.Pagination
135+
var param *interfaces.ProjectListParam
136+
if req.Pagination != nil && req.Pagination.Offset != nil && req.Pagination.Limit != nil {
137+
param = &interfaces.ProjectListParam{
138+
Offset: req.Pagination.Offset,
139+
Limit: req.Pagination.Limit,
140+
}
141+
pagination = nil
142+
} else {
143+
pagination = internalapimodel.ToProjectPagination(req.Pagination)
144+
if pagination == nil {
145+
defaultLimit := int32(100)
146+
req.Pagination = &pb.Pagination{
147+
First: &defaultLimit,
148+
}
149+
pagination = internalapimodel.ToProjectPagination(req.Pagination)
150+
}
151+
}
152+
131153
// Convert SearchFieldType to string
132154
var searchField *string
133155
if req.SearchField != nil && *req.SearchField == pb.SearchFieldType_SEARCH_FIELD_TYPE_TOPICS {
@@ -146,7 +168,7 @@ func (s server) GetAllProjects(ctx context.Context, req *pb.GetAllProjectsReques
146168
visibility = &v
147169
}
148170

149-
res, info, err := uc.Project.FindAll(ctx, req.Keyword, sort, pagination, searchField, visibility)
171+
res, info, err := uc.Project.FindAll(ctx, req.Keyword, sort, pagination, param, searchField, visibility)
150172

151173
if err != nil {
152174
log.Errorf("GetAllProjects: Database query failed: %v", err)

server/internal/infrastructure/mongo/project.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/reearth/reearth/server/pkg/alias"
1515
"github.com/reearth/reearth/server/pkg/id"
1616
"github.com/reearth/reearth/server/pkg/project"
17+
"github.com/reearth/reearth/server/pkg/visualizer"
1718
"github.com/reearth/reearthx/account/accountdomain"
1819
"github.com/reearth/reearthx/log"
1920
"github.com/reearth/reearthx/mongox"
@@ -606,8 +607,61 @@ func (r *Project) FindAll(ctx context.Context, pFilter repo.ProjectFilter) ([]*p
606607
}
607608
}
608609

610+
if pFilter.Limit != nil && pFilter.Offset != nil {
611+
totalCount, err := r.client.Count(ctx, filter)
612+
if err != nil {
613+
log.Errorf("FindAll: Count error: %v", err)
614+
return nil, nil, visualizer.ErrorWithCallerLogging(ctx, "FindAll: Count error:", err)
615+
}
616+
617+
var sortDoc bson.D
618+
if pFilter.Sort != nil {
619+
sortKey := pFilter.Sort.Key
620+
if sortKey == "starcount" {
621+
sortKey = "star_count" // Map to MongoDB field name
622+
}
623+
sortOrder := 1
624+
if pFilter.Sort.Desc {
625+
sortOrder = -1
626+
}
627+
sortDoc = bson.D{{Key: sortKey, Value: sortOrder}}
628+
} else {
629+
sortDoc = bson.D{{Key: "star_count", Value: -1}}
630+
}
631+
632+
collation := options.Collation{
633+
Locale: "en",
634+
Strength: 3,
635+
CaseLevel: true,
636+
Alternate: "shifted",
637+
}
638+
639+
findOptions := options.Find().
640+
SetCollation(&collation).
641+
SetSkip(*pFilter.Offset).
642+
SetLimit(*pFilter.Limit)
643+
644+
if len(sortDoc) > 0 {
645+
findOptions.SetSort(sortDoc)
646+
}
647+
648+
c := mongodoc.NewProjectConsumer(nil)
649+
if err := r.client.Find(ctx, filter, c, findOptions); err != nil {
650+
log.Errorf("FindAll: Find error: %v", err)
651+
return nil, nil, visualizer.ErrorWithCallerLogging(ctx, "FindAll: Count error:", err)
652+
}
653+
654+
pageInfo := &usecasex.PageInfo{
655+
TotalCount: totalCount,
656+
HasNextPage: *pFilter.Offset+*pFilter.Limit < totalCount,
657+
HasPreviousPage: *pFilter.Offset > 0,
658+
}
659+
660+
return c.Result, pageInfo, visualizer.ErrorWithCallerLogging(ctx, "FindAll: Count error:", err)
661+
}
662+
609663
if pFilter.Pagination == nil {
610-
log.Warnf("FindAll: Pagination is nil, not using pagination")
664+
visualizer.WarnWithCallerLogging(ctx, "FindAll: No pagination provided, returning all results")
611665
}
612666

613667
projects, pageInfo, err := r.paginateWithoutWorkspaceFilter(ctx, filter, pFilter.Sort, pFilter.Pagination)

server/internal/usecase/interactor/project.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ func (i *Project) FindVisibilityByWorkspace(
341341
return result, pInfo, err
342342
}
343343

344-
func (i *Project) FindAll(ctx context.Context, keyword *string, sort *project.SortType, pagination *usecasex.Pagination, searchField *string, visibility *string) ([]*project.Project, *usecasex.PageInfo, error) {
344+
func (i *Project) FindAll(ctx context.Context, keyword *string, sort *project.SortType, pagination *usecasex.Pagination, param *interfaces.ProjectListParam, searchField *string, visibility *string) ([]*project.Project, *usecasex.PageInfo, error) {
345345
pFilter := repo.ProjectFilter{
346346
Keyword: keyword,
347347
Sort: sort,
@@ -350,6 +350,11 @@ func (i *Project) FindAll(ctx context.Context, keyword *string, sort *project.So
350350
Visibility: visibility,
351351
}
352352

353+
if param != nil {
354+
pFilter.Limit = param.Limit
355+
pFilter.Offset = param.Offset
356+
}
357+
353358
pList, pInfo, err := i.projectRepo.FindAll(ctx, pFilter)
354359
if err != nil {
355360
return nil, nil, err

server/internal/usecase/interfaces/project.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ type Project interface {
105105

106106
FindVisibilityByUser(context.Context, *user.User, bool, *usecase.Operator, *string, *project.SortType, *usecasex.Pagination, *ProjectListParam) ([]*project.Project, *usecasex.PageInfo, error)
107107
FindVisibilityByWorkspace(context.Context, accountdomain.WorkspaceID, bool, *usecase.Operator, *string, *project.SortType, *usecasex.Pagination, *ProjectListParam) ([]*project.Project, *usecasex.PageInfo, error)
108-
FindAll(context.Context, *string, *project.SortType, *usecasex.Pagination, *string, *string) ([]*project.Project, *usecasex.PageInfo, error)
108+
FindAll(context.Context, *string, *project.SortType, *usecasex.Pagination, *ProjectListParam, *string, *string) ([]*project.Project, *usecasex.PageInfo, error)
109109
UpdateVisibility(context.Context, id.ProjectID, string, *usecase.Operator) (*project.Project, error)
110110

111111
Create(context.Context, CreateProjectParam, *usecase.Operator) (*project.Project, error)

0 commit comments

Comments
 (0)