HMPPS Creating Future Opportunities (CFO) utilise the Case Assessment and Tracking System (CATS) to support delivery of CFO Evolution . The programme utilises external funding to perform rehabilitative services with offenders in custody and the community. Approx. 600 users from non-government organisations use CATS to record work performed with offenders creating an evidence base that supports performance management, payments to providers, ongoing research and audits from external bodies.
Mechanism (How does it communicate with other systems? Frequency of data pull/push, reporting, events etc)
CATS relies on the external data from Nomis and Delius. This is aggregated and managed by the CFO Data Management System.
- ASP.NET Core (Blazor)
- C#
- LINQ
- Entity Framework (runtime ORM)
- SQL Project (database schema management)
- SQL Server
- HTML, CSS, Javascript
- Dotnet Aspire
600 (approx. 100 concurrent)
This has been developed on Windows 11 using Visual Studio 2022, Visual Studio Code and JetBrains Rider
- .NET 10 SDK
- Visual Studio Code users:
The recommended way to run and debug these apps is using .NET Aspire.
- Using Visual Studio Code: open the project and press
F5, selecting the Default Configuration. - Using Visual Studio or other IDEs: From the debug configuration dropdown, select
Cats.AppHostand start the application.
On startup, Aspire automatically applies the SQL Project schema to the local SQL Server container before starting the application. The DatabaseSeeding project then runs to seed any required reference data. No manual migration steps are needed for local development.
The database schema is managed via a SQL Project at src/Database/CatsDb/CatsDb.sqlproj (using the Microsoft.Build.Sql SDK). Schema is defined as .sql files organised by SQL schema (e.g. Activities/, Enrolment/, Identity/).
When running locally via Aspire, the CatsSqlProj resource deploys the SQL Project to the local SQL Server container automatically. EF Core is used as the runtime ORM only — it no longer manages migrations.
Note: The SQL Project deployment is skipped when publishing to Kubernetes (
WithSkipWhenDeployed()). The schema must be applied to the target database separately before deploying a new release.
This repository includes a file-based Cake script at cake.cs. Run it from the repository root with:
dotnet cake.csBy default this runs the Publish target with the Release configuration. The full target chain is:
Clean -> Restore -> Build -> Test -> Publish
You can run a specific target or change the configuration by passing arguments to the script:
# Build without publishing
dotnet cake.cs --target=Build
# Run tests
dotnet cake.cs --target=Test
# Publish using Debug configuration
dotnet cake.cs --target=Publish --configuration=DebugAvailable targets:
CleanRestoreBuildTestPublish
The Publish target writes output to:
artifacts/Server.UIartifacts/DatabaseSeedingartifacts/CatsDb.dacpac
This repository uses Aspire for service composition (dependency injection, service discovery, and configuration management).
Aspire is also used to provide a Kubernetes publishing workflow that is currently in preview: container image build & push, and generation/packaging of Kubernetes manifests & Helm charts.
Prerequisites
- Docker (for image builds)
- Access to a container registry (credentials configured)
- kubectl and a valid kubeconfig with cluster access
- Helm (for chart-based deployments)
IMAGE_NAME=hmpps-cfo/cats
TAG=latest
REGISTRY=registry.mycorp.com:1234
# Locally
dotnet publish src/Server.UI/Server.UI.csproj \
--configuration Release \
--os linux \
--arch x64 \
--target:PublishContainer \
--property:ContainerRepository=$IMAGE_NAME \
--property:ContainerImageTag=$TAG
# or to a remote registry (with the ContainerRegistry property)
dotnet publish src/Server.UI/Server.UI.csproj \
--configuration Release \
--os linux \
--arch x64 \
--target:PublishContainer \
--property:ContainerRegistry=$REGISTRY \
--property:ContainerRepository=$IMAGE_NAME \
--property:ContainerImageTag=$TAG
dotnet aspire publish -o aspire-output
helm upgrade --install aspire ./aspire-output --namespace default \
--set parameters.cats.cats_image=$IMAGE