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, IFeatureManager featureManager) : ServiceCacheBase, IEvidenceService { public async Task CreateEvidenceAsync(Guid userId, IFormCollection form, IFormFile file, CancellationToken cancellationToken = default) => await service.CreateEvidenceAsync(userId, form, file, cancellationToken); public async Task CreateIndicatorAsync(CreateIndicatorRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.CreateIndicatorAsync(request, userId, cancellationToken); public async Task CreateMilestoneAsync(CreateMilestoneRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.CreateMilestoneAsync(request, userId, cancellationToken); public async Task> GetEvidenceAsync(string evidenceId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetEvidenceAsync(evidenceId, cancellationToken); 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 Task> GetEvidenceFilesAsync(Pagination pagination, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetEvidenceFilesAsync(pagination, cancellationToken); 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 Task> GetEvidenceUrlAsync(string evidenceIdHash, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetEvidenceUrlAsync(evidenceIdHash, cancellationToken); var cacheKey = HashService.ToMd5Hash($"getevidenceurl-{evidenceIdHash}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetEvidenceUrlAsync(evidenceIdHash, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value, cancellationToken); return result.Value; } return Result.Ok(cached); })); public async Task> GetIndicatorAsync(string indicatorId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetIndicatorAsync(indicatorId, cancellationToken); 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 Task> GetIndicatorsAsync(Pagination pagination, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetIndicatorsAsync(pagination, cancellationToken); 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 Task> GetMilestoneEvidencesAsync(string milestoneIdHash, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetMilestoneEvidencesAsync(milestoneIdHash, cancellationToken); 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 Task> GetProjectEvidencesAsync(string projectIdHash, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetProjectEvidencesAsync(projectIdHash, cancellationToken); 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 Task RecordIndicatorActualAmountAsync(string indicatorIdHash, decimal amount, Guid userId, CancellationToken cancellationToken = default) => await service.RecordIndicatorActualAmountAsync(indicatorIdHash, amount, userId, cancellationToken); public async Task UpdateEvidenceAsync(UpdateEvidenceRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.UpdateEvidenceAsync(request, userId, cancellationToken); }