Files
git.stella-ops.org/src/__Libraries/StellaOps.Provcache.Api/ProvcacheEndpointExtensions.GetEvidenceChunks.cs

96 lines
3.2 KiB
C#

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Globalization;
namespace StellaOps.Provcache.Api;
public static partial class ProvcacheEndpointExtensions
{
/// <summary>
/// GET /v1/provcache/proofs/{proofRoot}
/// </summary>
private static async Task<IResult> GetEvidenceChunksAsync(
string proofRoot,
int? offset,
int? limit,
bool? includeData,
[FromServices] IEvidenceChunkRepository chunkRepository,
ILogger<ProofsApiEndpoints> logger,
CancellationToken cancellationToken)
{
logger.LogDebug("GET /v1/provcache/proofs/{ProofRoot} offset={Offset} limit={Limit}", proofRoot, offset, limit);
try
{
if (offset is < 0)
{
return BadRequest("Offset must be zero or greater.", "Invalid pagination");
}
if (limit is <= 0)
{
return BadRequest("Limit must be greater than zero.", "Invalid pagination");
}
var startIndex = offset ?? 0;
var pageSize = Math.Min(limit ?? DefaultPageSize, MaxPageSize);
// Get manifest for total count
var manifest = await chunkRepository.GetManifestAsync(proofRoot, cancellationToken);
if (manifest is null)
{
return Results.NotFound();
}
if (startIndex >= manifest.TotalChunks)
{
return Results.Ok(new ProofEvidenceResponse
{
ProofRoot = proofRoot,
TotalChunks = manifest.TotalChunks,
TotalSize = manifest.TotalSize,
Chunks = [],
NextCursor = null,
HasMore = false
});
}
// Get chunk range
var chunks = await chunkRepository.GetChunkRangeAsync(proofRoot, startIndex, pageSize, cancellationToken);
var chunkResponses = chunks
.OrderBy(c => c.ChunkIndex)
.Select(c => new ProofChunkResponse
{
ChunkId = c.ChunkId,
Index = c.ChunkIndex,
Hash = c.ChunkHash,
Size = c.BlobSize,
ContentType = c.ContentType,
Data = includeData == true ? Convert.ToBase64String(c.Blob) : null
}).ToList();
var hasMore = startIndex + chunks.Count < manifest.TotalChunks;
var nextCursor = hasMore
? (startIndex + pageSize).ToString(CultureInfo.InvariantCulture)
: null;
return Results.Ok(new ProofEvidenceResponse
{
ProofRoot = proofRoot,
TotalChunks = manifest.TotalChunks,
TotalSize = manifest.TotalSize,
Chunks = chunkResponses,
NextCursor = nextCursor,
HasMore = hasMore
});
}
catch (Exception ex)
{
logger.LogError(ex, "Error getting evidence chunks for proof root {ProofRoot}", proofRoot);
return InternalError("Evidence retrieval failed");
}
}
}