Run initial test for Climate Resilience Verification Suite

Add first part of Alert Quality Analytics
This commit is contained in:
voltsrage
2026-06-24 03:01:00 +08:00
parent 032cd1d240
commit 185dc93fa1
50 changed files with 4116 additions and 55 deletions
@@ -163,6 +163,54 @@ public class AlertService : IAlertService
return alert;
}
public async Task<AlertFeedback> SubmitFeedbackAsync(
Guid alertId, AlertFeedbackType type, string? comment)
{
if (!_currentUser.IsAuthenticated || _currentUser.UserId is null)
throw new ValidationException("Authentication required.", "AUTH_REQUIRED");
var userId = _currentUser.UserId.Value;
var alert = await _db.ClinicalAlerts.FindAsync(alertId);
if (alert is null)
throw new NotFoundException("Alert not found.", "ALERT_NOT_FOUND");
if (alert.Status == AlertStatus.Open)
throw new ValidationException(
"Feedback can only be submitted on acknowledged or resolved alerts.",
"ALERT_NOT_REVIEWABLE");
var alreadySubmitted = await _db.AlertFeedbacks
.AnyAsync(f => f.AlertId == alertId && f.UserId == userId);
if (alreadySubmitted)
throw new ConflictException(
"You have already submitted feedback for this alert.",
"FEEDBACK_ALREADY_SUBMITTED");
var feedback = new AlertFeedback
{
Id = Guid.NewGuid(),
AlertId = alertId,
UserId = userId,
FeedbackType = type,
Comment = string.IsNullOrWhiteSpace(comment) ? null : comment.Trim(),
CreatedAt = DateTimeOffset.UtcNow
};
_db.AlertFeedbacks.Add(feedback);
alert.FeedbackReceived = true;
await _db.SaveChangesAsync();
await _audit.WriteAsync(
AuditAction.AlertFeedbackSubmitted,
"ClinicalAlert",
alert.Id,
newValue: new { feedbackType = type.ToDbString(), feedback.UserId },
reason: comment);
return feedback;
}
private async Task<int> ResolveSuppressionWindowMinutesAsync(
AlertType alertType, int defaultWindowMinutes)
{