Skip to content

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

119 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

SchoolAccount-Web is an MVC presentation application for the DfE School Account service built on .NET 10. It uses a minimal clean architecture solution, with CQRS abstractions, structured logging, error handling, and architecture tests.

Documentation

Architecture decisions are recorded as ADRs in the decisions folder:

New decisions should follow the ADR template.

Getting Started

Follow these steps to start the MVC locally.

Note: Windows users can use the git bash command prompt to run the project's .sh bash scripts.

  1. Install prerequisites:

  2. Run the setup script from the repository root to restore the dotnet tools and enable the git hooks:

    ./init.sh
  3. Run the MVC using one of the following:

    Method Command Outcome
    Docker Compose docker compose up --build Starts the MVC and its dependencies (Seq) in containers
    .NET CLI dotnet run --project src/SchoolAccount.Web.Mvc Runs the MVC directly using the http launch profile, no containers

    In Rider or Visual Studio you can use the equivalent docker-compose or http run configurations from the toolbar.

  4. Launch Collect API.

  5. Once running, the presentation is available at http://localhost:5016:

    • Logs (if started with compose) at http://localhost:8081
  6. Debugging guidance:

    • Set breakpoints in your C# files under src/ and start either run configuration with debugging enabled.

Feedback Component

To ensure the feedback component is functional locally, there are tools that can be used to see this journey.

  1. Install prerequisites:

  2. Go to the root of the LocalDevTools repository and run this command to start Azurite and seed an initial table:

docker compose up
  1. Open Azure Storage Explorer and connect to the Azurite instance running on http://127.0.0.1:10002/devstoreaccount1/

  2. To set your own TableStorageConnectionString use the .NET user secrets

  3. Use the feedback component and check Azure Storage Explorer to see your new data

Configuration

The project requires the following app configuration values to be overridden, ideally using User Secrets:

{
  "OpenIDConnectSettings": {
    "Authority": "<URL-OF-DSI-OIDC-SERVER>",
    "ClientId": "<DSI-CLIENT-ID>"
  },
  "AcademiesApiClient": {
    "BaseUrl": "<URL-OF-ACADEMIES-API>",
    "ApiKey": "<ACADEMIES-API-KEY>"
  }
}

Build and Test

Use the .NET CLI to build or test the solution.

  • To build locally:

    dotnet build
  • To run all tests:

    dotnet test

Architecture tests under tests/SchoolAccount.ArchitectureTests enforce the clean architecture dependency rules between layers.

Formatting

Code is formatted with CSharpier, installed as a local dotnet tool and enforced by the "Check formatting" step in the build workflow. To format the solution locally:

dotnet csharpier format .

A pre-commit hook, managed by Husky.NET and configured in .husky/task-runner.json, formats staged C# files automatically before each commit; init.sh installs it and restores the tools on a fresh clone. To format on save, install the Rider plugin or the VS Code extension; the editors documentation covers setup for these and other IDEs. See Format code with CSharpier for the reasoning.

Code Analysis

The build runs with the full set of .NET/Roslyn analyzers (AnalysisLevel=latest, AnalysisMode=All) plus SonarAnalyzer.CSharp, configured in Directory.Build.props. TreatWarningsAsErrors means any violation fails dotnet build, locally and in the build workflow, rather than being left as a warning. Rules that don't fit this codebase are suppressed by ID in .editorconfig. See Coding Standards and Enforce code quality with Roslyn analysers for the conventions and the reasoning.

Code Coverage

The build workflow collects code coverage on every run, posts a summary to the pull request, and fails the build if line coverage drops below the minimum threshold. The threshold is defined by the MIN_LINE_COVERAGE variable at the top of build.yml. Which files are included is controlled by coverage.config.

To generate the same report locally, run coverage.sh from the repository root:

./coverage.sh

To ensure that the same report is generated locally, ensure you have the latest version of dotnet installed.

The script runs all tests with coverage enabled, merges the per-project results with ReportGenerator, and writes an HTML report to TestResults/CoverageReport/index.html. Pass --open to open the report in your browser when it finishes:

./coverage.sh --open

Architecture

The solution follows a clean architecture pattern with vertical slice features:

Project Purpose
SchoolAccount.Web.Mvc ASP.NET Core Web MVC - controllers, middleware, error handling
SchoolAccount.Application CQRS handlers and feature logic, organised by feature folder
SchoolAccount.Domain Domain entities and business rules
SchoolAccount.Infrastructure External concerns - time, data access, integrations
SchoolAccount.SharedKernel Shared primitives - Result<T>, Error, ValidationError

Logging

Structured logs are written via Serilog to Seq. When running via Docker Compose, the Seq UI is available at http://localhost:8081.

Published Docker Image

The Web project is published to the GitHub Container Registry as a Docker image that can be pulled down and run. The image is created on every push to the main branch and tagged with the current commit SHA and the latest tag.

To verify the image locally, you can run:

docker run --platform linux/amd64 --name web -e OpenIDConnectSettings__ClientId=SA_TEST_CLIENT -e OpenIDConnectSettings__Authority=https://localhost:7041 -e ASPNETCORE_ENVIRONMENT=development -p 5100:8080 -d --pull=always ghcr.io/dfe-digital/schoolaccount-web:latest

You can then test the Web project by visiting http://localhost:5100.

To stop and delete the container, you can run:

docker stop web
docker rm web

Dependency Updates

Dependabot checks NuGet packages and GitHub Actions weekly, and groups updates to keep the number of pull requests down. A NuGet package goes in the first group it matches:

Group What's in it Update types
test-tooling Test libraries All
dotnet Packages released with each version of .NET, such as Microsoft.AspNetCore.* All
azure Azure SDK packages, which all build on Azure.Core All
serilog Serilog and its sinks All
fluentvalidation FluentValidation and its DI extensions All
opentelemetry OpenTelemetry exporters and instrumentation All
minor-and-patch Every other package, except SonarAnalyzer.CSharp Minor, patch
(no group) Major updates to other packages, and every SonarAnalyzer.CSharp update One PR each

SonarAnalyzer.CSharp gets its own pull requests because a new release can add rules that fail the build, which would hold up every other update in a group. GitHub Actions minor and patch updates arrive together in one pull request.

Directory.Packages.props has one labelled ItemGroup per group, so the grouping is visible where versions are set. When you add a package:

  1. Add its version to the ItemGroup for its group, or to other if none fits.
  2. If it went into a named group, check that a pattern in that group in dependabot.yml matches its name, and add one if not. Packages in other need no change, because minor-and-patch covers them.

Use the exact package name for a single package (for example "Shouldly"), or end it with * to match a family of packages (for example "Microsoft.Testing.*").

Contributing

  1. Branch from main using the convention task/<short-description> or feature/<short-description>.
  2. Open a pull request against main.
  3. The build workflow must pass before merging.

Third-Party Libraries

Some components within the solution are third-party libraries, which cannot be managed via NuGet packages. These will be self-managed; listed below and are located within the solution under a lib folder.

Name Version / Date Added Source
Step By Step Navigation Thu 3rd Sep 2026 https://github.com/alphagov/govuk-prototype-kit-step-by-step

Support for npm packages may be added in the future.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages