using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using TCMSDAL.DTO; using TCMSDAL.Interfaces; using TCMSDAL.QueryBuilders; namespace TCMSDAL.Implementations; public class TCMSCoverageDAL : ITCMSCoverageDAL { private readonly IQueryExecutor _QueryExecutor; public TCMSCoverageDAL(IQueryExecutor queryExecutor) { _QueryExecutor = queryExecutor; } public async Task> GetCoverageReportAsync( int? projectId, LoginDTO login, CancellationToken ct) => await _QueryExecutor.QueryAsync( login, TCMSCoverageQB.GET_COVERAGE_REPORT, new { TenantId = login.ClientId, ProjectId = projectId }, cancellationToken: ct).ConfigureAwait(false) ?? Enumerable.Empty(); public async Task> GetCoverageHeatmapAsync( int? projectId, LoginDTO login, CancellationToken ct) { var rows = await _QueryExecutor.QueryAsync( login, TCMSCoverageQB.GET_COVERAGE_HEATMAP, new { TenantId = login.ClientId, ProjectId = projectId }, cancellationToken: ct).ConfigureAwait(false) ?? Enumerable.Empty(); // Compute gap % and traffic-light status in-process foreach (var row in rows) { row.P1GapPct = 100 - row.P1Pct; row.P2GapPct = 100 - row.P2Pct; row.P3GapPct = 100 - row.P3Pct; row.P1Status = TrafficLight(row.P1Pct); row.P2Status = TrafficLight(row.P2Pct); row.P3Status = TrafficLight(row.P3Pct); } return rows; } public async Task SaveCoverageSnapshotAsync( TCMSCoverageSnapshotDTO dto, LoginDTO login, CancellationToken ct) => await _QueryExecutor.ExecuteAsync( login, TCMSCoverageQB.SAVE_COVERAGE_SNAPSHOT, new { dto.ModuleId, dto.TestRunId, dto.CoveragePct, dto.TotalCases, dto.PassedCases, TenantId = login.ClientId }, cancellationToken: ct).ConfigureAwait(false); public async Task> GetCoverageTrendAsync( int moduleId, LoginDTO login, CancellationToken ct) => await _QueryExecutor.QueryAsync( login, TCMSCoverageQB.GET_COVERAGE_TREND, new { ModuleId = moduleId, TenantId = login.ClientId }, cancellationToken: ct).ConfigureAwait(false) ?? Enumerable.Empty(); private static string TrafficLight(decimal pct) => pct switch { >= 80 => "Green", >= 50 => "Yellow", _ => "Red" }; }