Academic records and degrees
Academic-record management for the Proeduca group and official degree issuance: .NET 8 APIs, Docker and an Angular frontend in production, with Clean Architecture and DDD.
Problem
Academic records and official degree issuance cut across institutions in the Proeduca group. The risk is not picking a framework: it is the domain coupling to infrastructure, so a failure in a record or a degree stops the process.
Solution
A bounded domain for records and degrees with Clean Architecture and DDD, .NET 8 APIs containerised with Docker, CQRS with Mediator, and a pipeline (TeamCity, Azure DevOps, SonarQube, GitFlow) that keeps untested, unreviewed work off main.
Results
80%
Unit test coverage held
2020 — present
In the role
Records and degrees in production
Product
- Presentation
API and frontend
ASP.NET Core and Angular 18. Adapters: they do not own the domain.
- Application
Use cases
CQRS with Mediator. A command or a query, not a fat controller.
- Domain
Records and degrees
Entities and business rules. Zero framework dependencies.
- Infrastructure
Data and Docker
Entity Framework, SQL Server and .NET 8. Docker for dev/prod parity.
How it reaches production
- TeamCity
- Azure DevOps
- Docker
- SonarQube
- GitFlow
- Code review
Tech stack
- .NET 8
- C#
- ASP.NET Core
- Entity Framework
- Angular 18
- SQL Server
- Docker
- Azure DevOps
- TeamCity
- SonarQube
The work I lead at Proeduca is not a public portfolio piece: it is academic-record management for the group and official degree issuance. I lead a Scrum team that ships domain, .NET 8 APIs and an Angular frontend, all in production and containerised with Docker.
This case covers the decisions that can be said out loud. The code stays at Proeduca.
What had to keep running
A record does not fail in the abstract: it fails when enrolment, assessment or a degree cannot be issued. The work of these years has been to modernise that domain without cutting service, with a core that can be maintained and a pipeline that keeps unreviewed work off main.
Decisions
Clean Architecture and DDD. The records-and-degrees domain does not depend on ASP.NET, Entity Framework or Angular. Business rules live in the core; the API and the frontend are adapters. The promise is not using a fashionable pattern: it is that code written today can still be maintained by someone else two years from now.
CQRS with Mediator. Use cases come in as a command or a query, not a fat controller. Mediator decouples orchestration from infrastructure: the handler talks to the domain and to repositories, not to HTTP or SQL details.
.NET 8 and Docker. The backend runs on current ASP.NET Core. Docker keeps the development environment and production aligned: what passes tests in the pipeline is what gets deployed.
Delivery. TeamCity and Azure DevOps run the pipeline. SonarQube and GitFlow, with pull-request code review, are the gate to main. Unit test coverage is held at 80%.
AI, at the scope it actually has
AI comes into the development cycle —Claude, Codex, OpenCode— where it shortens the path. Internal process automation runs on n8n. Neither replaces the judgement of whoever merges, and neither is a production microservice for academic documents: that is not on the record here.
Gallery
What I learned
- → Pull-request code review as the only gate to main is cheaper than an incident on a degree or in enrolment season.
- → 80% coverage is not a sprint number: it is a line the pipeline holds.
- → Mediator and DDD are not ceremony. They are the boundary that stops the frontend or Entity Framework from owning the domain.
- → Docker keeps development and production aligned; .NET 8 is the floor, not the slogan.
- → AI in the development cycle (Claude, Codex, OpenCode) shortens the path; n8n covers internal automation. Neither replaces the judgement of whoever merges.
Architecture · technical leadership · .NET
Hiring a .NET Software Architect or Tech Lead?
Open to full-time employment in software architecture or technical leadership on .NET products. Tell me about the role and the team: I reply within 24–48 h.