DFE-Digital / DFE-Digital/check-performance-data
[Tech debt] Web controllers query IPortalDbContext directly
@davidgouge is already working on this.
Since Sep 8, 2026.
- Dominant language
- C#
- Stars
- 0
- Forks
- 1
- Avg merge
- 19h 21m
- Merged PRs (30d)
- 54
Description
Overview
Five controllers inject IPortalDbContext and query DbSets directly in the action. DevPipelineController and TestDataController are development tooling, but ContentStagingController and SearchAnalyticsController are real features. Each is business logic in Web with no Application service in front of it, and no way to unit test it without a database.
Separately, four of the five declare the dependency as an optional nullable constructor parameter — IPortalDbContext? dbContext = null. That is test convenience leaking into production wiring: if the registration is ever missed, the controller silently does nothing at runtime instead of failing at startup.
Evidence
Controllers injecting IPortalDbContext:
Web/Controllers/DevPipelineController.cs:25Web/Controllers/QueueAdminController.cs:32— optional-nullWeb/Controllers/SearchAnalyticsController.cs:66— optional-nullWeb/Controllers/TestDataController.cs:48— optional-nullWeb/Controllers/ContentStagingController.cs:30— optional-null
Proposed fix
Give each controller a repository or query-service interface defined in Application and implemented in Persistence, following the existing pattern (IWindowRepository, IContentBlockRepository). SearchAnalyticsController largely has this already via SearchAnalyticsQueryService — the direct IPortalDbContext use alongside it should be folded in.
Make every injected dependency required. Where a test needs a substitute, substitute the interface with NSubstitute rather than passing null.
Once done, the Web project's reference to Persistence should be needed only by Program.cs / MigrationExtensions.cs for migration wiring.
Acceptance criteria
- No
*Controller.csin Web referencesIPortalDbContext. - No controller constructor has an optional nullable service parameter.
- New repository interfaces live in Application, implementations in Persistence, registered in the Persistence
DependencyManager. - The corresponding architecture test is unskipped and passing.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.