hybrid pagination

This commit is contained in:
Mazyar
2026-05-17 17:21:36 +03:30
parent 42d0a47226
commit 6dac5b482a
39 changed files with 696 additions and 386 deletions
+9 -1
View File
@@ -185,8 +185,16 @@ func (h *Handler) SearchInquiries(c echo.Context) error {
}
// Call service
inquiries, err := h.service.Search(c.Request().Context(), form, response.NewPagination(c))
pagination, err := response.NewPagination(c)
if err != nil {
return response.PaginationBadRequest(c, err)
}
inquiries, err := h.service.Search(c.Request().Context(), form, pagination)
if err != nil {
if response.IsListPaginationError(err) {
return response.PaginationBadRequest(c, err)
}
return response.InternalServerError(c, "Failed to search inquiries")
}
+16 -22
View File
@@ -16,7 +16,7 @@ type Repository interface {
Create(ctx context.Context, inquiry *Inquiry) error
GetByID(ctx context.Context, id string) (*Inquiry, error)
UpdateStatus(ctx context.Context, id string, status, reason, changedBy, description string) error
Search(ctx context.Context, form *SearchInquiriesForm, pagination *response.Pagination) ([]Inquiry, int64, error)
Search(ctx context.Context, form *SearchInquiriesForm, pagination *response.Pagination) (*orm.PaginatedResult[Inquiry], error)
Delete(ctx context.Context, id string) error
CheckPendingInquiry(ctx context.Context, email string) (*Inquiry, error)
CheckPendingInquiryByPhone(ctx context.Context, phone string) (*Inquiry, error)
@@ -206,7 +206,7 @@ func (r *inquiryRepository) CheckPendingInquiryByPhone(ctx context.Context, phon
}
// Search retrieves inquiries with pagination and filters
func (r *inquiryRepository) Search(ctx context.Context, form *SearchInquiriesForm, pagination *response.Pagination) ([]Inquiry, int64, error) {
func (r *inquiryRepository) Search(ctx context.Context, form *SearchInquiriesForm, pagination *response.Pagination) (*orm.PaginatedResult[Inquiry], error) {
filter := bson.M{}
// Add search filter
@@ -223,34 +223,28 @@ func (r *inquiryRepository) Search(ctx context.Context, form *SearchInquiriesFor
filter["status"] = *form.Status
}
// Build sort
sort := "created_at"
if pagination.SortBy != "" {
sort = pagination.SortBy
mongoPagination, err := orm.BuildListPagination(
pagination.Limit,
pagination.Offset,
pagination.Cursor,
pagination.SortBy,
pagination.SortOrder,
filter,
orm.ListPaginationOptions{},
)
if err != nil {
return nil, err
}
sortOrder := "desc"
if pagination.SortOrder != "" {
sortOrder = pagination.SortOrder
}
// Build pagination
paginationBuilder := orm.NewPaginationBuilder().
Limit(pagination.Limit).
Skip(pagination.Offset).
SortBy(sort, sortOrder).
Build()
// Use ORM to find inquiries
result, err := r.ormRepo.FindAll(ctx, filter, paginationBuilder)
result, err := r.ormRepo.FindAll(ctx, filter, mongoPagination)
if err != nil {
r.logger.Error("Failed to search inquiries", map[string]interface{}{
"error": err.Error(),
})
return nil, 0, err
return nil, err
}
return result.Items, result.TotalCount, nil
return result, nil
}
// Delete deletes an inquiry
+5 -7
View File
@@ -273,29 +273,27 @@ func (s *inquiryService) Search(ctx context.Context, form *SearchInquiriesForm,
"offset": pagination.Offset,
})
// Get inquiries
inquiries, total, err := s.repository.Search(ctx, form, pagination)
page, err := s.repository.Search(ctx, form, pagination)
if err != nil {
s.logger.Error("Failed to search inquiries", map[string]interface{}{
"error": err.Error(),
})
return nil, errors.New("failed to search inquiries")
return nil, err
}
// Convert to responses
var inquiryResponses []*InquiryResponse
for _, inquiry := range inquiries {
for _, inquiry := range page.Items {
inquiryResponses = append(inquiryResponses, inquiry.ToResponse())
}
s.logger.Info("Inquiries search completed successfully", map[string]interface{}{
"total_found": total,
"total_found": page.TotalCount,
"returned": len(inquiryResponses),
})
return &InquiryListResponse{
Inquiries: inquiryResponses,
Meta: pagination.Response(total),
Meta: pagination.ListMeta(page.TotalCount, page.NextCursor, page.HasMore, page.PageOffset),
}, nil
}