Ground-up system · Desktop, web & realtime · 2026
Fuel Station Management System
A complete fuel-management system for gas stations, built from the ground up: a Windows desktop middleware that drives forecourt controllers and outdoor payment terminals and hands every sale to the store POS, plus a multi-tenant central platform with an Angular admin app that enforces fleet-card fuel limits at the pump in real time.
The challenge
Fuel dispensers, an outdoor payment terminal, bank pre-authorizations, the store POS and the operator’s ERP all had to agree on every litre sold — including at night, unattended, when the terminal is the only cashier. Fleet customers needed monthly fuel limits enforced at the pump even though the ERP’s balances lag, and nothing could ever release money or lose a transaction because a network link or the application went down.
What I contributed
- 01
Built the station desktop middleware in VB.NET: forecourt controller integration — pump status, money and volume presets, transaction lock and clear for multi-POS sites, emergency stop, price pushes — over both a serial driver and the vendor’s COM API.
- 02
Implemented the outdoor payment terminal as a screen-by-screen state machine: pump selection, barcode, amount, PIN, bank pre-authorization and completion, fuelling and receipt printing, with reconnect timers and recovery of uncompleted card transactions after a restart.
- 03
Defined the file-based POS contract — one transaction file per sale, written temp-then-atomic-rename, with encrypted per-pump recovery files — so the existing POS and ERP agent consume sales unchanged.
- 04
Designed the central platform on .NET 10: a multi-tenant minimal API with a master database plus one database per tenant, hashed station API keys, JWT roles, EF Core, a worker service syncing companies and vehicles from the ERP, and an Angular 22 zoneless admin app.
- 05
Wrote the fleet-limit engine: available = monthly limit − fuel this business month − active reservations, with an idempotent create → authorize → complete/cancel protocol, SQL Server application locks per company, and a maintenance worker that moves unresolved reservations to review instead of releasing money.
- 06
Extracted a pure, unit-tested reliability core — journal state machine, ordered outbox with exponential retry, recovery planner — and wired it into the desktop so fleet fuelling is fail-closed while card and manual sales keep working when the backend is unreachable.
- 07
Ran the infrastructure end to end: VPN for stations, Caddy TLS in front of IIS, Gitea CI/CD with staged deploys and rollback, a private wiki, and a security hardening pass (secrets out of the repo, fixed-time PIN checks, log redaction, firewall audit).
Key decisions
Reserve before you authorize
The ERP balance lags, so the platform reserves limit first and only then authorizes the pump preset — the dispenser pumps against money that is already accounted for.
Never release money automatically
Authorized reservations that go unresolved are moved to review with an incident, not cancelled. A person decides; the system only makes the state visible.
Fail closed for fleet cards, open for everything else
If the central platform is unreachable, fleet-card fuelling stops but card and manual sales continue — a station never goes dark because a backend did.
Keep the legacy contract
The store POS reads the same one-line transaction files it always did; atomic writes and recovery files sit behind that contract instead of replacing it.
The outcome
The operator runs the system in production across its stations with a second company onboarding: unattended night fuelling against prepayment, fleet limits enforced at the pump in real time, remote diagnostics and pump-incident dashboards for the back office, and a codebase with a tested reliability core rather than defensive patches.