Hardened API and catered for Partner role query filter bypass

This commit is contained in:
2026-10-04 08:18:43 +02:00
parent 8d069c2da0
commit 8100518549
62 changed files with 232 additions and 193 deletions
@@ -46,7 +46,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
context.Evidences.Add(evidence);
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create evidence."));
}));
public async Task<Result> RecordIndicatorActualAmountAsync(string indicatorIdHash, decimal amount, Guid userId, CancellationToken cancellationToken = default) =>
@@ -65,7 +65,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
.SetProperty(f => f.ActualAmount, amount)
.SetProperty(f => f.CreatedBy, userId), cancellationToken);
return Result.OkIf(changedTotal > 0, UpdateError.New);
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to update indicator."));
}));
public async Task<Result<Indicator[]>> GetIndicatorsAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
@@ -79,7 +79,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
.Take(pagination.PageSize)
.ToListAsync(cancellationToken);
return Result.Ok(indicators.Select(i => i.Map()).ToArray());
return Result.Ok(indicators?.Select(i => i.Map()).ToArray() ?? []);
}));
public async Task<Result<Domain.Models.Evidence[]>> GetEvidenceFilesAsync(Pagination pagination, CancellationToken cancellationToken = default) =>
@@ -93,7 +93,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
.Take(pagination.PageSize)
.ToListAsync(cancellationToken);
return Result.Ok(evidence.Select(i => i.Map()).ToArray());
return Result.Ok(evidence?.Select(i => i.Map()).ToArray() ?? []);
}));
public async Task<Result> CreateMilestoneAsync(CreateMilestoneRequest request, Guid userId, CancellationToken cancellationToken = default) =>
@@ -142,7 +142,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
CreatedAt = DateTime.UtcNow
});
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create indicator."));
}));
public async Task<Result<Indicator>> GetIndicatorAsync(string indicatorId, CancellationToken cancellationToken) =>
@@ -158,8 +158,8 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
var indicator = await context.Indicators.AsNoTracking().FirstOrDefaultAsync(i => i.Id == decodeResult.Value, cancellationToken);
return Result.FailIf(indicator is null, NotFoundError.New)
.ToResult(indicator!.Map());
return Result.FailIf(indicator is null, NotFoundError.Create("Indicator not found."))
.ToResult(indicator?.Map()!);
}));
public async Task<Result<Domain.Models.Evidence>> GetEvidenceAsync(string evidenceId, CancellationToken cancellationToken = default) =>
@@ -175,8 +175,8 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
var evidence = await context.Evidences.AsNoTracking().FirstOrDefaultAsync(e => e.Id == decodeResult.Value, cancellationToken);
return Result.FailIf(evidence is null, NotFoundError.New)
.ToResult(evidence!.Map());
return Result.FailIf(evidence is null, NotFoundError.Create("Evidence not found."))
.ToResult(evidence?.Map()!);
}));
public async Task<Result<Domain.Models.Evidence[]>> GetMilestoneEvidencesAsync(string milestoneIdHash, CancellationToken cancellationToken = default) =>
@@ -196,7 +196,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
.ThenByDescending(o => o.UpdatedAt)
.ToListAsync(cancellationToken);
return Result.Ok(evidences.Select(e => e.Map()).ToArray());
return Result.Ok(evidences?.Select(e => e.Map()).ToArray() ?? []);
}));
public async Task<Result<Domain.Models.Evidence[]>> GetProjectEvidencesAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
@@ -216,7 +216,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
.ThenBy(o => o.UpdatedAt)
.ToListAsync(cancellationToken);
return Result.Ok(evidences.Select(e => e.Map()).ToArray());
return Result.Ok(evidences?.Select(e => e.Map()).ToArray() ?? []);
}));
public async Task<Result> UpdateEvidenceAsync(UpdateEvidenceRequest request, Guid userId, CancellationToken cancellationToken = default) =>
@@ -235,7 +235,7 @@ public sealed class EvidenceService(IDbContextFactory<ApplicationDbContext> cont
.SetProperty(f => f.UpdatedBy, userId)
.SetProperty(f => f.UpdatedAt, DateTime.UtcNow), cancellationToken);
return Result.OkIf(changedTotal > 0, UpdateError.New);
return Result.OkIf(changedTotal > 0, UpdateError.Create("Failed to update evidence."));
}));
public async Task<Result<string>> GetEvidenceUrlAsync(string evidenceIdHash, CancellationToken cancellationToken = default) =>