package utils import ( "encoding/base64" "fmt" "strings" "time" "github.com/google/uuid" ) const ( DefaultLimit = 50 MaxLimit = 200 ) type CursorParams struct { CursorTime *time.Time CursorID *uuid.UUID Limit int32 } func ParseCursor(cursor string) (*time.Time, *uuid.UUID, error) { if cursor == "" { return nil, nil, nil } raw, err := base64.RawURLEncoding.DecodeString(cursor) if err != nil { return nil, nil, fmt.Errorf("invalid cursor encoding") } parts := strings.SplitN(string(raw), "|", 2) if len(parts) != 2 { return nil, nil, fmt.Errorf("invalid cursor format") } t, err := time.Parse(time.RFC3339Nano, parts[0]) if err != nil { return nil, nil, fmt.Errorf("invalid cursor time") } id, err := uuid.Parse(parts[1]) if err != nil { return nil, nil, fmt.Errorf("invalid cursor id") } return &t, &id, nil } func EncodeCursor(t time.Time, id uuid.UUID) string { raw := fmt.Sprintf("%s|%s", t.Format(time.RFC3339Nano), id.String()) return base64.RawURLEncoding.EncodeToString([]byte(raw)) } func ClampLimit(limit int) int32 { if limit <= 0 { return DefaultLimit } if limit > MaxLimit { return MaxLimit } return int32(limit) }