using SurrealDb.Net; using TarninaHub.Application.Abstractions; using TarninaHub.Application.Dtos; namespace TarninaHub.Infrastructure.Persistence; public sealed class GrantCallService : IGrantCallService { private const string SelectFields = "type::string(id) AS id, name, opens_at, closes_at, status, external_id"; private readonly ISurrealDbClient _client; public GrantCallService(ISurrealDbClient client) { _client = client; } public async Task> ListAsync( string? status, CancellationToken cancellationToken) { var parameters = new Dictionary(); var where = string.Empty; if (!string.IsNullOrWhiteSpace(status)) { where = " WHERE status = $status"; parameters["status"] = status; } var response = await _client.RawQuery( $"SELECT {SelectFields} FROM grant_call{where} ORDER BY opens_at DESC;", parameters, cancellationToken); response.EnsureAllOks(); var rows = response.GetValue>(0) ?? []; return rows.Select(Map).ToList(); } public async Task GetAsync(string grantCallId, CancellationToken cancellationToken) { var (table, id) = SurrealRecordId.Split(grantCallId); var response = await _client.RawQuery( $"SELECT {SelectFields} FROM type::record($table, $id) LIMIT 1;", new Dictionary { ["table"] = table, ["id"] = id }, cancellationToken); response.EnsureAllOks(); var rows = response.GetValue>(0) ?? []; return rows.Count > 0 ? Map(rows[0]) : null; } private static GrantCallResponse Map(GrantCallRow row) => new( row.Id, row.Name, row.OpensAt, row.ClosesAt, row.Status, row.ExternalId); }