Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion SAPPub.Core/Entities/Establishment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ public class Establishment

public string UrbanRuralId { get; set; } = string.Empty;
public string UrbanRuralName { get; set; } = string.Empty;

public string Website { get; set; } = string.Empty;

public string Easting { get; set; } = string.Empty;
Expand Down
47 changes: 47 additions & 0 deletions SAPPub.Core/Entities/EstablishmentMinimum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using SAPPub.Core.Attributes;
using SAPPub.Core.Enums;
using SAPPub.Core.ServiceModels;
using System.Diagnostics.CodeAnalysis;
using System.Net.WebSockets;
using System.Runtime.Serialization;

namespace SAPPub.Core.Entities;

[ExcludeFromCodeCoverage]
public class EstablishmentMinimum
{
public string URN { get; set; } = string.Empty;

public string EstablishmentName { get; set; } = string.Empty;

public string LAId { get; set; } = string.Empty;

public string LAName { get; set; } = string.Empty;

[DbColumnName("ISKS2")]
public bool IsKS2 { get; set; }

[DbColumnName("ISKS4")]
public bool IsKS4 { get; set; }

[DbColumnName("ISKS5")]
public bool IsKS5 { get; set; }

public string Website { get; set; } = string.Empty;


public static EstablishmentMinimumServiceModel MapToServiceModel(Establishment e)
{
return new()
{
URN = e.URN,
EstablishmentName = e.EstablishmentName,
LAId = e.LAId,
LAName = e.LAName,
IsKS2 = e.IsKS2,
IsKS4 = e.IsKS4,
IsKS5 = e.IsKS5,
Website = e.Website,
};
}
}
2 changes: 2 additions & 0 deletions SAPPub.Core/Interfaces/Services/IEstablishmentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ public interface IEstablishmentService
Task<EstablishmentServiceModel> GetEstablishmentAsync(string urn, CancellationToken ct = default);
Task<IEnumerable<EstablishmentServiceModel>> GetEstablishmentsAsync(IEnumerable<string> urns, CancellationToken ct = default);

Task<EstablishmentMinimumServiceModel> GetEstablishmentMinimumAsync(string urn, CancellationToken ct = default);

}
28 changes: 28 additions & 0 deletions SAPPub.Core/ServiceModels/EstablishmentMinimumServiceModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using SAPPub.Core.Entities.Destinations;
using SAPPub.Core.Entities.KS4.Absence;
using SAPPub.Core.Entities.KS4.Performance;
using SAPPub.Core.Enums;
using SAPPub.Core.Helpers;

namespace SAPPub.Core.ServiceModels;

public class EstablishmentMinimumServiceModel
{
public string URN { get; set; } = string.Empty;

public string EstablishmentName { get; set; } = string.Empty;

public string EstablishmentNameClean => TextHelpers.CleanForUrl(EstablishmentName);

public string LAId { get; set; } = string.Empty;

public string LAName { get; set; } = string.Empty;

public bool IsKS2 { get; set; }

public bool IsKS4 { get; set; }

public bool IsKS5 { get; set; }

public string Website { get; set; } = string.Empty;
}
4 changes: 2 additions & 2 deletions SAPPub.Core/Services/DestinationsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class DestinationsService(
{
public async Task<KS4DestinationsDetails> GetKS4DestinationsDetailsAsync(string urn, CancellationToken ct = default)
{
var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var laCode = establishment?.LAId ?? string.Empty;

if (string.IsNullOrWhiteSpace(establishment?.URN))
Expand Down Expand Up @@ -109,7 +109,7 @@ public async Task<KS5DestinationsDetails> GetKS5DestinationsDetailsAsync(string
{
ct.ThrowIfCancellationRequested();

var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var laCode = establishment.LAId ?? string.Empty;

if (string.IsNullOrWhiteSpace(establishment.URN))
Expand Down
27 changes: 25 additions & 2 deletions SAPPub.Core/Services/EstablishmentService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using SAPPub.Core.Entities;
using Microsoft.Extensions.Caching.Memory;
using SAPPub.Core.Entities;
using SAPPub.Core.Exceptions;
using SAPPub.Core.Interfaces.Repositories;
using SAPPub.Core.Interfaces.Services;
Expand All @@ -7,9 +8,12 @@
namespace SAPPub.Core.Services;

public sealed class EstablishmentService(
IEstablishmentRepository establishmentRepository) : IEstablishmentService
IEstablishmentRepository establishmentRepository,
IMemoryCache memoryCache
) : IEstablishmentService
{
private readonly IEstablishmentRepository _establishmentRepository = establishmentRepository ?? throw new ArgumentNullException(nameof(establishmentRepository));
private readonly IMemoryCache _memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(establishmentRepository));

public async Task<IEnumerable<EstablishmentServiceModel>> GetEstablishmentsAsync(int page, int take, CancellationToken ct = default)
{
Expand All @@ -36,4 +40,23 @@ public async Task<IEnumerable<EstablishmentServiceModel>> GetEstablishmentsAsync

return establishments.Select(e => Establishment.MapToServiceModel(e));
}

public async Task<EstablishmentMinimumServiceModel> GetEstablishmentMinimumAsync(string urn, CancellationToken ct = default)
{
if (_memoryCache.TryGetValue(urn, out EstablishmentMinimumServiceModel? cacheValue) && cacheValue != null)
{
return cacheValue;
}

var establishment = await _establishmentRepository.GetEstablishmentAsync(urn, ct)
?? throw new NotFoundException($"Establishment not found with URN: {urn}");

var cacheEntryOptions = new MemoryCacheEntryOptions();

var establishmentModel = EstablishmentMinimum.MapToServiceModel(establishment);

_memoryCache.Set(urn, establishmentModel, cacheEntryOptions);

return establishmentModel;
}
}
2 changes: 1 addition & 1 deletion SAPPub.Core/Services/KS4/Attendance/AttendanceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task<AttendanceModel> GetAttendenceDetailsAsync(
string urn,
CancellationToken ct = default)
{
var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);

if (string.IsNullOrWhiteSpace(establishment.URN))
return new AttendanceModel { Urn = urn, IsKS2 = false, IsKS4 = false, IsKS5 = false };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public async Task<AttainmentAndProgressModel> GetAttainmentAndProgressAsync(
CancellationToken ct = default)
{
// Need establishment first to get LAId/LAName (and to check if URN is valid)
var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);

if (string.IsNullOrWhiteSpace(establishment.URN))
return new AttainmentAndProgressModel { Urn = urn, IsKS2 = false, IsKS4 = false, IsKS5 = false };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public async Task<EnglishAndMathsResultsModel> GetEnglishAndMathsResultsAsync(
CancellationToken ct = default)
{
// Need establishment first to get LAId/LAName (and to check if URN is valid)
var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);

if (string.IsNullOrWhiteSpace(establishment.URN))
return CreateEmpty(urn);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task<EnglishMathsQualificationModel> GetEnglishAndMathsQualificatio
{
ct.ThrowIfCancellationRequested();

var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);

var establishmentPerformanceTask = ks5PerformanceRepository.GetEstablishmentPerformanceAsync(urn, ct);
var englandPerformanceTask = ks5PerformanceRepository.GetEnglandPerformanceAsync(ct);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task<KS2AdditionalMeasuresModel> GetAdditionalMeasures(string urn,
ArgumentException.ThrowIfNullOrWhiteSpace(urn);
ct.ThrowIfCancellationRequested();

var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var establishmentPerformanceTask = ks2PerformanceRepository.GetEstablishmentPerformanceAsync(urn, ct);
var localAuthorityPerformanceTask = ks2PerformanceRepository.GetLaPerformanceAsync(establishment.LAId, ct);
var englandPerformanceTask = ks2PerformanceRepository.GetEnglandPerformanceAsync(ct);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public async Task<KS2MeetingOrExceedingStandardsModel> GetMeetingOrExceedingStan
ArgumentException.ThrowIfNullOrWhiteSpace(urn);
ct.ThrowIfCancellationRequested();

var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var establishmentPerformanceTask = ks2PerformanceRepository.GetEstablishmentPerformanceAsync(urn, ct);
var localAuthorityPerformanceTask = ks2PerformanceRepository.GetLaPerformanceAsync(establishment.LAId, ct);
var englandPerformanceTask = ks2PerformanceRepository.GetEnglandPerformanceAsync(ct);
Expand Down
2 changes: 1 addition & 1 deletion SAPPub.Core/Services/Performance/KS2ScaledScoresService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public async Task<KS2ScaledScoreModel> GetScaledScoreModel(string urn, Cancellat
ArgumentException.ThrowIfNullOrWhiteSpace(urn);
ct.ThrowIfCancellationRequested();

var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var establishmentPerformanceTask = ks2PerformanceRepository.GetEstablishmentPerformanceAsync(urn, ct);
var localAuthorityPerformanceTask = ks2PerformanceRepository.GetLaPerformanceAsync(establishment.LAId, ct);
var englandPerformanceTask = ks2PerformanceRepository.GetEnglandPerformanceAsync(ct);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public async Task<Level3QualificationModel> GetLevel3QualificationDetailsAsync(
Level3 level3Qualification,
CancellationToken ct = default)
{
var establishment = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishment = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var establishmentPerformanceTask = ks5PerformanceRepository.GetEstablishmentPerformanceAsync(urn, ct);
var englandPerformanceTask = ks5PerformanceRepository.GetEnglandPerformanceAsync(ct);
var laPerformanceTask = ks5PerformanceRepository.GetLaPerformanceAsync(establishment.LAId, ct);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Dapper;
using Microsoft.FeatureManagement;
using Npgsql;
using SAPPub.Core.Entities;
using SAPPub.Core.Helpers;
Expand All @@ -7,6 +8,8 @@
using SAPPub.Core.Interfaces.Services.Search;
using SAPPub.Core.ServiceModels.Search.InputModels;
using SAPPub.Core.Specifications;
using StackExchange.Profiling;
using StackExchange.Profiling.Data;

namespace SAPPub.Infrastructure.Repositories
{
Expand Down Expand Up @@ -106,6 +109,7 @@ internal static SearchSqlParts BuildSearchSqlParts(SearchQuery query, int maxRes

public async Task<(IEnumerable<Establishment> Results, int TotalCount)> SearchAsync(SearchQuery query, int maxResults = 10, CancellationToken ct = default)
{

var visibilitySpec = await _searchVisibilityPolicy.GetVisibilitySpecificationAsync(ct);
var parts = BuildSearchSqlParts(query, maxResults, visibilitySpec);

Expand All @@ -121,7 +125,8 @@ SELECT COUNT(*)
FROM v_establishment
{parts.WhereClause};";

await using var conn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
await using var npgsqlConn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
using var conn = new ProfiledDbConnection(npgsqlConn, MiniProfiler.Current);
var results = await conn.QueryAsync<Establishment>(sql, parts.Parameters);
var totalCount = await conn.ExecuteScalarAsync<int>(countSql, parts.Parameters);

Expand Down
15 changes: 11 additions & 4 deletions SAPPub.Infrastructure/Repositories/Generic/DapperRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
using SAPPub.Core.Interfaces.Repositories.Generic;
using SAPPub.Infrastructure.Mapping.ValueCodes;
using SAPPub.Infrastructure.Repositories.Helpers;
using StackExchange.Profiling;
using StackExchange.Profiling.Data;

namespace SAPPub.Infrastructure.Repositories.Generic
{
Expand Down Expand Up @@ -46,7 +48,9 @@ public async Task<IEnumerable<T>> ReadPageAsync(int page, int take, Cancellation
if (string.IsNullOrWhiteSpace(sql))
throw new NotSupportedException($"No ReadMultiple query for {typeof(T).Name}");

await using var conn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);

await using var npgsqlConn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
using var conn = new ProfiledDbConnection(npgsqlConn, MiniProfiler.Current);

var cmd = new DapperCommandBuilder()
.WithCommandText(sql)
Expand All @@ -68,7 +72,8 @@ public async Task<IEnumerable<T>> ReadAllAsync(CancellationToken ct = default)
if (string.IsNullOrWhiteSpace(sql))
throw new NotSupportedException($"No ReadMultiple query for {typeof(T).Name}");

await using var conn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
await using var npgsqlConn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
using var conn = new ProfiledDbConnection(npgsqlConn, MiniProfiler.Current);

var cmd = new DapperCommandBuilder()
.WithCommandText(sql)
Expand Down Expand Up @@ -104,7 +109,8 @@ public async Task<IEnumerable<T>> ReadAllAsync(CancellationToken ct = default)
if (string.IsNullOrWhiteSpace(sql))
throw new NotSupportedException($"No ReadSingle query for {typeof(T).Name}");

await using var conn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
await using var npgsqlConn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
using var conn = new ProfiledDbConnection(npgsqlConn, MiniProfiler.Current);

var cmd = new DapperCommandBuilder()
.WithCommandText(sql)
Expand Down Expand Up @@ -211,7 +217,8 @@ public async Task<IEnumerable<T>> ReadManyAsync(object? parameters, Cancellation
if (string.IsNullOrWhiteSpace(sql))
throw new NotSupportedException($"No ReadMany query for {typeof(T).Name}");

await using var conn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
await using var npgsqlConn = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
using var conn = new ProfiledDbConnection(npgsqlConn, MiniProfiler.Current);

var cmd = new DapperCommandBuilder()
.WithCommandText(sql)
Expand Down
1 change: 1 addition & 0 deletions SAPPub.Infrastructure/SAPPub.Infrastructure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.2" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="MiniProfiler.Shared" Version="4.5.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Npgsql" Version="10.0.1" />
<PackageReference Include="Spatial4n" Version="0.4.1.1" />
Expand Down
10 changes: 5 additions & 5 deletions SAPPub.Web/Areas/Profiles/Controllers/CurriculumController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ namespace SAPPub.Web.Areas.Profiles.Controllers;
public class CurriculumController(ILogger<CurriculumController> logger, IFeatureManager featureManager) : Controller
{
[Route("school/{urn}/{schoolName}/curriculum", Name = RouteConstants.CurriculumRoot)]
public async Task<IActionResult> Index([FromServices] IAboutSchoolService aboutSchoolService,
public async Task<IActionResult> Index([FromServices] IEstablishmentService establishmentService,
string urn, string schoolName,
CancellationToken ct)
{
var schoolDetails = await aboutSchoolService.GetAboutSchoolDetailsAsync(urn, ct);
var schoolDetails = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);

if (string.IsNullOrWhiteSpace(schoolDetails.Urn))
if (string.IsNullOrWhiteSpace(schoolDetails.URN))
{
logger.LogWarning("No establishment details found for URN: {URN}", urn);
return View("Error");
Expand All @@ -43,7 +43,7 @@ public async Task<IActionResult> KS2(
[FromServices] IEstablishmentService establishmentService,
string urn, string schoolName, CancellationToken ct)
{
var establishmentDetails = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishmentDetails = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var model = ViewModels.KS2.CurriculumAndExtraCurricularActivitiesViewModel.Map(establishmentDetails);
return View(model);
}
Expand All @@ -54,7 +54,7 @@ public async Task<IActionResult> KS4(
[FromServices] IEstablishmentService establishmentService,
string urn, string schoolName, CancellationToken ct)
{
var establishmentDetails = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishmentDetails = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var model = ViewModels.KS4.CurriculumAndExtraCurricularActivitiesViewModel.Map(establishmentDetails);
return View(model);
}
Expand Down
2 changes: 1 addition & 1 deletion SAPPub.Web/Areas/Profiles/Controllers/KS2Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace SAPPub.Web.Areas.Profiles.Controllers;
[ServiceFilter(typeof(PrimaryQueryValidationFilter))]
public class KS2Controller(IOptions<UrlLinksOptions> urlLinksOptions) : Controller, IEstablishment
{
public EstablishmentServiceModel Establishment { get; set; } = null!; // set by the PrimaryQueryValidationFilter
public EstablishmentMinimumServiceModel Establishment { get; set; } = null!; // set by the PrimaryQueryValidationFilter

[HttpGet]
[Route("school/{urn}/{schoolName}/primary-performance/pupil-progress", Name = RouteConstants.PrimaryAcademicPerformancePupilProgress)]
Expand Down
4 changes: 2 additions & 2 deletions SAPPub.Web/Areas/Profiles/Controllers/KS4Controller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public async Task<IActionResult> AcademicPerformanceSubjectsEntered(
string schoolName,
CancellationToken ct)
{
var establishmentDetails = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishmentDetails = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);

if (string.IsNullOrWhiteSpace(establishmentDetails?.URN))
{
Expand All @@ -114,7 +114,7 @@ public async Task<IActionResult> AcademicPerformanceAdditionalMeasures(
[FromServices] IAdditionalMeasuresService additionalMeasuresService,
string urn, string schoolName, CancellationToken ct)
{
var establishmentDetails = await establishmentService.GetEstablishmentAsync(urn, ct);
var establishmentDetails = await establishmentService.GetEstablishmentMinimumAsync(urn, ct);
var additionalMeasures = await additionalMeasuresService.GetAsync(urn, establishmentDetails.LAId, ct);

var model = AcademicPerformanceAdditionalMeasuresViewModel.MapToMeasuresInTableFormat(additionalMeasures, establishmentDetails);
Expand Down
Loading
Loading