Ahexon
Accounting and point-of-sale for Australian small businesses, with about 2,700 automated tests.
- Context
- Australian small businesses juggle a till, a bookkeeper and the tax office. Ahexon puts double-entry bookkeeping, BAS and GST reporting, payroll tax, bank reconciliation and a point-of-sale system with a kitchen display in one web platform, linked to Xero, QuickBooks, MYOB and Square, with an Expo app that keeps selling offline.
- Role
- I designed the product and the data model and built it with AI coding agents: 73 pages, 50 API routes and 37 database migrations across 257 commits from May to October 2026, with about 2,700 automated tests over the tax and ledger logic.
- Stack
- Next.js 16, React 19 and TypeScript; Supabase (Postgres), Clerk, Stripe, Resend and Twilio; Vitest. The mobile point of sale is Expo with SQLite.
- Visit
- ahexon.com
The hard problem
Square money, ledger money
Square takes GST-inclusive card sales, refunds and fees, then pays a lump sum into the bank days later. Each of those has to land in a double-entry ledger balanced to the cent, with GST pulled out correctly for the BAS, and a sale must never post twice when a sync is re-run or dies halfway. I routed everything through a Square clearing account: a sale debits clearing and credits revenue and GST payable, a fee debits fees, a payout moves clearing to the bank, so clearing nets to zero when the money arrives. The journal lines come from pure functions with no database access. GST uses Square's own figure when it exists and the one-eleventh rule when it doesn't, and the net is the total minus the GST, so every entry balances by construction, and a balance check runs before anything is written. The sync only picks up rows without a ledger stamp, stamps them after posting, and deletes an orphaned journal if its lines fail. Fifty-two tests cover it. The next step is moving that guarantee into the database itself, with a unique constraint and a single transaction.