From spreadsheets to a system for shifts and contracts in healthcare.
A company supplying doctors and healthcare professionals to hospitals and facilities across Italy ran shifts, contracts and margins on spreadsheets and an old portal. We replaced both with a system built around the way it works.
We built a custom management system for a healthcare staffing provider. Doctors sign up through a portal, upload documents and see their shifts; the back office manages contracts, extensions and rates by time fraction, plans shifts on a calendar and gets the cost, revenue and margin of every shift automatically. Three report engines, Excel exports of every list and PDF calendars complete the picture. The new system replaced the old one on 18 March 2025 and has kept growing since.
Context
The client manages professionals working shifts in many public and private facilities, with contracts coming from public tenders, the group's own facilities and affiliated centres. Until 2025 it used a Yii2 portal on PHP 7, with a private area for doctors and a back office, alongside Excel sheets for the numbers.
The problem
Each contract has different rates per time slot, shift or service, rates change over time and some contracts are extended several times. Some doctors have their own terms, others are paid a monthly fee instead of per shift. Working out cost and margin of every shift by hand was slow and error-prone, and the old portal ran on an unsupported PHP version, with passwords stored in an outdated format.
What we did
- 01
The professional as a process
Each professional moves through six explicit states: registered, profiled, eligible, active, suspended (recoverable), suspended (not recoverable). The move to profiled happens on its own once the profile is complete and the CV uploaded. Specialisations, regions, languages, groups and notes are part of the record, and filters combine state, specialisation, facility, province and age.
- 02
A portal for doctors
Quick or full sign-up, with the tax code filling in birth date and town, an age check, a mandatory CV and separate privacy consents. Doctors update their details, upload documents even before they are eligible and, once active, see a calendar of past and upcoming shifts.
- 03
Documents with approval
Sixteen document types, one valid file per type: each upload waits until the back office approves or rejects it, and the previous version is archived automatically. The dashboard shows documents to review, recent sign-ups and active professionals without a signed contract.
- 04
Contracts, extensions and fractions
Each contract has its tender code, protocol number, starting bid, economic offer used as the budget and an internal owner. Extensions form a chain and the contract status is recomputed across the whole chain. Rates live in time fractions, each with hourly or per-shift cost and revenue, optional terms for a single doctor and a rate code numbered automatically.
- 05
Shifts that compute themselves
When a shift is saved, the system finds the fraction in force, preferring one dedicated to that doctor, and computes duration, cost, revenue, margin and the difference against the base rate. It blocks overlapping shifts for the same doctor and warns about adjacent ones. When a contract changes, a queue recomputes the shifts affected.
- 06
Calendar, reports and exports
The React calendar shows the month by facility and activity, with a live cost estimate, copy and paste, multi-select to approve or delete, notes and locked cells. It exports to landscape or portrait PDF on letterhead. Three report engines (flexible, month on month, contract budget) and Excel exports of every list give accounting the fees, costs, revenue and margins.
- 07
Migrating without stopping
During the transition a command synced professionals, regions, specialisations and documents from the old database, with a final check before switch-off. Old passwords are converted to a secure format at first login, without asking anyone to reset them. A Python script syncs unsubscribes from the newsletter platform every fifteen minutes, so people who opt out stop getting marketing messages.
How it went
Since 18 March 2025 all work runs through the new system. After the switch-off came monthly performance-based pay, professional groups and rate codes, without touching the foundations. An in-app what's-new panel tells users what has changed. We applied the same approach to a management system for a residential facility.
Tools
FAQ
Why not an off-the-shelf vertical product?
Because contracts with extensions, rate fractions and per-shift margin are the core of the client's business. A generic package would have forced them to change their model.
How do you migrate off an old system without stopping work?
With a period of coexistence: the new system reads and syncs data from the old one until every flow is verified, then the old one is switched off. Users log in with their usual credentials.
What happens if a rate changes halfway through a contract?
A new fraction is added from the date of the change. Shifts already worked keep the old rate, later ones use the new one, and the history stays available.