Skip to content

mszal449/Heetlog-Graduate-Project

Repository files navigation

Heetlog logo

Heetlog

Know what your heating season actually costs you.

Backend

Rust Actix Web SeaORM PostgreSQL JWT OpenAPI

Infrastructure

Docker Docker Compose NGINX GitHub Actions Render

Frontend

React TypeScript Vite Tailwind CSS Zustand React Router


Overview

Heetlog is a heating management app for people who heat their own house: register your boiler or stove, log every fuel purchase and burn, and get an honest picture of what a heating season costs — plus service reminders so the yearly inspection doesn't get forgotten. Built as my engineering thesis project.

Dashboard

Dashboard
Dark mode Mobile
Dashboard in dark mode Dashboard on mobile

Features

  • Multiple heaters per user (coal, wood, gas, oil, electric, pellet, biomass), each with its own history, and one marked as your main one
  • Fuel records with per-unit tracking (kg / litres / kWh) and cost, aggregated into daily-usage series and season summaries
  • Consumption charts and a stats page — see how usage tracks over the season instead of guessing
  • Service records (cleaning, inspection, repair, maintenance) with statuses and reminders for what's due or already overdue
  • Feature proposals board — users submit ideas, vote on them and comment; statuses are moved by admins
  • Admin panel with a user list and per-user detail view
  • Google OAuth sign-in, light/dark theme, installable as a PWA, Polish-language UI

Tech & why

A thesis project, but built like a real product: real auth, a containerised deployment story, and a test suite that runs against a real database rather than mocks.

Rust was the experiment here. A CRUD app like this would have been quicker in something I already knew — I picked Rust specifically to find out what it's like to build a normal web backend in it, ORM, migrations, OAuth and all.

Rust + Actix Web The experiment — a typed, fast HTTP layer with a controller → service → entity split that keeps business logic out of the handlers
SeaORM + Postgres Async ORM with versioned migrations that run automatically on boot — no manual migration step in prod
utoipa + Swagger UI The OpenAPI spec is derived from the handlers and DTOs themselves and served at /swagger, so the docs can't drift from the code
JWT in httpOnly cookies Short-lived access token plus a refresh token, both httpOnly and SameSite-scoped, exchanged via a one-time code after the Google OAuth redirect
React + TypeScript + Tailwind Responsive frontend with Zustand for client state and thin Axios service modules over the API
Docker Compose One compose file per purpose — run the stack, run the tests — so CI and local runs are the same commands
GitHub Actions Every push builds the images and runs the full backend + frontend suite through make test
Makefile Single entry point for everything: make run, make test, make migration-up, make db-reset

Implementation notes

Backend
  • Layered structurecontrollers/ (HTTP + OpenAPI annotations), services/ (business logic), entities/ (SeaORM models), models/ (request/response DTOs), middleware/ (auth extraction). Domain rules like "is this service overdue?" live on the entity model, not in a handler.
  • Auth — Google OAuth 2.0 is the only login path. The callback hands the frontend a one-time code, which is exchanged for httpOnly access + refresh cookies; the refresh endpoint rotates the access token without another round trip to Google.
  • Migrations — SeaORM migrations under backend/migration/, applied by Migrator::up at startup, so a fresh container is always schema-current.
  • Config — a single AppConfig loaded and validated once at boot (once_cell); missing env vars fail fast instead of surfacing later as runtime errors.
  • Testing — unit tests colocated in src/unit_tests/ for models and config, plus integration tests in backend/tests/ that hit a real Postgres started by Compose.
Frontend
  • Two build modesnpm run dev talks to a locally running backend; the production build is served by NGINX in its own container (frontend/Dockerfile), with the backend URL injected at build time.
  • State — Zustand stores for auth and theme, plain Axios service modules per resource; no data-fetching framework, which keeps the dependency surface small.
  • Theme — light/dark is resolved before first paint by an inline script in index.html, so there's no flash on load.
  • Testing — Vitest + Testing Library with MSW mocking the API, so component tests exercise real request handling instead of stubbed functions.
Deployment & CI
  • Multi-stage images — the Rust backend compiles in a builder stage and ships as a slim runtime image; the frontend builds with Vite and ships as NGINX + static assets. The frontend Dockerfile also exposes a test target that CI reuses.
  • Compose per purposedocker/docker-compose.yml runs the stack, docker/docker-compose.test.yml brings up a throwaway Postgres, runs both suites and tears the volumes down.
  • CI — GitHub Actions runs make test on every push, so CI and a local test run are literally the same command.
  • Hostingrender.yaml deploys the backend as a Docker web service; the frontend deploys as a separate static build.

Project Structure

praca_dyplomowa/
├── backend/            # Rust + Actix Web API
│   ├── src/
│   │   ├── controllers/    # HTTP handlers + OpenAPI annotations
│   │   ├── services/       # business logic
│   │   ├── entities/       # SeaORM entities + domain rules
│   │   ├── models/         # request/response DTOs
│   │   └── middleware/     # auth
│   ├── migration/      # SeaORM migrations
│   └── tests/          # integration tests (real Postgres)
├── frontend/           # React + TypeScript + Vite + Tailwind
│   ├── src/
│   └── tests/          # Vitest + Testing Library + MSW
├── docker/             # compose files (run / test) and seed data
├── .github/workflows/  # CI
└── Makefile            # dev/test/migration/deploy commands

About

Heetlog is a heating management app for people who heat their own house.

Topics

Resources

Stars

Watchers

Forks

Packages

Used by

Contributors

Languages