The job
In 2025 I took on a freelance project for Aliman Bulus Boarding School. The school tracked student tuition and fees in paper books. They wanted a finance system instead: one place to record payments, run a monthly ledger audit and produce reports for several admin levels.
The records had to cover hundreds of students and keep history across years. Invoices had to come out of that history. And when several payments were posted at the same time, every one of them had to land on the balance correctly.
What I built
I worked across the whole stack. Before building any screens, I wrote the UI specifications. Then I built the Next.js frontend and a Node.js backend on PostgreSQL, using Prisma, Tailwind CSS and Docker.
The core is a double-entry ledger for student payments. I designed a normalized schema so the school could keep financial history over many years and generate invoices from it. On top of that sit role-based dashboards for treasurers, where each role sees only the data it is allowed to see. Each admin tier gets its own report, and staff can search and filter the ledger data.
The part I was most careful with was posting payments. Two payments for the same student can arrive at once, and a naive update can overwrite one of them. I wrapped each posting in an atomic database transaction with a pessimistic write lock. Balances are not overwritten, so the ledger and the audit reports stay consistent across semesters. I also tuned the SQL indexes for the ledger queries, which brought response times under 10ms.
How it went
More than 500 students are now tracked on the ledger instead of paper books. Treasurers reconcile it each month without the old books, and the finance team spends less time balancing numbers by hand. The school's CEO noted that it was delivered on time.
What I took away: with money records, I plan for concurrent writes from the start, because a race in a balance update is easy to miss in testing. And writing the UI spec first helped me keep to a short freelance timeline.
