HGV HUB

Working-time, pay and compliance tracking for HGV drivers — a personal tool that had to grow a domain model once it served more than one person.

Active PublicOpen Source

What it is

An open-source platform for tracking HGV working time, pay and operational compliance. It runs two ways — entirely in your browser with no server, or self-hosted with a real backend — and there is no service of mine in the middle of either.

Figures below were measured on 31 August 2026.

The problem it started with

It began as a single-purpose tool for my own driving work: my hours, my rates, my employer’s rules. That is a perfectly good reason to build something, and it is also the beginning of the actual engineering problem rather than the end of it.

Working time in this domain is genuinely awkward to model. Shifts cross midnight. Pay bands differ by day of week and time of day. Rest and driving limits run on their own cycles that ignore calendar boundaries. A driver can work through an agency for one client this week and a different one next week, on different terms, with the same underlying legal obligations following the driver rather than the arrangement.

None of that is hard to hardcode for one person. All of it is hard to hardcode for two.

When hardcoded stopped scaling

The interesting part is what the code had to become.

The evolution is recorded as fourteen numbered migrations, each with its own tests, and their names read as a fair summary of the journey: local storage moved to a real indexed database; a rate table that had been a constant in the application became versioned data; a master-data foundation appeared; employer and client organisations — originally the same conflated thing — were separated; person and driver profile were pulled apart; engagements and placements were refined.

The original hardcoded rate table survives only as static migration data, so an existing install still upgrades correctly. Nothing in the codebase reads a hardcoded rate any more. That is the shape of the whole change: the personal assumptions were not deleted, they were turned into configuration.

One shift, two views

The idea the current model is built around is small and does a lot of work.

A shift exists once. The driver’s view and the company’s view are different queries over the same canonical record — not two representations kept in step by whoever remembers to update both.

One canonical Shift stored once Driver view a query Company view a different query Not two copies kept in step. Pay · Rate cards Organisation commercial config Driver compliance driver-based rules No dependency, enforced in code. Changing who pays, or how much, cannot change the rules a driver is measured against.

Architecture only. No real records, organisations or rates are represented.

Underneath it sits a small set of entities — Workspace, Person, Membership, Organisation, Engagement, Assignment, Shift, RateCard, ComplianceProfile — which exist because each one replaced an assumption that used to be implicit in a single person’s setup.

The boundary the architecture enforces

The decision I would defend hardest is an absence.

The compliance layer does not import the pay engine or the rate-card service. It cannot read them, so it cannot be influenced by them. Compliance rules are configured per driver, never per company.

That matters because the alternative is quietly dangerous. If an organisation’s configuration, an engagement, a pay structure or a rate card could feed into how a driver’s hours are evaluated, then a commercial change could move a compliance threshold without anyone deciding to move it. Separating them is a structural guarantee rather than a policy someone has to remember.

It is an engineering boundary. It is not certification, and it does not make any output legally authoritative.

Modelling regulated work

What the system currently models: driving, working and rest concepts on an EU/tachograph-oriented workflow · vehicle walkaround checks, including paired tractor-and-trailer checks with defects attributed to the right vehicle · a defect status workflow · driver document expiry for licence, tachograph card and CPC · the 35-hour, five-year CPC training cycle · rate cards and per-load pay · and a Transport Manager view whose scope is informed by the Senior Traffic Commissioner’s Statutory Document No. 3.

The boundary, stated plainly: HGV HUB models these concepts. It does not replace a tachograph, provide certification, guarantee legal compliance, calculate payroll authoritatively, or replace professional judgement. Every output depends on what you enter.

Two ways to run it

Solo. No server, no account, no sign-up. Data lives in the browser’s own IndexedDB on that one device.

Self-hosted. A real backend — Fastify and PostgreSQL, accounts with Argon2id password hashing and server-side sessions, packaged for Docker Compose.

Both modes run the same client and the same domain logic; the difference is where the data lives, not what the application believes. There is no hosted HGV HUB service, and none is planned.

The interface is fully available in English and Polish.

Tests and independent CI

386 automated tests. More useful than the number is what they hold: complete Vehicle Check flows driven through the real UI, a failed checklist item automatically raising a defect and that defect closing back through check history, tractor-and-trailer pairing attributing faults to the correct vehicle, the rate-card lifecycle from creation through revision to archive, and every one of the fourteen migrations.

They run on GitHub Actions against the public repository, currently green.

Moving them into independent CI was worth doing for a reason beyond the badge: it immediately exposed timing-dependent assumptions in the test suite that never failed on a development machine. Those tests were asserting on state that loads asynchronously, and were corrected to wait for it properly.

Where it stands

Active development, currently v0.4.3. Public and open source under GNU AGPL-3.0-or-later — releases up to v0.3.19 were MIT, and those grants stand.

Public releases are produced through a controlled release pipeline rather than by publishing development history directly, so release provenance and privacy are part of the publishing process rather than something checked afterwards.

Honestly stated: I haven’t verified any external users yet. There are no external contributors, no adoption to report, and no hosted service. It is a working tool that is open for others to run, not a product with a user base I can point to.

Source

The official upstream is github.com/Sako404/hgv-hub. Contributions are welcome under the repository’s own policy — the one firm rule there being that fixtures and examples must be synthetic, never real driver, employer or client data.

All projects