using Health.Domain.Entities; using Health.Domain.Enums; namespace Health.Application.Reports; public sealed record ReportUploadFile( string FileName, long Length, Stream Content); public sealed record ReportDto( Guid Id, Guid UserId, string FileUrl, string FileType, string Category, string Status, string AiStatus, string ReviewStatus, string? Severity, string? AiSummary, string? AiIndicators, string? DoctorComment, string? DoctorRecommendation, string? DoctorName, DateTime? ReviewedAt, DateTime CreatedAt); public sealed record ReportUploadResult( bool Success, int Code, string? Message, ReportDto? Report); public sealed record ReportAnalysisJob( Guid TaskId, Guid ReportId, string FilePath); public sealed record StoredReportFile( string FileUrl, string FilePath); public interface IReportService { Task> GetReportsAsync(Guid userId, CancellationToken ct); Task GetReportAsync(Guid userId, Guid reportId, CancellationToken ct); Task UploadReportAsync(Guid userId, ReportUploadFile file, CancellationToken ct); Task DeleteReportAsync(Guid userId, Guid reportId, CancellationToken ct); Task ReanalyzeReportAsync(Guid userId, Guid reportId, CancellationToken ct); } public interface IReportAnalysisQueue { Task EnqueueAsync(ReportAnalysisJob job, CancellationToken ct = default); Task RecoverStaleAsync(CancellationToken ct); Task TryTakeAsync(CancellationToken ct); Task CompleteAsync(Guid taskId, CancellationToken ct); Task RetryAsync(Guid taskId, string error, CancellationToken ct); } public interface IReportAnalysisService { Task AnalyzeAsync(ReportAnalysisJob job, CancellationToken ct); } public interface IReportRepository { Task> ListAsync(Guid userId, CancellationToken ct); Task GetOwnedAsync(Guid userId, Guid reportId, CancellationToken ct); Task GetByIdAsync(Guid reportId, CancellationToken ct); Task AddAsync(Report report, CancellationToken ct); void Delete(Report report); Task SaveChangesAsync(CancellationToken ct); } public interface IReportFileStorage { Task SaveAsync(ReportUploadFile file, string extension, CancellationToken ct); string GetLocalFilePath(string fileUrl); bool Exists(string filePath); void Delete(string filePath); }