Jonathan Hipolito

← All projects

Forecasting and rostering

Headcount

Works out how busy a made-up café in Fitzroy, Melbourne will be next week, half-hour by half-hour, then builds the staff roster for it. A machine learning model forecasts the coffees and covers from the weather, holidays and local events, and a constraint solver fills the week: everyone inside their availability and leave, ten hours off between shifts, and the lowest wage bill once weekend, public holiday and casual rates are counted.

Headcount forecast for a week in Melbourne: the accuracy test against copying last week, each day's weather and expected orders, and Saturday's coffees and covers through the day with rain cutting it 20%
The roster for the same Saturday built from the forecast: each person's shift on a timeline under the needed versus rostered curve, and the solver panel showing an optimal roster with coverage up to 98.6% and a lower wage bill

What I built

  • A forecasting model in Python (scikit-learn, gradient-boosted trees with a Poisson loss) trained on two years of half-hourly sales against real Melbourne weather from Open-Meteo, Victorian public and school holidays, and local events like AFL Grand Final day
  • Honest accuracy: it's tested on the eight weeks it never trained on and shown next to simply copying last week (about 17% off per half-hour on coffees versus 24%), with the actual, forecast and copy lines on one chart
  • Each day explained step by step from a plain day of the same weekday (rain −25%, street festival +13%), and what-ifs for rain, heat or an event that redraw the forecast and the staff it needs
  • Staffing ratios that turn the forecast into how many baristas, floor staff and cooks each half-hour needs, applied to that week's roster in one click
  • A FastAPI service with an OR-Tools CP-SAT model that rosters 16 people for the week and, usually within a few seconds, proves it's the cheapest roster that keeps every rule, streaming each better roster to the browser while it works
  • A checker that explains every gap (who could have covered it and why they didn't) and a Next.js front end built as static files: coverage curve, drag-to-edit day timeline, week grid, staff, leave and pay rules. The API runs in Docker with MySQL behind a Cloudflare Tunnel

Stack

Python, scikit-learn, FastAPI, OR-Tools, SQLAlchemy, MySQL, Next.js, TypeScript, Docker

Live

scheduling-demo.jnathan.dev ↗