Senior .NET backend engineer
APIs, event-driven systems, legacy modernisation
C# · .NET · Azure · SQL Server
I'm a senior .NET backend engineer in Lisbon. I've spent more than twelve years building APIs, event-driven services and migrations of old systems onto current .NET, most of it for banks.
This year I'm building open-source projects in public, starting with an event-sourced ledger and a name matcher. When something in them takes more thought than expected, I write it up here.
-
Snapshots in an event-sourced ledger are a cacheledger-core
ledger-core takes a snapshot of an account every 100 events. Treating it as a cache decided when it is taken, how it is stored, and what happens when it fails.
-
An event store on PostgreSQL: why appends take a lockledger-core
Identity values are handed out at insert time, not at commit, so a reader that follows the global position can skip an event for good. Here is how my ledger's event store avoids that, and what it costs.
-
Normalising payee names: where NFKD stopspayee-match
NFKD removes most accents from a name before fuzzy matching. It does nothing for ß, ø or ł, so those need a small table, and dots and apostrophes need their own rules.
-
Why 0.05 × 0.5 is 0.02 in my ledgerledger-core
decimal.Round uses banker's rounding by default. How ledger-core uses it, and why amounts with too many decimals are rejected instead of rounded.