Work / 2026 / web
Wolt Income Splitter
Splits shared delivery income proportionally, with history and analytics. No build step at all.
- Status
- live
- Stack
- Vanilla JS · HTML · Supabase · PostgreSQL · Row-level security · Chart.js · Service Worker
- Build step
- None
- Dependencies
- Zero installed
- Isolation
- Postgres row-level security
- Offline
- Service worker cache
A PWA for Wolt couriers and fleet owners who share an account or a vehicle. Enter each worker's gross, set the owner's commission and shared expenses, and get everyone's take-home instantly. Three HTML files with inline scripts — no framework, no bundler, no node_modules.
The problem
A fleet owner runs one Wolt account with several drivers. At the end of a pay period the gross has to be divided: the owner takes a commission, shared expenses come off the top, and the rest is split in proportion to what each person actually earned. Done on a phone, at the end of a shift, by someone tired. Arithmetic done that way produces arguments.
The split itself:
Net Income = Total Gross − Expenses
Owner Cut = Net Income × (Commission% / 100)
Workers Pool = Net Income − Owner Cut
per worker:
Proportion = Worker Gross / Total Gross
Take-Home = Workers Pool × Proportion
Constraints
- Phone-first, end of shift. Slow network, tired user, one hand.
- Money. The output is what people are paid. It has to be inspectable, and the formula is on the page for that reason.
- Multiple accounts, strictly separated. One fleet must never see another’s figures.
Decisions
No framework and no build step. Three HTML files with inline <script>
tags, served static. This is a calculator with a history table. A bundler would
have added a toolchain, a lockfile and a class of failures the app does not
otherwise have. The whole thing is readable by viewing source, which for
something that computes people’s pay is a feature.
Row-level security in Postgres, not in the client. Supabase policies enforce isolation at the database, so a bug in the frontend cannot leak another fleet’s data. Authorisation checked anywhere above the data layer is a suggestion.
PWA with a service worker. Installs to the home screen, and the cached pages open in a basement car park with no signal.
Chart.js from a CDN. The single external dependency, loaded for the history analytics only, on a page that is not the critical path.
Tradeoffs
Inline scripts in HTML files do not scale, and this application is not going to scale — it is a formula, a table, and a chart. If it ever grows a third distinct surface the no-build decision should be revisited rather than defended.