refactor: Replace offset pagination with cursor-based pagination for subscriber listing

- Replace Page and PageSize with Cursor and Limit in ListSubscribersRequest
- Replace Total, Page, and PageSize with NextCursor and HasMore in ListSubscribersResponse
- Add default limit of 20 with max cap of 100 in ListSubscribers
- Replace ListSubscribers call with ListSubscribersCursor in subscriber_crud.go
- Remove unused database import from subscriber_crud.go
- Replace context.Background() with context.Without
This commit is contained in:
nutcas3
2026-05-01 09:06:13 +03:00
parent 444d767ceb
commit 36748d534e
2 changed files with 18 additions and 19 deletions
@@ -53,17 +53,16 @@ type UpdateSubscriberRequest struct {
// ListSubscribersRequest is the query-filter payload for listing subscribers.
type ListSubscribersRequest struct {
Page int `json:"page" query:"page"`
PageSize int `json:"page_size" query:"page_size"`
Cursor string `json:"cursor" query:"cursor"`
Limit int `json:"limit" query:"limit"`
Status models.SubscriberStatus `json:"status" query:"status"`
OrganizationID string `json:"organization_id" query:"organization_id"`
Search string `json:"search" query:"search"`
}
// ListSubscribersResponse is the paginated subscriber list result.
// ListSubscribersResponse is the cursor-paginated subscriber list result.
type ListSubscribersResponse struct {
Subscribers []models.Subscriber `json:"subscribers"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NextCursor string `json:"next_cursor,omitempty"`
HasMore bool `json:"has_more"`
}
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"github.com/nutcas3/telecom-platform/apps/api-server/internal/database"
"github.com/nutcas3/telecom-platform/apps/api-server/internal/models"
"github.com/sirupsen/logrus"
)
@@ -44,7 +43,7 @@ func (s *SubscriberService) CreateSubscriber(ctx context.Context, req *CreateSub
subscriber.EUICCID = req.EUICCID
go func() {
// Use derived context for goroutine to respect parent cancellation
bgCtx := context.Background()
bgCtx := context.WithoutCancel(ctx)
if err := s.provisionESIMProfile(bgCtx, subscriber.ID); err != nil {
logrus.WithError(err).WithField("subscriber_id", subscriber.ID).Warn("Failed to provision eSIM profile")
}
@@ -106,24 +105,25 @@ func (s *SubscriberService) UpdateSubscriber(ctx context.Context, id uint, req *
return subscriber, nil
}
// ListSubscribers lists subscribers with pagination and filtering.
// ListSubscribers lists subscribers with cursor-based pagination and filtering.
func (s *SubscriberService) ListSubscribers(ctx context.Context, req *ListSubscribersRequest) (*ListSubscribersResponse, error) {
dbReq := &database.ListSubscribersRequest{
Page: req.Page,
PageSize: req.PageSize,
Status: string(req.Status),
OrganizationID: req.OrganizationID,
Search: req.Search,
// Set default limit if not provided
limit := req.Limit
if limit <= 0 {
limit = 20
}
subscribers, total, err := s.db.ListSubscribers(ctx, dbReq)
if limit > 100 {
limit = 100
}
subscribers, nextCursor, hasMore, err := s.db.ListSubscribersCursor(ctx, req.Cursor, limit, string(req.Status), req.OrganizationID, req.Search)
if err != nil {
return nil, fmt.Errorf("failed to list subscribers: %w", err)
}
return &ListSubscribersResponse{
Subscribers: subscribers,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
NextCursor: nextCursor,
HasMore: hasMore,
}, nil
}