Compare commits
3
Commits
f39eb9d8fe
...
24697776d0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24697776d0 | ||
|
|
4b806a3202 | ||
|
|
26df423180 |
@@ -153,5 +153,5 @@ public interface IProjectService
|
||||
Task<Result<SiteVisit[]>> GetSiteVisitsAsync(string projectIdHash, CancellationToken cancellationToken = default);
|
||||
|
||||
[Log]
|
||||
Task<Result<SiteVisit>> GetSiteVisitAsync(string SiteVisitIdHash, CancellationToken cancellationToken = default);
|
||||
Task<Result<SiteVisit>> GetSiteVisitAsync(string siteVisitIdHash, CancellationToken cancellationToken = default);
|
||||
}
|
||||
|
||||
@@ -215,26 +215,102 @@ public sealed class GovernanceCacheService(GovernanceService service, IDistribut
|
||||
return Result.Ok(cached.FromJson<Programme[]>());
|
||||
}));
|
||||
|
||||
public Task<Result<Tenant>> GetTenantAsync(string tenantIdHash, CancellationToken cancellationToken = default)
|
||||
public async Task<Result<Tenant>> GetTenantAsync(string tenantIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Tenant>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetTenantAsync(tenantIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"gettenant-{tenantIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetTenantAsync(tenantIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<TenantOrganisation>> GetTenantOrganisationAsync(string tenantOrganisationIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<Tenant>());
|
||||
}));
|
||||
|
||||
public async Task<Result<TenantOrganisation>> GetTenantOrganisationAsync(string tenantOrganisationIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<TenantOrganisation>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetTenantOrganisationAsync(tenantOrganisationIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"gettenantorganisation-{tenantOrganisationIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetTenantOrganisationAsync(tenantOrganisationIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<TenantOrganisation[]>> GetTenantOrganisationsAsync(CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<TenantOrganisation>());
|
||||
}));
|
||||
|
||||
public async Task<Result<TenantOrganisation[]>> GetTenantOrganisationsAsync(CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<TenantOrganisation[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetTenantOrganisationsAsync(cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"gettenantorganisations").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetTenantOrganisationsAsync(cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<Tenant[]>> GetTenantsAsync(CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<TenantOrganisation[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Tenant[]>> GetTenantsAsync(CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Tenant[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetTenantsAsync(cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"gettenants").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetTenantsAsync(cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
return Result.Ok(cached.FromJson<Tenant[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Organisation>> UpdateOrganisationAsync(UpdateOrganisationRequest request, CancellationToken cancellationToken = default) =>
|
||||
await service.UpdateOrganisationAsync(request, cancellationToken);
|
||||
|
||||
|
||||
@@ -56,13 +56,14 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var organisations = await context.Organisations.AsNoTracking()
|
||||
.OrderBy(o => o.Name)
|
||||
var organisations = await context.TenantOrganisations.AsNoTracking()
|
||||
.Include(i => i.Organisation)
|
||||
.OrderBy(o => o.Organisation!.Name)
|
||||
.Skip((pagination.Page - 1) * pagination.PageSize)
|
||||
.Take(pagination.PageSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(organisations.Select(o => o.Map()).ToArray());
|
||||
return Result.Ok(organisations.Select(o => o.Organisation!.Map()).ToArray());
|
||||
}));
|
||||
|
||||
public async Task<Result<Organisation>> GetOrganisationAsync(string organisationIdHash, CancellationToken cancellationToken = default) =>
|
||||
@@ -76,11 +77,12 @@ public sealed class GovernanceService(IDbContextFactory<ApplicationDbContext> co
|
||||
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var organisation = await context.Organisations.AsNoTracking()
|
||||
.FirstOrDefaultAsync(o => o.Id == decodeResult.Value, cancellationToken);
|
||||
var tenantOrganisation = await context.TenantOrganisations.AsNoTracking()
|
||||
.Include(i => i.OrganisationId)
|
||||
.FirstOrDefaultAsync(o => o.OrganisationId == decodeResult.Value, cancellationToken);
|
||||
|
||||
return Result.FailIf(organisation is null, NotFoundError.New)
|
||||
.ToResult(organisation!.Map());
|
||||
return Result.FailIf(tenantOrganisation is null, NotFoundError.New)
|
||||
.ToResult(tenantOrganisation!.Organisation!.Map());
|
||||
}));
|
||||
|
||||
public async Task<Result<Instrument[]>> GetInstrumentsAsync(string programmeIdHash, CancellationToken cancellationToken = default) =>
|
||||
|
||||
@@ -86,46 +86,198 @@ public sealed class ProjectCacheService(ProjectService service, IDistributedCach
|
||||
return Result.Ok(cached.FromJson<Domain.Models.Activity>());
|
||||
}));
|
||||
|
||||
public Task<Result<Beneficiary[]>> GetBeneficiariesAsync(string projectIdHash, CancellationToken cancellationToken = default)
|
||||
public async Task<Result<Beneficiary[]>> GetBeneficiariesAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Beneficiary[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetBeneficiariesAsync(projectIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getbeneficiaries-{projectIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetBeneficiariesAsync(projectIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<Beneficiary>> GetBeneficiaryAsync(string beneficiaryIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<Beneficiary[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Beneficiary>> GetBeneficiaryAsync(string beneficiaryIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Beneficiary>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetBeneficiaryAsync(beneficiaryIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getbeneficiary-{beneficiaryIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetBeneficiaryAsync(beneficiaryIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<ChangeRequest>> GetChangeRequestAsync(string changeRequestIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<Beneficiary>());
|
||||
}));
|
||||
|
||||
public async Task<Result<ChangeRequest>> GetChangeRequestAsync(string changeRequestIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<ChangeRequest>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetChangeRequestAsync(changeRequestIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getchangerequest-{changeRequestIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetChangeRequestAsync(changeRequestIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<ChangeRequest[]>> GetChangeRequestsAsync(string projectIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<ChangeRequest>());
|
||||
}));
|
||||
|
||||
public async Task<Result<ChangeRequest[]>> GetChangeRequestsAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<ChangeRequest[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetChangeRequestsAsync(projectIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getchangerequests-{projectIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetChangeRequestsAsync(projectIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<ComplianceItem>> GetComplianceItemAsync(string complianceItemIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<ChangeRequest[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result<ComplianceItem>> GetComplianceItemAsync(string complianceItemIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<ComplianceItem>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetComplianceItemAsync(complianceItemIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getcomplianceitem-{complianceItemIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetComplianceItemAsync(complianceItemIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<ComplianceItem[]>> GetComplianceItemsAsync(string projectIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<ComplianceItem>());
|
||||
}));
|
||||
|
||||
public async Task<Result<ComplianceItem[]>> GetComplianceItemsAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<ComplianceItem[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetComplianceItemsAsync(projectIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getcomplianceitems-{projectIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetComplianceItemsAsync(projectIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<Issue>> GetIssueAsync(string issueIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<ComplianceItem[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Issue>> GetIssueAsync(string issueIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Issue>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetIssueAsync(issueIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getissue-{issueIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetIssueAsync(issueIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<Issue[]>> GetIssuesAsync(string projectIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<Issue>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Issue[]>> GetIssuesAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Issue[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetIssuesAsync(projectIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getissues-{projectIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetIssuesAsync(projectIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
return Result.Ok(cached.FromJson<Issue[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Milestone>> GetMilestoneAsync(string milestoneIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Milestone>>>)(async () =>
|
||||
{
|
||||
@@ -174,16 +326,54 @@ public sealed class ProjectCacheService(ProjectService service, IDistributedCach
|
||||
return Result.Ok(cached.FromJson<Milestone[]>());
|
||||
}));
|
||||
|
||||
public Task<Result<Outcome>> GetOutcomeAsync(string outcomeIdHash, CancellationToken cancellationToken = default)
|
||||
public async Task<Result<Outcome>> GetOutcomeAsync(string outcomeIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Outcome>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetOutcomeAsync(outcomeIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getoutcome-{outcomeIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetOutcomeAsync(outcomeIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<Outcome[]>> GetOutcomesAsync(string beneficiaryIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<Outcome>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Outcome[]>> GetOutcomesAsync(string beneficiaryIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Outcome[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetOutcomesAsync(beneficiaryIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getoutcomes-{beneficiaryIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetOutcomesAsync(beneficiaryIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
return Result.Ok(cached.FromJson<Outcome[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result<Programme>> GetProgrammeAsync(string programmeIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<Programme>>>)(async () =>
|
||||
{
|
||||
@@ -376,16 +566,54 @@ public sealed class ProjectCacheService(ProjectService service, IDistributedCach
|
||||
return Result.Ok(cached.FromJson<Project[]>());
|
||||
}));
|
||||
|
||||
public Task<Result<SiteVisit>> GetSiteVisitAsync(string SiteVisitIdHash, CancellationToken cancellationToken = default)
|
||||
public async Task<Result<SiteVisit>> GetSiteVisitAsync(string siteVisitIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<SiteVisit>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetSiteVisitAsync(siteVisitIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getsitevisit-{siteVisitIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetSiteVisitAsync(siteVisitIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public Task<Result<SiteVisit[]>> GetSiteVisitsAsync(string projectIdHash, CancellationToken cancellationToken = default)
|
||||
return Result.Ok(cached.FromJson<SiteVisit>());
|
||||
}));
|
||||
|
||||
public async Task<Result<SiteVisit[]>> GetSiteVisitsAsync(string projectIdHash, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result<SiteVisit[]>>>)(async () =>
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!await featureManager.IsEnabledAsync(ServiceCachingFeature))
|
||||
return await service.GetSiteVisitsAsync(projectIdHash, cancellationToken);
|
||||
|
||||
var cacheKey = HashService.ToMd5Hash($"getsitevisits-{projectIdHash}").Value;
|
||||
|
||||
var cached = await cache.GetStringAsync(cacheKey, cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(cached))
|
||||
{
|
||||
var result = await service.GetSiteVisitsAsync(projectIdHash, cancellationToken);
|
||||
|
||||
if (result.IsFailed) return result;
|
||||
|
||||
await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken);
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
return Result.Ok(cached.FromJson<SiteVisit[]>());
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateBeneficiaryItemAsync(UpdateBeneficiaryRequest request, Guid userId, CancellationToken cancellationToken = default) =>
|
||||
await service.UpdateBeneficiaryItemAsync(request, userId, cancellationToken);
|
||||
|
||||
|
||||
@@ -498,7 +498,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<Result<SiteVisit>> GetSiteVisitAsync(string SiteVisitIdHash, CancellationToken cancellationToken = default)
|
||||
public Task<Result<SiteVisit>> GetSiteVisitAsync(string siteVisitIdHash, CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ public sealed class IdentityService(IDbContextFactory<ApplicationDbContext> cont
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
// TODO: Ensure TenantUser status is checked
|
||||
var userExistsAndActive = await context.Users
|
||||
.AnyAsync(u => u.Id == userId && u.Status == ActivityStatus.Active, cancellationToken);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
@@ -7,16 +8,19 @@ using PostFundManagement.Infrastructure.Database;
|
||||
|
||||
namespace PostFundManagement.Application.Services.Users;
|
||||
|
||||
public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextFactory) : IUserService
|
||||
public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextFactory, ITenantContextService tenantContext) : IUserService
|
||||
{
|
||||
public async Task<Result> SyncUserAsync(Guid userId, string email, CancellationToken cancellationToken = default) =>
|
||||
await Result.Try((Func<Task<Result>>)(async () =>
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var user = await context.Users.FirstOrDefaultAsync(u => u.Id == userId, cancellationToken);
|
||||
var tenantUser = await context.TenantUsers
|
||||
.Include(i => i.User)
|
||||
.FirstOrDefaultAsync(u => u.UserId == userId, cancellationToken);
|
||||
|
||||
if (user is null)
|
||||
if (tenantUser is null)
|
||||
{
|
||||
context.Users.Add(new Domain.Entities.User
|
||||
{
|
||||
Id = userId,
|
||||
@@ -24,12 +28,22 @@ public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextF
|
||||
Status = ActivityStatus.Active,
|
||||
LastLoginAt = DateTime.UtcNow
|
||||
});
|
||||
|
||||
context.TenantUsers.Add(new Domain.Entities.TenantUser
|
||||
{
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
CreatedBy = userId,
|
||||
Status = ActivityStatus.Active,
|
||||
TenantId = tenantContext.TenantId,
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
user!.Email = email;
|
||||
user.LastLoginAt = DateTime.UtcNow;
|
||||
tenantUser.User!.Email = email;
|
||||
tenantUser.User.LastLoginAt = DateTime.UtcNow;
|
||||
|
||||
context.Users.Update(user);
|
||||
context.Users.Update(tenantUser.User);
|
||||
}
|
||||
|
||||
return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.New);
|
||||
@@ -40,19 +54,19 @@ public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextF
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var query = context.Users.AsNoTracking();
|
||||
var query = context.TenantUsers.Include(i => i.User).AsNoTracking();
|
||||
|
||||
if (request.Status.HasValue)
|
||||
query = query.Where(u => u.Status == request.Status.Value);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.Email))
|
||||
query = query.Where(u => u.Email != null && u.Email.Contains(request.Email));
|
||||
query = query.Where(u => u.User!.Email != null && u.User!.Email.Contains(request.Email));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(request.SortBy))
|
||||
query = request.SortBy.ToLowerInvariant() switch
|
||||
{
|
||||
"email" => request.SortDescending ? query.OrderByDescending(u => u.Email) : query.OrderBy(u => u.Email),
|
||||
"lastloginat" => request.SortDescending ? query.OrderByDescending(u => u.LastLoginAt) : query.OrderBy(u => u.LastLoginAt),
|
||||
"email" => request.SortDescending ? query.OrderByDescending(u => u.User!.Email) : query.OrderBy(u => u.User!.Email),
|
||||
"lastloginat" => request.SortDescending ? query.OrderByDescending(u => u.User!.LastLoginAt) : query.OrderBy(u => u.User!.LastLoginAt),
|
||||
"status" => request.SortDescending ? query.OrderByDescending(u => u.Status) : query.OrderBy(u => u.Status),
|
||||
_ => request.SortDescending ? query.OrderByDescending(u => u.Id) : query.OrderBy(u => u.Id)
|
||||
};
|
||||
@@ -62,7 +76,7 @@ public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextF
|
||||
var users = await query.Skip((pagination.Page - 1) * pagination.PageSize)
|
||||
.Take(pagination.PageSize).ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(users.Select(u => u.Map()).ToArray());
|
||||
return Result.Ok(users.Select(u => u.User!.Map()).ToArray());
|
||||
}));
|
||||
|
||||
public async Task<Result> UpdateUserStatusAsync(Guid userId, ActivityStatus status, CancellationToken cancellationToken = default) =>
|
||||
@@ -70,8 +84,13 @@ public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextF
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var changedTotal = await context.Users
|
||||
.Where(f => f.Id == userId)
|
||||
var changedTotal = await context.TenantUsers
|
||||
.Include(i => i.User)
|
||||
.Where(f => f.UserId == userId)
|
||||
.ExecuteUpdateAsync(f => f
|
||||
.SetProperty(u => u.Status, status), cancellationToken);
|
||||
|
||||
changedTotal += await context.Users.Where(f => f.Id == userId)
|
||||
.ExecuteUpdateAsync(f => f.SetProperty(u => u.Status, status), cancellationToken);
|
||||
|
||||
return Result.OkIf(changedTotal > 0, UpdateError.New);
|
||||
@@ -82,10 +101,11 @@ public sealed class UserService(IDbContextFactory<ApplicationDbContext> contextF
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var user = await context.Users.AsNoTracking()
|
||||
.FirstOrDefaultAsync(f => f.Id == userId, cancellationToken);
|
||||
var tenantUser = await context.TenantUsers.AsNoTracking()
|
||||
.Include(i => i.User)
|
||||
.FirstOrDefaultAsync(f => f.UserId == userId, cancellationToken);
|
||||
|
||||
return Result.FailIf(user == null, NotFoundError.New)
|
||||
.ToResult(user?.Map()!);
|
||||
return Result.FailIf(tenantUser == null, NotFoundError.New)
|
||||
.ToResult(tenantUser!.User?.Map()!);
|
||||
}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user