Case study · SaaS / Freelance finance
DuesheetProposals, invoices and a client portal for freelancers who bill internationally
Duesheet is an invoicing web app built by DanixSoft for freelancers and small studios who bill clients abroad: it sends proposals clients accept online, issues invoices in eight currencies, gives each client a private portal, and records payments with the rupees that actually landed.
Proposals, multi-currency invoices, a client portal, server-generated PDFs, a payments ledger and reminders, for freelancers who get paid from abroad and need to know who still owes them.
What problem does Duesheet solve?
Freelancers billing international clients juggle invoices in Word or spreadsheets, lose track of what is outstanding in which currency, and cannot say how many rupees a dollar invoice actually brought in after fees and rates.
How does Duesheet work?
Every document is written through database functions that compute the totals and allocate gap-free numbers only when an invoice is sent. Payments are an append-only ledger that records what landed in PKR, so the effective rate is derived from real receipts rather than fetched, and each client reads only their own documents through a tokenised portal.
What we built
- Proposals the client accepts or declines online, with the name and time recorded, and one-click conversion to an invoice
- Invoices in eight currencies with line items, discount and tax, sequential numbering and CSV export
- A client portal and per-document links showing what is paid and owed, with PDFs
- Server-generated A4 PDFs for invoices and proposals
- Payments recorded with the PKR amount received, owner-only reversals, and a yearly ledger CSV
- Email reminders before, on and after the due date, with one-click unsubscribe, and recurring invoices
What is Duesheet built with?
- Application
- Next.js 16 (App Router, Server Actions), React 19, TypeScript, Tailwind CSS v4
- Data
- Supabase Postgres with row-level security and Auth
- Documents
- pdf-lib for server-side PDFs
- Quality
- Vitest unit tests and a database rules and isolation check script
Engineering challenges
- Money held as integer minor units per currency, with the same rounding in SQL and TypeScript and tests comparing the two
- Every table scoped to a workspace by row-level security, with column-level grants protecting totals, numbers and tokens
- Client links use random 96-bit tokens and return only that client's documents
- A database check script covering isolation, portal scope, ledger immutability and numbering


