What I Learned While Building an SSU Management System

Lessons learned while building a real-world SSU management system — from patient workflows and fiscal tracking to access control and data integrity.
I didn’t start this project thinking it would teach me much. I thought it was “just” another management system.
I was wrong.
Building the SSU Management System forced me to confront real-world constraints: messy data, strict rules, local fiscal calendars, and the uncomfortable reality that business logic is harder than infrastructure.
This post is about what I learned while building, not what I shipped.
Lesson 1: Business Logic Is the Real Core of the System
At first, I focused too much on routes, schemas, and UI. The system only became stable once I treated business rules as first‑class citizens.
Patient Management Was Not “Simple CRUD”
Patients weren’t just rows in a table. They belonged to SSU categories, each with real policy implications:
- Poor
- Destitute
- Disabled
- Senior Citizen
- GBV Victim
- Others defined by regulation
Each patient required:
- Demographic details
- Hospital-issued identifiers
- Ward / Municipality mapping
What I learned:
If you don’t model the business reality accurately, your system will eventually lie — even if the code is “correct.”
Lesson 2: Visit Tracking Exposes Hidden Complexity
Recording patient visits looked easy until diagnosis and treatment history entered the picture.
A visit needed to answer:
- Why did the patient come?
- What diagnosis was made?
- What treatment or support was provided?
- Was financial assistance involved?
Over time, I realized visits are append-only historical facts, not editable records.
What I learned:
Some data should never be mutable. History is more valuable than convenience.
Lesson 3: Financial Tracking Forces Discipline
Money changes everything.
The system needed to track:
- SSU budgets per fiscal year
- Support expenses (transport, equipment, medical aid)
- Exact linkage between patients, visits, and fiscal periods
Budgets were not global — they reset per fiscal year, which introduced edge cases I didn’t anticipate early.
What I learned:
Financial data forces you to design with precision. Ambiguity becomes a bug very quickly.
Lesson 4: Local Calendars Break Assumptions
The system couldn’t rely on standard Gregorian dates.
Local reporting and budgeting depended on Nepali fiscal years, so I integrated a Nepali date converter to ensure correctness.
This affected:
- Budget calculations
- Reporting ranges
- Validation logic
What I learned:
Time is not universal. If your system ignores local context, it will fail silently.
Lesson 5: “Modern Stack” Choices Have Tradeoffs
I used a modern setup, but reality mattered more than hype.
Stack Choices
- Framework: Next.js 16 (App Router) running on Bun
- Database: Serverless Postgres (provider anonymized 😄) with Drizzle ORM
- Authentication: Custom auth built on Better-Auth (sessions, accounts, invitations)
- Styling: Tailwind CSS v4 with Shadcn/Radix UI
What I learned:
Tooling doesn’t save you from bad decisions — it only makes good ones faster.
Lesson 6: Rate Limiting Is About Trust, Not Traffic
I didn’t need distributed rate limiting.
Login and signup needed simple protection against brute force, so I used in‑memory rate limiting instead of external infrastructure.
What I learned:
Solve the problem you actually have. Overengineering security can be as harmful as ignoring it.
Lesson 7: Roles and Invitations Are Security Boundaries
The system had clear separation:
- Admins manage budgets, approvals, and staff
- Users handle patient data and visits
Staff onboarding worked through an invitation system, not open registration.
What I learned:
Access control isn’t a feature — it’s a boundary. Treat it like one.
Lesson 8: Data Integrity Belongs in the Database
One decision paid off immediately.
When a patient was deleted, their:
- Visits
- Expenses
- Linked records
were automatically removed using cascading deletes at the schema level.
What I learned:
If data integrity depends on application code, it will eventually fail.
Databases exist to enforce rules. Let them.
Final Reflection
This project changed how I think about backend systems.
I stopped asking:
“Does it work?”
and started asking:
“Can this system be trusted six months from now?”
The biggest lesson was simple:
Real systems are defined by constraints, not features.
Everything I learned came from respecting those constraints instead of fighting them.