ClinicFlow
Appointment and follow-up management for small clinics still tracking return visits on paper.
Small clinics lose patients between visits, not through negligence: someone is told to come back in six weeks, it goes in a diary, and nobody reopens that page. Storing appointments is easy; making a commitment resurface on its own, on the right day, without anyone remembering to look, is the actual problem. The second was multi-tenancy. Several clinics share one deployment, and a bug that leaks one clinic's patients into another's dashboard is a data breach, not a display glitch.
Tenant isolation lives in the schema rather than the query layer. Each patient carries a UNIQUE (id, clinic_id) constraint, and appointments and follow-ups reference that pair through composite foreign keys, so Postgres rejects any row whose clinic_id disagrees with its patient's even if the application code is wrong. Query scoping is the second layer, and cross-clinic access returns 404 rather than 403 so the ID space cannot be probed. Auth uses httpOnly cookies behind a server-side proxy: the JWT is set by a Next.js route handler and never reaches client JavaScript, which costs a proxy layer and CSRF handling but means an XSS bug anywhere in the dependency tree cannot exfiltrate a session. Overdue state is derived per request from the follow-up date in the clinic's timezone, never stored, because a stored flag goes stale at midnight and needs a cron job to stay honest.
Shipped and deployed: Next.js on Vercel, Flask on Render, Postgres on Neon, with 99 backend tests covering authentication, validation and tenant isolation. The full workflow runs end to end in production, from registering a clinic to booking the visit after a completed follow-up. What I would change: the frontend has no automated tests, and two responsive layout bugs reached production before I caught them by resizing a browser, which is exactly what a component test would have caught first.




