Digital operations logbook for two thermal power plants
I replaced the Excel shift logbooks with a real-time web application, with shifts as a business entity, official reports generated from the data and more than 1,400 automated tests.
Project facts
- Role
- Full-stack engineer, sole developer (design, backend, frontend, database, deployment)
- Period
- Mar 2026 to present
- Public links
- Internal system: the code is private, and names, data and diagrams were left out or recreated.
1,400+
automated test cases across backend and frontendSource: node:test and Vitest suites in the repository, September 2026 516
commits over 6 months of continuous developmentSource: Git history, March to September 2026 38 of 39
findings closed from an in-house security auditSource: Internal security audit report, 2026
The problem
Operations staff at two thermal power plants kept their shift logs in Excel workbooks. Information was scattered across files, closing a shift depended on each person's discipline, and the official daily reports were assembled by hand by copying cells.
My role
- Gathered requirements with shift supervisors, operations engineers and chemists, and turned them into a domain model of shifts, logbooks and role-based permissions.
- Designed and built the frontend, the backend, the database and the corporate sign-in integration.
- Deployed and run the system on a company Linux server, with nginx, systemd and an update script with built-in checks.
- Documented 71 architecture decisions and drove an in-house security audit until 38 of 39 findings were closed.
Constraints
- Users on 24-hour shifts whose operating day crosses midnight.
- Mandatory corporate sign-in with role-based access.
- Self-hosted server on the corporate network, behind a firewall that inspects TLS.
- Minimal third-party dependencies to keep auditing and maintenance simple.
Decisions
- 01
Shifts as a business entity, closed atomically
Closing a shift freezes the team roster into an immutable snapshot, so history does not change when staff changes later.
Ruled out
- Store loose events and rebuild shifts at query time
- 02
Real time over WebSockets with origin validation
Several people work on the same shift at once; changes arrive instantly and origin validation prevents connection hijacking.
Ruled out
- Poll the server every few seconds
- 03
In-house .xlsx reader and writer on top of zlib
The official report had to match the Excel template exactly without adding large libraries to a backend that has only 6 production dependencies.
Ruled out
- Use a third-party spreadsheet library
- 04
A tested data contract with the generation dashboard
Another production system consumes the logbook events. A contract test fails if either side changes the shape of the data, and each system writes only to its own schema.
Ruled out
- Let the dashboard read the logbook tables directly
Architecture
Users
- Operations web appReact, views per role and per plant
Services
- Logbook APIExpress, 19 domain modules
- Real-time channelWebSockets with origin validation
- Scheduled jobsShift closing, hourly ingestion and dispatch
Data
- SQL ServerCatalogs and transactions in separate schemas
- Official Excel reportGenerated from the data
Integrations
- Microsoft Entra IDSign-in and role-based access
- Plant historianHourly fuel consumption
- Generation dashboardConsumes events through the contract
How data moves
- Operations web apptoLogbook APILogs events and closes shifts
- Real-time channeltoOperations web appPushes shift changes and active users
- Logbook APItoSQL ServerStores every entry with its shift
- Logbook APItoMicrosoft Entra IDValidates the session and permissions
- Plant historiantoScheduled jobsDelivers each hour of consumption
- Logbook APItoOfficial Excel reportBuilds the daily workbook
- Generation dashboardtoLogbook APIQueries events by period
Results
- Both plants log their shifts in the application, with each shift's history frozen when it closes.
- The official daily report comes out of the data in the template's format, with no cells copied by hand.
- The generation dashboard consumes logbook events through a tested contract, without touching its tables.
What I would do differently
- From day one I would prioritize the tests that protect dangerous invariants, such as never deleting data from a real plant, over overall coverage.
- I would move the scheduled jobs into a separate service earlier, so the API can restart without pausing plant data ingestion.
Technologies
- React
- Vite
- Node.js
- Express
- WebSockets
- SQL Server
- Microsoft Entra ID
- Microsoft Graph
- Excel
- Linux
- nginx
- systemd