Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit 784b6f3

Browse files
authored
feat: DTOSS-9179 - Transform function completion, and test/logging refactoring (#23)
1 parent 5c3545b commit 784b6f3

29 files changed

+934
-513
lines changed

src/ServiceLayer.Common/Data/Migrations/20250527094020_ValidationErrors.Designer.cs

Lines changed: 225 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Microsoft.EntityFrameworkCore.Migrations;
2+
3+
#nullable disable
4+
5+
namespace ServiceLayer.Mesh.Migrations
6+
{
7+
/// <inheritdoc />
8+
public partial class ValidationErrors : Migration
9+
{
10+
/// <inheritdoc />
11+
protected override void Up(MigrationBuilder migrationBuilder)
12+
{
13+
migrationBuilder.AddColumn<string>(
14+
name: "ValidationErrors",
15+
table: "MeshFiles",
16+
type: "nvarchar(max)",
17+
nullable: true);
18+
}
19+
20+
/// <inheritdoc />
21+
protected override void Down(MigrationBuilder migrationBuilder)
22+
{
23+
migrationBuilder.DropColumn(
24+
name: "ValidationErrors",
25+
table: "MeshFiles");
26+
}
27+
}
28+
}

src/ServiceLayer.Common/Data/Migrations/ServiceLayerDbContextModelSnapshot.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ protected override void BuildModel(ModelBuilder modelBuilder)
5353
.HasMaxLength(20)
5454
.HasColumnType("nvarchar(20)");
5555

56+
b.Property<string>("ValidationErrors")
57+
.HasColumnType("nvarchar(max)");
58+
5659
b.HasKey("FileId");
5760

5861
b.ToTable("MeshFiles");

src/ServiceLayer.Common/Data/Models/MeshFile.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ public class MeshFile
1616
public string? BlobPath { get; set; }
1717
public DateTime FirstSeenUtc { get; set; }
1818
public DateTime LastUpdatedUtc { get; set; }
19+
// ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength
20+
public string? ValidationErrors { get; set; }
1921
}

src/ServiceLayer.Mesh/Configuration/AppConfiguration.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ namespace ServiceLayer.Mesh.Configuration;
44

55
public class AppConfiguration :
66
IFileDiscoveryFunctionConfiguration,
7-
IFileExtractFunctionConfiguration,
87
IFileExtractQueueClientConfiguration,
98
IFileTransformQueueClientConfiguration,
109
IFileTransformFunctionConfiguration,

src/ServiceLayer.Mesh/Configuration/IFileExtractFunctionConfiguration.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using NHS.MESH.Client.Models;
2+
3+
namespace ServiceLayer.Mesh.Extensions;
4+
5+
public static class ApiErrorResponseExtensions
6+
{
7+
public static string ToFormattedString(this APIErrorResponse? error)
8+
{
9+
return error == null ? "Unknown error" : $"ErrorEvent: {error.ErrorEvent ?? "N/A"}, ErrorCode: {error.ErrorCode ?? "N/A"}, ErrorDescription: {error.ErrorDescription}";
10+
}
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using ServiceLayer.Data.Models;
2+
3+
namespace ServiceLayer.Mesh;
4+
5+
public abstract class FileTransformerBase : IFileTransformer
6+
{
7+
protected abstract MeshFileType HandlesFileType { get; }
8+
public virtual bool CanHandle(MeshFileType fileType) => fileType == HandlesFileType;
9+
public abstract Task<IList<ValidationError>> TransformFileAsync(Stream stream, MeshFile metaData);
10+
}

src/ServiceLayer.Mesh/FileTypes/NbssAppointmentEvents/FileTransformer.cs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,23 @@
33

44
namespace ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents;
55

6-
// TODO - NBSS appointment file specific implementation of IFileTransformer. To orchestrate parsing, validation and staging of data (delegated to separate classes)
7-
public class FileTransformer : IFileTransformer
6+
public class FileTransformer(
7+
IFileParser fileParser,
8+
IValidationRunner validationRunner,
9+
IStagingPersister stagingPersister)
10+
: FileTransformerBase
811
{
9-
private readonly IFileParser _fileParser;
10-
private readonly IValidationRunner _validationRunner;
11-
private readonly IStagingPersister _stagingPersister;
12+
protected override MeshFileType HandlesFileType => MeshFileType.NbssAppointmentEvents;
1213

13-
public FileTransformer(IFileParser fileParser, IValidationRunner validationRunner, IStagingPersister stagingPersister)
14-
{
15-
_fileParser = fileParser;
16-
_validationRunner = validationRunner;
17-
_stagingPersister = stagingPersister;
18-
}
19-
20-
public MeshFileType HandlesFileType => MeshFileType.NbssAppointmentEvents;
21-
22-
public async Task<IList<ValidationError>> TransformFileAsync(Stream stream, MeshFile metaData)
14+
public override async Task<IList<ValidationError>> TransformFileAsync(Stream stream, MeshFile metaData)
2315
{
2416
// TODO - wrap this parsing in a try-catch and return a List<ValidationError> in case of any unforeseen parsing issues (file is totally unlike anything we expect)
25-
var parsed = _fileParser.Parse(stream);
17+
var parsed = fileParser.Parse(stream);
2618

27-
var validationErrors = _validationRunner.Validate(parsed);
19+
var validationErrors = validationRunner.Validate(parsed);
2820
if (!validationErrors.Any())
2921
{
30-
await _stagingPersister.WriteStagedData(parsed, metaData);
22+
await stagingPersister.WriteStagedData(parsed, metaData);
3123
}
3224

3325
return validationErrors;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents.Validation;
3+
4+
namespace ServiceLayer.Mesh.FileTypes.NbssAppointmentEvents;
5+
6+
public static class ServiceCollectionExtensions
7+
{
8+
public static IServiceCollection ConfigureNbssAppointmentEvents(this IServiceCollection services)
9+
{
10+
services.AddTransient<IFileTransformer, FileTransformer>();
11+
services.AddTransient<IFileParser, FileParser>();
12+
services.AddTransient<IStagingPersister, StagingPersister>();
13+
services.AddSingleton<IValidationRunner, ValidationRunner>();
14+
services.RegisterValidators();
15+
16+
return services;
17+
}
18+
19+
private static IServiceCollection RegisterValidators(this IServiceCollection services)
20+
{
21+
foreach (var recordValidator in ValidatorRegistry.GetAllRecordValidators())
22+
{
23+
services.AddSingleton<IRecordValidator>(_ => recordValidator);
24+
}
25+
26+
foreach (var fileValidator in ValidatorRegistry.GetAllFileValidators())
27+
{
28+
services.AddSingleton<IFileValidator>(_ => fileValidator);
29+
}
30+
31+
return services;
32+
}
33+
}

0 commit comments

Comments
 (0)