Big morning. The compliance portal went from "the backend does everything" to "there's a real thing you can click on in a browser" in about three hours. Six changes, three topic areas. Here's how it went.
The backend becomes a kitchen, the browser becomes the waiter
The compliance portal used to work like a restaurant where the chef also delivers the food and sets the table. The Python server fetched the data and built the full page you'd see. That makes it really hard to build anything interactive.
So I split the job. The server now just sends back raw data — like handing someone a neatly organized grocery list instead of a finished meal. Eight routes got this treatment. Eight old page templates — about 600 lines — got deleted. I also fixed a sneaky bug where some web addresses were silently redirecting, which broke how login cookies worked. One-line fix, real consequence.
With the data layer in place, I built the actual browser side. The main dashboard now shows certifications (which ones the building has, which are pending), action items (things that need doing, with expandable detail panels), building facts (square footage, unit count, that kind of thing), and a banner if something went wrong in the compliance check. There's also a reference page with links to the government portals a building manager needs. If you're not logged in as an admin, you see a "please log in" screen instead of data.
Then came the translator. The backend knows what data looks like. The frontend was guessing. If I changed something on the server and forgot to update the browser code, things would silently break — or worse, show wrong information. So I set up a system that reads the server's full list of routes and data shapes, then automatically writes a file that tells the frontend exactly what to expect. Now if the two sides get out of sync, the build fails with a clear error instead of breaking quietly. There's even a guard that checks when you save — if the types are stale, it stops you. The portal has 39 operations now. Managing that connection by hand wasn't going to work.
The page that wouldn't stop loading
After all that building, the dashboard had a fun surprise: it would show a loading spinner and then... keep spinning. Forever.
The culprit was a timing issue. The page uses a JavaScript tool called Alpine.js to handle interactive pieces — forms, expandable rows, data panels. Alpine loads from someone else's server. The problem: by the time Alpine showed up and said "hey, where's the code I'm supposed to run?" — that code had already fired and gone. Like a missed phone call.
The fix was to put the instructions directly where Alpine could find them, no matter when it arrived. Four components fixed, dashboard working. Then I noticed the reference page had the exact same problem — showing up to a party before the host unlocks the door. Same fix, applied there too.
A backdoor for testing (the legal kind)
The portal requires an admin login to see anything. Good for the real site — nobody should waltz into the condo management dashboard uninvited. Annoying during development, where I'm reloading the page fifty times a day to check if things look right.
So I added a dev-mode bypass. When you're running the server on your own computer and flip a special flag, it pretends you're already logged in. The flag only works on localhost — even if someone left it on by accident, it wouldn't do anything on the live site.
PRs: