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.Communications; public sealed class CommunicationsCacheService(CommunicationsService service, IDistributedCache cache, IFeatureManager featureManager) : ServiceCacheBase, ICommunicationsService { public async Task CreateNotificationAsync(CreateNotificationRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.CreateNotificationAsync(request, userId, cancellationToken); public async Task> GetApplicantDataAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetApplicantDataAsync(applicantUserId, cancellationToken); var cacheKey = HashService.ToMd5Hash($"getapplicantdata-{applicantUserId}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetApplicantDataAsync(applicantUserId, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); } return Result.Ok(cached!.FromJson()); })); public async Task> GetApplicantInviteAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetApplicantInviteAsync(applicantUserId, cancellationToken); var cacheKey = HashService.ToMd5Hash($"getapplicantinvite-{applicantUserId}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetApplicantInviteAsync(applicantUserId, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); } return Result.Ok(cached!.FromJson()); })); public async Task> GetApplicantInvitesAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetApplicantInvitesAsync(applicantUserId, cancellationToken); var cacheKey = HashService.ToMd5Hash($"getapplicantinvites-{applicantUserId}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetApplicantInvitesAsync(applicantUserId, 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> GetInvitesAsync(Pagination pagination, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetInvitesAsync(pagination, cancellationToken); var cacheKey = HashService.ToMd5Hash($"getinvites-{pagination.Page}-{pagination.PageSize}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetInvitesAsync(pagination, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return Result.Ok(result.Value); } return Result.Ok(cached.FromJson()); })); public async Task> GetNotificationAsync(string notificationIdHash, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetNotificationAsync(notificationIdHash, cancellationToken); var cacheKey = HashService.ToMd5Hash($"getnotification-{notificationIdHash}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetNotificationAsync(notificationIdHash, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return Result.Ok(result.Value); } return Result.Ok(cached.FromJson()); })); public async Task> GetNotificationsAsync(string organisationIdHash, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) return await service.GetNotificationsAsync(organisationIdHash, cancellationToken); var cacheKey = HashService.ToMd5Hash($"getnotifications-{organisationIdHash}").Value; var cached = await cache.GetStringAsync(cacheKey, cancellationToken); if (string.IsNullOrWhiteSpace(cached)) { var result = await service.GetNotificationsAsync(organisationIdHash, cancellationToken); if (result.IsFailed) return result; await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); return Result.Ok(result.Value); } return Result.Ok(cached.FromJson()); })); public async Task> SendInviteAsync(InviteRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.SendInviteAsync(request, userId, cancellationToken); public async Task UpdateNotificationAsync(UpdateNotificationRequest request, CancellationToken cancellationToken = default) => await service.UpdateNotificationAsync(request, cancellationToken); }