Client Project
Hereafter Ghana DMS: Donor Management & Fundraising Platform
Donor management and fundraising system for a nonprofit: one-time and recurring giving, in-kind inventory, campaigns, madrasa sponsorship, bulk SMS/email, and a permission-gated admin dashboard.

Overview
The Hereafter Ghana DMS is the donor and fundraising backbone that sits alongside the organisation's public website. It is a full-stack system I built end to end: a TypeScript + Express REST API and a Next.js 16 / React 19 application that serves two audiences from one codebase - a permission-gated admin dashboard for staff and a public giving portal for supporters. It owns everything to do with giving: donor records and verification, one-time and recurring donations, in-kind donations with inventory, fundraising campaigns and health cases, a madrasa student-sponsorship programme, bulk SMS and email messaging, spreadsheet imports of mobile-money statements, and the reporting and analytics that run the back office.
The Problem
The nonprofit was tracking donors and donations across spreadsheets and disconnected tools. There was no reliable way to accept both one-time and recurring mobile-money giving, reconcile payments automatically, keep an inventory of in-kind donations, message thousands of donors without falling foul of SMS costs and delivery failures, or produce trustworthy reports. Sensitive donor data and financial records also needed real access control: different staff should see and do different things, deletions should be recoverable, and payment handling had to be tamper-resistant.
The Solution
I designed the DMS as a strictly layered Express API (routes to controllers to factory services to Prisma) with a Next.js dashboard on top. Payments run through Paystack for one-time giving and Hubtel for recurring mobile-money subscriptions, both reconciled by signature-verified webhooks and auto-charge sweeps. Long-running work is offloaded to seven BullMQ (Redis) background workers: SMS/email dispatch with per-recipient delivery logging and suppression lists, Excel statement/donor imports keyed on phone number, subscription charging, async data exports, and scheduled donor-recognition and giving-reminder jobs. Access control is a core feature, not an afterthought: JWT auth with refresh tokens and optional email-OTP two-factor, a SUPER_ADMIN/ADMIN/STAFF role model, and a runtime role-to-permission matrix that super-admins edit without code changes. Every record uses soft delete with restore/purge. Donor phone numbers are E.164-normalised, message bodies are GSM-7 sanitised to stay single-segment, and an admin-managed mobile-money allow-list blocks any send containing an unknown MoMo number. Optional Google Gemini integration drafts message copy and writes plain-language, PII-free report summaries, and is feature-flagged so the system runs fine without it. The frontend uses RTK Query with a mutex-guarded silent token refresh, TanStack Table, Recharts, and permission gating that mirrors the backend RBAC.