← Blog
Case study Migration & Security

Rebuilding the appointment portal, with people already in line

by Team P3·27 September 2026·7 min read

When a citizen has to transfer a contract or bring a document, they book an appointment at the counter of the company supplying their water, gas or energy. The portal is the shared calendar of operators and the client's staff: over a hundred thousand appointments since 2020, always with slots already set for the coming weeks. There was no moment to 'switch off and on'.

01The starting point

The old portal worked, but surprises abounded: the availability rules (hours, capacity, hundreds of exceptions and holidays) lived in compiled programs whose source no longer existed — we rebuilt them by reading the database queries left inside. One rule was even in the web page code. The SMS notifications queried tables that no longer existed: they'd been dead for a while and no one had noticed. And the appointment didn't record which company it was for, a datum simply missing on shared counters.

02The choices

A new application, not a refit. Written in Python with a mature open-source framework, on a cloud machine in an Italian region, registered to the client and administered by us: the infrastructure is theirs, we run it. The client is a line of configuration: adding a company no longer needs a release. Strict separation: on shared counters, the other company's appointments don't exist for the operator, not in the calendar nor in search.

Design is measured. Even colors: the logo's 'pure' colors failed the contrast test for people who struggle to tell them apart, and were corrected on a measured basis, not by eye.

03The migration: with people already in line

The switch happened counter by counter, with explicit authorization for each. Over twenty-seven thousand past and future appointments were migrated, repeatably (each row remembers its origin, no duplicates) and silently (no confirmation emails sent for appointments from years back). For a few days the two portals ran in parallel, with a probe every half hour bringing across appointments booked on the old one; then a notice, finally the old one read-only. Where a datum wasn't there, we didn't invent it.

04Security, verified from outside

A portal on the internet must be checked as an outsider would. The review found one serious problem: no limit on login attempts. Closed the same day, applied only to the login page. The rest was in order: modern encryption, security headers, database reachable only from the machine itself, admin access from a single address. And the data isn't only in the cloud: every night a full copy comes down to an on-site server.

05What we learned

1. When the rules are in lost code, the data still tells the truth. 2. You don't invent missing data: better an empty, declared field than a plausible false value. 3. Migrations are done with people inside: parallel, probe, notice, read-only. Never a leap in the dark. 4. Security is verified from outside, and automated checks must themselves be checked.

[P3]
Team P3
Technical boutique · EU-hosted
P3 team notes on compliance and sovereignty, written by the people who apply them for European SMEs. Write to us →
Got a NIS2 deadline?

Start from the snapshot of your network.

[ Book Munin ]