using MediatR; using Microsoft.EntityFrameworkCore; using ReC.Application.Common.Dto; using ReC.Application.Common.Exceptions; using ReC.Application.Common.Interfaces; using System.Text.Json; namespace ReC.Application.Common.Behaviors.Action; public class HeaderQueryBehavior(IRecDbContext dbContext) : IPipelineBehavior where TRequest : notnull where TResponse : IEnumerable { public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancel) { var actions = await next(cancel); foreach (var action in actions) await SetHeader(action, cancel); return actions; } private async Task SetHeader(RecActionViewDto action, CancellationToken cancel) { if (action.HeaderQuery is not string headerQuery) return; await using var command = dbContext.Database.GetDbConnection().CreateCommand(); command.CommandText = headerQuery; await dbContext.Database.OpenConnectionAsync(cancel); try { object? scalar; try { scalar = await command.ExecuteScalarAsync(cancel); } catch (Exception ex) { throw new DataIntegrityException( $"Header query execution failed. The stored SQL may be malformed. ActionId: {action.Id}, ProfileId: {action.ProfileId}, Error: {ex.Message}"); } if (scalar is not string rawHeader) throw new DataIntegrityException( $"Header query returned no result or a null value. ActionId: {action.Id}, ProfileId: {action.ProfileId}"); var headerDict = JsonSerializer.Deserialize>(rawHeader) ?? throw new DataIntegrityException( $"Header query returned invalid JSON. ActionId: {action.Id}, ProfileId: {action.ProfileId}"); action.Headers = headerDict.ToDictionary(header => header.Key, kvp => kvp.Value.ToString()); } finally { await dbContext.Database.CloseConnectionAsync(); } } }