Insight
Building a heating-analysis application
Requirements, service boundaries and reviewable automation in a React and Spring Boot application for heating-system efficiency.
- Project
- 2021
- Published
- Author
- Janis Schanbacher
At EWUS, engineers needed to identify efficiency improvements across existing heating systems. I built a web application to support that work, bringing together installation and measurement data, automated analyses and a review step before saving the results.
The project used React, Java and Spring Boot and formed the basis of my 2021 bachelor’s thesis at HTW Berlin. Three decisions connect the requirements, architecture and interface: what to automate, where to draw system boundaries, and how engineers would review the results.
Define a useful result before automating it
The initial scope covered four analyses: equipment sizing, utilisation efficiency, return temperature and the difference between supply and return temperatures.
Discussions with my company supervisor translated the engineers’ working process into scenarios, user stories and acceptance criteria. One requirement shaped much of the design: generated suggestions must be reviewed before they replace existing text. The first version would assist an engineer, with full automation left for later.
That decision made the scope concrete. An analysis needed to produce a suggestion an engineer could inspect, edit and approve. “Run an analysis” became a workflow that could be implemented and evaluated with its intended users.
Separate responsibilities before choosing services
Data access was useful beyond this one application. I separated a facility service, which combined information from existing systems, from an analysis service responsible for calculations and their configuration. A React frontend handled the user workflow.
These were deliberately broad services communicating over HTTP and JSON. Analysis configuration stayed inside the analysis service; it did not need another deployment of its own. The thesis compares monolithic, service-oriented and microservice architectures, but the practical question was which boundaries supported reuse without creating unnecessary operational work.
Inside those boundaries, Model–View–Controller helped organise the React view, request-handling controllers and separate model/application logic; Spring Data JPA repositories handled persistence. Convention over configuration reduced setup choices; explicit domain names and focused methods made the application-specific parts easier to follow.
The API combined resource-oriented configuration with a batch-analysis command that accepted a selection of installations. The thesis describes that command as RPC-style alongside the REST-oriented endpoints: the interface made the analysis operation explicit.
Today I would also compare this design with a modular monolith: clear responsibilities do not require separate processes. The deciding factors are reuse, team ownership and the cost of deploying and changing the system. Fowler’s monolith-first discussion provides useful context for that tradeoff.
Make review part of the interface
The engineers were used to tables and installation identifiers. The interface built on that familiarity: existing text alongside generated suggestions, editable results and explicit confirmation before saving.

A second screen let engineers choose which analyses ran for each installation. Bulk changes appeared in the table before a separate confirmation saved them. That made a convenient action easier to inspect before it affected many installations.

This is a useful pattern wherever software proposes consequential changes: put the result, relevant context and confirmation close together. A technically successful request should also leave the person using it able to understand what happened.
Build confidence through feedback
JUnit, Mockito and a HyperSQL test database covered backend behaviour. Spotless and ESLint supported consistent code. Frontend checks were manual, and two intended users tried the application without a walkthrough. Their feedback exposed practical improvements: preserve screen state, carry selections between screens and warn before discarding unsaved changes.
Automated tests and user feedback answered different questions: whether calculations and persistence behaved as expected, and whether the workflow made sense in practice. The thesis also identified repeated manual checks worth automating.
The result was a working prototype with four analyses, reusable data access and a review workflow. Its purpose—helping engineers improve heating-system efficiency—made the project especially worthwhile to me.
After the thesis
After the thesis, I continued developing and maintaining the application. Between 2022 and 2025, my work included Sentry-based error tracking and improvements to data integration and error handling, making failures easier to investigate as the application evolved.
In 2024, I added Docker and Docker Compose setups for builds and local development, and GitHub Actions workflows to build and deploy the backend services to Azure Container Apps. I also connected deployments with Sentry release tracking, helping relate reported errors to the deployed software version.
Thesis and source code
The full thesis and original frontend/backend code from 2021 document the original implementation in detail. The German thesis PDF includes the architecture comparison, demonstration and evaluation; the images above are its original figures 6.2 and 6.3.