in production · v1.16
PlanOpé
Internal team management platform
Presence planning, clients, appointments, KPIs and SaaS licences. It is the tool the support team opens on Monday morning to know who is in this week.
The problem
Team tracking lived in a shared spreadsheet: three tabs, two versions, and the same Monday question: “who is in this week?”. Plans changed without anyone knowing, leave was requested by message, and clients were tracked somewhere else again.
It needed one place, readable on a phone, answering three questions without searching: where the team stands, who owns which client, and what changed since Friday.
What I decided
React for the interface, Express and PostgreSQL behind, Socket.IO for notifications. No heavy front framework and no global state: TanStack Query holds the server cache, local state stays local. Components come from Radix and shadcn for keyboard accessibility, not for the look.
Real time was not optional: a planning you have to refresh by hand is useless. Permissions fit in one sentence, everyone sees everything and only leads edit, and in practice nobody has had to ask who was allowed to do what.
Exports are treated as features: PDF and Excel for plannings and KPIs, because the first thing anyone asks of an internal tool is to get the table out.
What broke
The first notifications arrived twice. The symptom looked like a server bug; the cause was a Socket.IO subscription recreated on every render, with no cleanup. The rule since then: when an event arrives twice, look at who is listening first.
A more instructive break: the IndexedDB-persisted cache served pre-logout data to another user on the same machine. The fix was methodological: the cache key now contains the session id, and logout clears the cache before handing control back.
The guard rails
Sign-in uses passkeys (WebAuthn) and a second factor, with openpgp for what must be encrypted client-side. The front is a PWA: installable, and readable when the network drops, which happens in an open-plan office.
Tests cover critical API flows and UI components. Nothing exhaustive: the point is that a planning regression shows up before the team sees it, not after.
What I keep from it
The part that gets real care is the one people look at every day: the week table. The rest has to be correct and fast, nothing fancy. Six months after go-live, nobody has asked to switch tools.