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
4 changes: 4 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
echo "checked-out-sha=${CHECKED_OUT_SHA}" >> $GITHUB_OUTPUT
echo "image-name=${{ env.IMAGE_NAME }}" >> $GITHUB_OUTPUT


build-import-deploy:
name: Deploy to ${{ needs.set-env.outputs.environment }}
runs-on: ubuntu-24.04
Expand All @@ -54,6 +55,9 @@ jobs:
id-token: write

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Build
uses: DFE-Digital/deploy-azure-container-apps-action/.github/actions/build@v5.2.1
with:
Expand Down
28 changes: 23 additions & 5 deletions DfE.ExternalApplications.Web.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,36 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35122.118
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DfE.ExternalApplications.Web", "src\DfE.ExternalApplications.Web.csproj", "{122FBAC3-C50C-4BEB-A838-AAC742F3C8BD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DfE.ExternalApplications.Web", "src\DfE.ExternalApplications.Web\DfE.ExternalApplications.Web.csproj", "{CA38CBED-6681-4A44-BEC8-832D5171D59F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DfE.ExternalApplications.Domain", "src\DfE.ExternalApplications.Domain\DfE.ExternalApplications.Domain.csproj", "{F8DC3D4E-5AB5-4D9B-927D-63F0F8B2CFE7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DfE.ExternalApplications.Application", "src\DfE.ExternalApplications.Application\DfE.ExternalApplications.Application.csproj", "{1DC38736-EF38-446D-B24E-E498E496F501}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DfE.ExternalApplications.Infrastructure", "src\DfE.ExternalApplications.Infrastructure\DfE.ExternalApplications.Infrastructure.csproj", "{72352B4A-6C2E-4800-B7E1-0B5E3111FE93}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{122FBAC3-C50C-4BEB-A838-AAC742F3C8BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{122FBAC3-C50C-4BEB-A838-AAC742F3C8BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{122FBAC3-C50C-4BEB-A838-AAC742F3C8BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{122FBAC3-C50C-4BEB-A838-AAC742F3C8BD}.Release|Any CPU.Build.0 = Release|Any CPU
{CA38CBED-6681-4A44-BEC8-832D5171D59F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CA38CBED-6681-4A44-BEC8-832D5171D59F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA38CBED-6681-4A44-BEC8-832D5171D59F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA38CBED-6681-4A44-BEC8-832D5171D59F}.Release|Any CPU.Build.0 = Release|Any CPU
{F8DC3D4E-5AB5-4D9B-927D-63F0F8B2CFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F8DC3D4E-5AB5-4D9B-927D-63F0F8B2CFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F8DC3D4E-5AB5-4D9B-927D-63F0F8B2CFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F8DC3D4E-5AB5-4D9B-927D-63F0F8B2CFE7}.Release|Any CPU.Build.0 = Release|Any CPU
{1DC38736-EF38-446D-B24E-E498E496F501}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1DC38736-EF38-446D-B24E-E498E496F501}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1DC38736-EF38-446D-B24E-E498E496F501}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1DC38736-EF38-446D-B24E-E498E496F501}.Release|Any CPU.Build.0 = Release|Any CPU
{72352B4A-6C2E-4800-B7E1-0B5E3111FE93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72352B4A-6C2E-4800-B7E1-0B5E3111FE93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72352B4A-6C2E-4800-B7E1-0B5E3111FE93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72352B4A-6C2E-4800-B7E1-0B5E3111FE93}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
22 changes: 11 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ ARG DOTNET_VERSION=8.0
FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-azurelinux3.0 AS build
WORKDIR /build

# Mount GitHub Token as a Docker secret so that NuGet Feed can be accessed
RUN --mount=type=secret,id=github_token dotnet nuget add source --username USERNAME --password $(cat /run/secrets/github_token) --store-password-in-clear-text --name github "https://nuget.pkg.github.com/DFE-Digital/index.json"

# Copy the application code
COPY ./src/ ./

# Build and publish the dotnet solution
RUN --mount=type=cache,target=/root/.nuget/packages \
dotnet restore && \
dotnet build --no-restore -c Release && \
dotnet publish --no-build -o /app
# Copy the solution file and source code
COPY ./DfE.ExternalApplications.Web.sln ./
COPY ./src/ ./src/

# Mount GitHub Token as a Docker secret, add NuGet source, and build the solution
RUN --mount=type=secret,id=github_token \
--mount=type=cache,target=/root/.nuget/packages \
dotnet nuget add source --username USERNAME --password $(cat /run/secrets/github_token) --store-password-in-clear-text --name github "https://nuget.pkg.github.com/DFE-Digital/index.json" && \
dotnet restore DfE.ExternalApplications.Web.sln && \
dotnet build DfE.ExternalApplications.Web.sln --no-restore -c Release && \
dotnet publish DfE.ExternalApplications.Web.sln --no-build -o /app

# Stage 2 - Build a runtime environment
FROM mcr.microsoft.com/dotnet/aspnet:${DOTNET_VERSION}-azurelinux3.0 AS final
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\DfE.ExternalApplications.Domain\DfE.ExternalApplications.Domain.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using DfE.ExternalApplications.Domain.Models;

namespace DfE.ExternalApplications.Application.Interfaces;

public interface IFormTemplateParser
{
Task<FormTemplate> ParseAsync(Stream templateStream, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using DfE.ExternalApplications.Domain.Models;

namespace DfE.ExternalApplications.Application.Interfaces;

public interface IFormTemplateProvider
{
Task<FormTemplate> GetTemplateAsync(string templateId, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace DfE.ExternalApplications.Application.Interfaces;

public interface ITemplateStore
{
Task<Stream> GetTemplateStreamAsync(string templateId, CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
17 changes: 17 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/Condition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class Condition
{
[JsonPropertyName("triggerField")]
public required string TriggerField { get; set; }

[JsonPropertyName("operator")]
public required string Operator { get; set; }

[JsonPropertyName("value")]
public required object Value { get; set; }
}
14 changes: 14 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/ConditionGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class ConditionGroup
{
[JsonPropertyName("logicalOperator")]
public required string LogicalOperator { get; set; }

[JsonPropertyName("conditions")]
public required List<Condition> Conditions { get; set; }
}
17 changes: 17 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/ConditionalLogic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class ConditionalLogic
{
[JsonPropertyName("conditionGroup")]
public required ConditionGroup ConditionGroup { get; set; }

[JsonPropertyName("affectedElements")]
public required List<string> AffectedElements { get; set; }

[JsonPropertyName("action")]
public required string Action { get; set; }
}
42 changes: 42 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/Field.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class Field
{
[JsonPropertyName("fieldId")]
public required string FieldId { get; set; }

[JsonPropertyName("type")]
public required string Type { get; set; }

[JsonPropertyName("label")]
public required Label Label { get; set; }

[JsonPropertyName("placeholder")]
public string? Placeholder { get; set; }

[JsonPropertyName("tooltip")]
public string? Tooltip { get; set; }

[JsonPropertyName("required")]
public bool Required { get; set; }

[JsonPropertyName("order")]
public required int Order { get; set; }

[JsonPropertyName("visibility")]
public Visibility? Visibility { get; set; }
[JsonPropertyName("validations")]
public List<ValidationRule>? Validations { get; set; }

[JsonPropertyName("options")]
public List<Option>? Options { get; set; }

[JsonPropertyName("complexField")]
public string? ComplexField { get; set; }

public string? Value { get; set; }
}
24 changes: 24 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/FormTemplate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models
{
[ExcludeFromCodeCoverage]
public class FormTemplate
{
[JsonPropertyName("templateId")]
public required string TemplateId { get; set; }

[JsonPropertyName("templateName")]
public required string TemplateName { get; set; }

[JsonPropertyName("description")]
public required string Description { get; set; }

[JsonPropertyName("taskGroups")]
public required List<TaskGroup> TaskGroups { get; set; }

//[JsonPropertyName("conditionalLogic")]
//public List<ConditionalLogic>? ConditionalLogic { get; set; }

Check warning on line 22 in src/DfE.ExternalApplications.Domain/Models/FormTemplate.cs

View workflow job for this annotation

GitHub Actions / Build, Test and Analyse

Remove this commented out code. (https://rules.sonarsource.com/csharp/RSPEC-125)
}
}
13 changes: 13 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/Label.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class Label
{
[JsonPropertyName("value")]
public required string Value { get; set; }
[JsonPropertyName("isPageHeading")]
public bool IsPageHeading { get; set; } = false;
}
14 changes: 14 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/Option.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class Option
{
[JsonPropertyName("value")]
public required string Value { get; set; }

[JsonPropertyName("label")]
public required string Label { get; set; }
}
27 changes: 27 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/Page.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
using DfE.ExternalApplications.Domain.Models;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class Page
{
[JsonPropertyName("pageId")]
public required string PageId { get; set; }

[JsonPropertyName("slug")]
public required string Slug { get; set; }

[JsonPropertyName("title")]
public required string Title { get; set; }

[JsonPropertyName("description")]
public required string Description { get; set; }

[JsonPropertyName("pageOrder")]
public required int PageOrder { get; set; }

[JsonPropertyName("fields")]
public required List<Field> Fields { get; set; }
}
23 changes: 23 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/Task.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class Task
{
[JsonPropertyName("taskId")]
public required string TaskId { get; set; }

[JsonPropertyName("taskName")]
public required string TaskName { get; set; }

[JsonPropertyName("taskOrder")]
public required int TaskOrder { get; set; }

[JsonPropertyName("taskStatus")]
public required string TaskStatus { get; set; }

[JsonPropertyName("pages")]
public required List<Page> Pages { get; set; }
}
23 changes: 23 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/TaskGroup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class TaskGroup
{
[JsonPropertyName("groupId")]
public required string GroupId { get; set; }

[JsonPropertyName("groupName")]
public required string GroupName { get; set; }

[JsonPropertyName("groupOrder")]
public required int GroupOrder { get; set; }

[JsonPropertyName("groupStatus")]
public required string GroupStatus { get; set; }

[JsonPropertyName("tasks")]
public required List<Task> Tasks { get; set; }
}
21 changes: 21 additions & 0 deletions src/DfE.ExternalApplications.Domain/Models/ValidationRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
using DfE.ExternalApplications.Domain.Models;

namespace DfE.ExternalApplications.Domain.Models;

[ExcludeFromCodeCoverage]
public class ValidationRule
{
[JsonPropertyName("type")]
public required string Type { get; set; } // "required", "regex", "maxLength"

[JsonPropertyName("rule")]
public required object Rule { get; set; } // pattern or numeric limit

[JsonPropertyName("message")]
public required string Message { get; set; }

[JsonPropertyName("condition")]
public Condition? Condition { get; set; } // optional conditional application
}
Loading
Loading