Case study

Online Paluwagan

A demo rotating-savings group with a reconciling ledger, fair payout rotation, and payment reminder drafts a human approves before anything is sent.

Proves Fintech and the Philippine market

Live demoCode

Problem

A paluwagan is a Filipino savings circle. Members pay a fixed amount each cycle, and one member takes the whole pot, until everyone has been paid once.

Most groups run on a chat thread and the organiser's memory. When someone pays late or misses a cycle, nobody is sure who is owed what. Disputes follow, and they are about friends and money at once.

Software for this has to be right about money first. A friendly reminder tool on top of wrong numbers makes the dispute worse.

Approach

I built the money rules as pure functions first and the screens second. The UI never does money math. It calls domain functions that the tests cover, and the store saves the result.

The ledger is append-only. A mistake is fixed with a reversing entry and a reason. When a member misses or underpays, the shortfall is recorded on the entry, the recipient's payout is short by the same amount, and the member owes it as arrears.

On top of that sit rule-based risk flags with their reasons shown, and reminder drafts in English and Filipino. A person edits and approves each draft before it can be sent, and sending is simulated. Everything stays in the browser. It is a portfolio demo, not a financial service.

Architecture

Online Paluwagan architecture The React UI calls an external store. Seed data feeds the store. The store reads and writes localStorage, with an in-memory fallback. The store calls the pure domain modules: ledger, rotation, risk, reminders, and money and dates. React UI no money math seed.ts two demo groups Store src/data/store.ts localStorage or in-memory Pure domain modules covered by the tests ledger.ts rotation.ts risk.ts reminders.ts money.ts dates.ts
No backend and no network call. Redrawn from the diagram in the project README.

Decisions

Results

  • 53 testsVitest, 6 files, all passing: ledger, rotation fairness, risk levels, reminder templates, seed data and currency formatting.
  • 12,000 operationsThe ledger property test runs 40 seeds of 300 random operations across contributions, payouts, arrears payments and reversals. After every step it checks reconciliation, a non-negative pot, non-negative arrears and append-only behaviour.
  • 95 / 100 / 100 / 100Lighthouse mobile preset on vite preview: performance, accessibility, best practices, SEO.
  • 65.9 kBGzipped initial load: 61.2 kB JS, 4.1 kB CSS, 0.6 kB HTML. axe finds no WCAG 2.1 AA violations on any route in either theme.

Measured on one machine against a local build.

Screens

Contributions by cycle for cycle 4: members paid on time, paid late, or not recorded, with Record buttons.
Contributions for one cycle. Late and missing payments are visible at a glance.
The append-only ledger table with entry numbers, types, members, signed amounts and Reverse buttons.
The ledger. Entries are never edited. A mistake gets a reversing entry instead.
Risk cards for two members marked High risk, with reasons and an arrears-owed panel.
Risk flags with their reasons, and the arrears a short payout created.

What I'd do next