Feb 2026 – present · Posted

OneFinOps — purchases, sales, banking, accounting

I work across the finance side of the product: the procure-to-pay service that takes a purchase order through goods receipt, supplier bill, matching, withholding tax and payment; the sales, banking and accounting modules around it; and the React screens that drive them. The hard part is that every write moves money. A double-click, a retried request or two workers settling the same bill must never pay or post twice, and every undo has to reverse exactly what its original created in the ledger.

Software Developer · OneFinOps · intern Feb – Jul 2026, full-time since

224Feature PRs merged
55System reports
5Integrations shipped
FolioC# · .NET · TypeScript · React · SQL Server · Kubernetes · Terraform
Exhibit A · Three-way match · Bill SB-0117Illustration · sample data
PO-0417GRN-0093SB-0117
LineItemPORcvdBilledStatus
01Steel brackets, 40 mm242424MATCHED
02Cable trays, 2 m121012MISMATCH
03Installation, site B111MATCHED

Line 02 billed 12 against 10 received. Payment is blocked until someone authorised accepts the variance.

As posted

Detect · decide · act
01 · Detects

A supplier bill whose lines disagree with the purchase order or the goods receipt — a unit price outside tolerance, a quantity beyond what was received or already billed, a line that isn't on the order at all.

02 · Decides

Per line — matched, under-billed partial, or mismatch — then rolls the lines up to one verdict for the bill. The gate fails closed.

03 · Acts

Blocks submit and payment until an authorised person accepts the variance, and records who accepted it.

The hard part

Money that survives retries and races

A bill can be settled from four paths at once: a manual clearance, a payout-cleared event from the bank worker, a direct payment completion, and an import. Each loaded the bill, applied the payment, and wrote the whole row back — so two concurrent settlements both read the same paid amount, both passed the over-payment check, and the second write silently erased the first, under-stating what was paid and risking a duplicate ledger posting.

The fix was a compare-and-set: a targeted update of paid amount, balance and status that only succeeds if the paid amount is still what was read, with every settle path routed through one helper that reads, applies, compare-and-sets, and reloads-and-retries on a lost race. All four paths had to move together, or a straggler would clobber the guarded value.

The same principle runs through the rest of the module: document numbers are minted inside the transaction so a failed create never burns one, and each idempotency key is scoped to its purpose and recorded in the same transaction as the work — so a rollback takes both, and a retried “hold” can never answer for a “release”.

Found while testing against a clean organisation — not in a customer's books.

Also on this entry

SalesThe order-to-cash side — customer invoices, receipts and credit notes, and the receivables they post to the ledger.
AccountingGL auto-posting from payables and receivables events, base-currency journals with realised FX gain and loss, books locking and year-end close.
GST & complianceGSTR-1 and 3B population with pre-file validation gates, 2B reconciliation, e-invoice IRN on finalise and e-way bills.
BankingBank statement import, matching to bills and invoices, categorise-to-GL, reconciliation sessions.
Office of the CFOA 55-report catalogue with scheduling and charted PDF exports; planning from annual operating plan to budget, forecasts and scenarios.
PlatformGitOps on Kubernetes, infrastructure as code, CI pipelines for ~30 services in one release wave.

Correspondence

Lands in my inbox · or email praveenreddygoli8@gmail.com