Harry Mbwasi

Latest

The OutbreakA hidden-role LAN game in Unity. Roles are dealt in secret, and the bunker they are dealt in is generated by code, not hand-built.September 2026

Work

Mineral tracker

A Django system for mineral stock and transport, built around four roles that each see a different slice of the same data.

Role
Engineering
Built with
Django, Python, PostgreSQL, django-allauth
Title card on warm paper: Mineral tracker, set in a large serif, over the line 'Mineral management and transportation, role by role.'

A management system for mineral stock and its movement, what is held, what is moving, and who signed for it.

Shipment tracking: a table of five shipments listing mineral, truck plate, route, weight, departure and arrival. Gypsum and copper ore are still in transit and show a dash where the arrival time will go.

The records in these screenshots are sample data, entered to exercise the dashboards. They are not real trading figures.

Roles are the design

The system defines four roles, administrator, operations manager, financial manager and store keeper, and they are the organising idea rather than a permissions afterthought. Each role opens onto a different part of the same records, which is what separates a tool that a warehouse actually uses from a CRUD interface with everything visible to everyone.

Login is required globally: anonymous requests redirect to the sign-in page rather than falling through to a public view, so there is no route that quietly leaks a record. Sign-in runs through django-allauth, with Google as an option, because the alternative is asking a store keeper to remember one more password.

What that separation looks like in practice: the financial manager opens onto money, and the store keeper opens onto stock. Neither screen is a filtered version of the other.

The financial manager’s view: five totals across the top — inflow, outflow, gross profit, government tax at eighteen per cent, and net profit, all in Tanzanian shillings — above a table of recent payments and two panels tracking debt owed by and to the business.

The store keeper’s view: stock balances by item on the left, the latest inbound and outbound movements on the right, each one carrying a reference such as a goods-received number.

Tax is computed rather than typed: the rate is a setting, and the dashboard derives government tax and net profit from the inflows and outflows already recorded, so the figure cannot drift from the payments it is drawn from.

Notes

  • Postgres first, reading DATABASE_URL, with a SQLite fallback so the project runs from a clean clone.
  • A setup_roles management command creates the role groups, so the permission model is reproducible rather than clicked together in the admin once and forgotten.
  • No GDAL anywhere, a deliberate choice, and anyone who has tried to deploy a Django app with a geospatial dependency on a small host will know why.