using PostFundManagement.Application.Abstractions; using PostFundManagement.Application.Abstractions.Services; using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; namespace PostFundManagement.Application.Services.Evidence; public sealed class EvidenceCacheService(EvidenceService service, IDistributedCache cache) : ServiceCacheBase, IEvidenceService { public async ValueTask CreateEvidenceAsync(Guid userId, IFormCollection form, IFormFile file, CancellationToken cancellationToken = default) => await service.CreateEvidenceAsync(userId, form, file, cancellationToken); public async ValueTask CreateIndicatorAsync(CreateIndicatorRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.CreateIndicatorAsync(request, userId, cancellationToken); public async ValueTask CreateMilestoneAsync(CreateMilestoneRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.CreateMilestoneAsync(request, userId, cancellationToken); public async ValueTask> GetEvidenceAsync(string evidenceId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var cacheKey = HashService.ToMd5Hash($"getevidence-{evidenceId}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetEvidenceAsync(evidenceId, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return result.Value; } return Result.Ok(cached.FromJson()); })); public async ValueTask> GetEvidenceFilesAsync(Pagination pagination, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var cacheKey = HashService.ToMd5Hash($"getevidencefiles-{pagination.Page}-{pagination.PageSize}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetEvidenceFilesAsync(pagination, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return result.Value; } return Result.Ok(cached.FromJson()); })); public async ValueTask> GetIndicatorAsync(string indicatorId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var cacheKey = HashService.ToMd5Hash($"getindicator-{indicatorId}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetIndicatorAsync(indicatorId, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return result.Value; } return Result.Ok(cached.FromJson()); })); public async ValueTask> GetIndicatorsAsync(Pagination pagination, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var cacheKey = HashService.ToMd5Hash($"getindicators-{pagination.Page}-{pagination.PageSize}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetIndicatorsAsync(pagination, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return result.Value; } return Result.Ok(cached.FromJson()); })); public async ValueTask> GetMilestoneEvidencesAsync(string milestoneIdHash, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var cacheKey = HashService.ToMd5Hash($"getmilestoneevidences-{milestoneIdHash}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if(string.IsNullOrWhiteSpace(cached)) { var result = await service.GetMilestoneEvidencesAsync(milestoneIdHash, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return result.Value; } return Result.Ok(cached.FromJson()); })); public async ValueTask> GetProjectEvidencesAsync(string projectIdHash, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var cacheKey = HashService.ToMd5Hash($"getprojectevidences-{projectIdHash}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if(string.IsNullOrWhiteSpace(cached)) { var result = await service.GetProjectEvidencesAsync(projectIdHash, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return result.Value; } return Result.Ok(cached.FromJson()); })); public async ValueTask RecordIndicatorActualAmountAsync(string indicatorIdHash, decimal amount, Guid userId, CancellationToken cancellationToken = default) => await service.RecordIndicatorActualAmountAsync(indicatorIdHash, amount, userId, cancellationToken); public async ValueTask UpdateEvidenceAsync(UpdateEvidenceRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.UpdateEvidenceAsync(request, userId, cancellationToken); }