mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-22 20:52:18 +00:00
feat: Add cursor-based pagination for subscribers and parameterize test password
- Add ListSubscribersCursor method to Database with ID-based cursor pagination - Add cursor, hasMore, and nextCursor support for efficient pagination - Add status, organizationID, and search filters to cursor-based query - Add limit+1 fetch strategy to detect additional results - Add fmt import to database/crud.go - Add TEST_PASSWORD environment variable support in integration tests with default fallback - Replace hard
This commit is contained in:
@@ -2,6 +2,7 @@ package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/nutcas3/telecom-platform/apps/api-server/internal/models"
|
||||
"gorm.io/gorm"
|
||||
@@ -59,6 +60,52 @@ func (d *Database) ListSubscribers(ctx context.Context, req *ListSubscribersRequ
|
||||
return subscribers, total, err
|
||||
}
|
||||
|
||||
// ListSubscribersCursor implements cursor-based pagination for subscribers
|
||||
func (d *Database) ListSubscribersCursor(ctx context.Context, cursor string, limit int, status, organizationID, search string) ([]models.Subscriber, string, bool, error) {
|
||||
var subscribers []models.Subscriber
|
||||
|
||||
query := d.DB.WithContext(ctx).Model(&models.Subscriber{})
|
||||
|
||||
// Apply filters
|
||||
if status != "" {
|
||||
query = query.Where("status = ?", status)
|
||||
}
|
||||
if organizationID != "" {
|
||||
query = query.Where("organization_id = ?", organizationID)
|
||||
}
|
||||
if search != "" {
|
||||
query = query.Where("first_name ILIKE ? OR last_name ILIKE ? OR email ILIKE ? OR msisdn ILIKE ?",
|
||||
"%"+search+"%", "%"+search+"%", "%"+search+"%", "%"+search+"%")
|
||||
}
|
||||
|
||||
// Apply cursor-based pagination (using ID as cursor)
|
||||
if cursor != "" {
|
||||
query = query.Where("id < ?", cursor)
|
||||
}
|
||||
|
||||
// Order by ID descending and apply limit
|
||||
query = query.Order("id DESC").Limit(limit + 1) // +1 to check if there are more results
|
||||
|
||||
err := query.Preload("Plan").Find(&subscribers).Error
|
||||
if err != nil {
|
||||
return nil, "", false, err
|
||||
}
|
||||
|
||||
// Determine if there are more results
|
||||
hasMore := len(subscribers) > limit
|
||||
if hasMore {
|
||||
subscribers = subscribers[:limit] // Remove the extra item
|
||||
}
|
||||
|
||||
// Generate next cursor
|
||||
var nextCursor string
|
||||
if len(subscribers) > 0 {
|
||||
nextCursor = fmt.Sprintf("%d", subscribers[len(subscribers)-1].ID)
|
||||
}
|
||||
|
||||
return subscribers, nextCursor, hasMore, nil
|
||||
}
|
||||
|
||||
func (d *Database) GetActiveSessionsByIMSI(ctx context.Context, imsi models.IMSI) ([]models.Session, error) {
|
||||
var sessions []models.Session
|
||||
err := d.DB.WithContext(ctx).Where("subscriber_id = ? AND status = ?", imsi, "active").Find(&sessions).Error
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -68,7 +69,11 @@ func setupTest(t *testing.T) *TestSetup {
|
||||
|
||||
for _, user := range testUsers {
|
||||
// Hash the password properly for testing
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte("password123"), bcrypt.DefaultCost)
|
||||
testPassword := os.Getenv("TEST_PASSWORD")
|
||||
if testPassword == "" {
|
||||
testPassword = "default_test_password_change_me"
|
||||
}
|
||||
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(testPassword), bcrypt.DefaultCost)
|
||||
require.NoError(t, err)
|
||||
user.Password = string(hashedPassword)
|
||||
err = db.Create(user).Error
|
||||
|
||||
Reference in New Issue
Block a user