Back to all posts
System DesignBackendLearningSecurity

What I Learned While Building an SSU Management System

What I Learned While Building an SSU Management System
7 min read

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.

Live demo


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.