Skip to content
Merged

Merge #180

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions JobFlow.Business/Services/OrganizationClientService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,19 +125,21 @@ public async Task<Result<CursorPagedResponseDto<OrganizationClient>>> GetClients
var withEmailCount = await baseQuery.CountAsync(c => c.EmailAddress != null && c.EmailAddress.Trim() != string.Empty);
var withPhoneCount = await baseQuery.CountAsync(c => c.PhoneNumber != null && c.PhoneNumber.Trim() != string.Empty);

if (CursorToken.TryRead(cursor, out var cursorCreatedAt, out var cursorId))
var offset = 0;
if (CursorToken.TryReadOffset(cursor, out var parsedOffset))
{
query = query.Where(c => c.CreatedAt < cursorCreatedAt || (c.CreatedAt == cursorCreatedAt && c.Id.CompareTo(cursorId) < 0));
offset = parsedOffset;
}

var batch = await query
.Skip(offset)
.Take(size + 1)
.ToListAsync();

var hasMore = batch.Count > size;
var items = hasMore ? batch.Take(size).ToList() : batch;
var nextCursor = hasMore && items.Count > 0
? CursorToken.Build(items[^1].CreatedAt, items[^1].Id)
var nextCursor = hasMore
? CursorToken.BuildOffset(offset + size)
: null;

return Result.Success(new CursorPagedResponseDto<OrganizationClient>
Expand Down
32 changes: 32 additions & 0 deletions JobFlow.Business/Utilities/CursorToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ public static string Build(DateTime timestampUtc, Guid id)
return Convert.ToBase64String(Encoding.UTF8.GetBytes(raw));
}

public static string BuildOffset(int offset)
{
var raw = $"off|{offset}";
return Convert.ToBase64String(Encoding.UTF8.GetBytes(raw));
}

public static bool TryRead(string? cursor, out DateTime timestampUtc, out Guid id)
{
timestampUtc = default;
Expand All @@ -21,6 +27,11 @@ public static bool TryRead(string? cursor, out DateTime timestampUtc, out Guid i
try
{
var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(cursor));

// Skip offset-style cursors
if (decoded.StartsWith("off|"))
return false;

var split = decoded.Split('|', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
if (split.Length != 2)
return false;
Expand All @@ -39,4 +50,25 @@ public static bool TryRead(string? cursor, out DateTime timestampUtc, out Guid i
return false;
}
}

public static bool TryReadOffset(string? cursor, out int offset)
{
offset = 0;

if (string.IsNullOrWhiteSpace(cursor))
return false;

try
{
var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(cursor));
if (!decoded.StartsWith("off|"))
return false;

return int.TryParse(decoded.AsSpan(4), out offset) && offset >= 0;
}
catch
{
return false;
}
}
}
Loading