<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jonatan Gall</title>
    <description>The latest articles on DEV Community by Jonatan Gall (@jonatansouza).</description>
    <link>https://dev.to/jonatansouza</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F159900%2Fe329c7e7-c0df-4ae5-b7e0-fa7694ff0fc7.jpeg</url>
      <title>DEV Community: Jonatan Gall</title>
      <link>https://dev.to/jonatansouza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonatansouza"/>
    <language>en</language>
    <item>
      <title>The Immutable Ledger: Data Integrity Through TypeScript &amp; Design Patterns</title>
      <dc:creator>Jonatan Gall</dc:creator>
      <pubDate>Tue, 10 Feb 2026 03:04:41 +0000</pubDate>
      <link>https://dev.to/jonatansouza/the-immutable-ledger-data-integrity-through-typescript-design-patterns-4749</link>
      <guid>https://dev.to/jonatansouza/the-immutable-ledger-data-integrity-through-typescript-design-patterns-4749</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;In robust financial architectures, the integrity of a system does not rely on the current state of a database row (e.g., &lt;code&gt;UPDATE accounts SET balance = 50&lt;/code&gt;), but rather on the derivation of its entire history.&lt;/p&gt;

&lt;p&gt;This article explores the &lt;strong&gt;Ledger Pattern&lt;/strong&gt; as a foundational primitive for reliable systems. We will examine a simplified TypeScript implementation that demonstrates &lt;strong&gt;Event Sourcing&lt;/strong&gt;, &lt;strong&gt;Immutability&lt;/strong&gt;, and the &lt;strong&gt;Builder Pattern&lt;/strong&gt; for testing—concepts that serve as the architectural ancestor of Blockchain technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concept:
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;If you store the Balance, you have to trust the database update. If you store the Ledger, you can prove the math.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I created a minimal TypeScript example to show how a Per-Customer Ledger works, the core concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One Ledger per Customer: A linear, append-only history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Zero Mutations: We never edit a transaction. We only add new lines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Derived State: The current balance is simply the sum of the history.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Problem: Mutable State in Finance
&lt;/h2&gt;

&lt;p&gt;In a standard CRUD application, updating a balance destroys the previous state. If a database write fails or a malicious actor modifies the value, the history is lost. This is often referred to as the "destructive update" problem.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Ledger&lt;/strong&gt;, by contrast, is an append-only log of events. The "current balance" is never stored; it is calculated deterministically by reducing the history of all transactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Implementation
&lt;/h2&gt;

&lt;p&gt;Presented below is a simple implementation designed to demonstrate the core mechanics of the Ledger pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Immutable Ledger
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnqx53oq7v2u1szy3s4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnqx53oq7v2u1szy3s4s.png" alt=" " width="800" height="753"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;State Derivation &amp;amp; Immutability:&lt;br&gt;
The &lt;code&gt;getBalance()&lt;/code&gt; method does not retrieve a stored variable; it calculates the state deterministically by reducing the transaction history. As shown in the test suite, the history array is exposed only as a ReadonlyArray or a spread copy. This ensures that while the state can be computed, the history remains tamper-proof a critical requirement for auditability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Blockchain Premise&lt;br&gt;
This structure is the conceptual ancestor of Blockchain technology. While this implementation relies on language level encapsulation (&lt;code&gt;private&lt;/code&gt;) for security, a Blockchain extends this by adding cryptographic hashing (e.g., Merkle Trees) to link the entries. In a distributed ledger, the "history" becomes a chain of blocks where immutability is guaranteed by cryptography rather than memory scope. Note the use of &lt;code&gt;private&lt;/code&gt; history and the &lt;code&gt;readonly&lt;/code&gt; return type. This ensures that once an entry is recorded, it cannot be tampered with by external consumers. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Testing with the Builder Pattern
&lt;/h3&gt;

&lt;p&gt;To validate this logic without writing repetitive boilerplate code, we employ the Builder Pattern. This allows us to construct complex transactional scenarios using a fluent, expressive interface.&lt;/p&gt;

&lt;p&gt;Furthermore, this pattern significantly improves readability and maintainability. By abstracting the instantiation details, the test cases become self-documenting narratives that focus entirely on the business behavior being verified. This separation of concerns not only promotes code reuse across different test suites but also reduces the cognitive load for reviewers, making the system's intent immediately clear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft05dcxjun3uikct1i8e4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft05dcxjun3uikct1i8e4.png" alt=" " width="800" height="951"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Validation
&lt;/h3&gt;

&lt;p&gt;The test suite confirms two critical behaviors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Correct Derivation: The balance acts as a reduction of the history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Immutability: Attempts to modify the history array (a common attack vector) fail to impact the internal state.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgssrjmk2do3rkrx6ff1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgssrjmk2do3rkrx6ff1g.png" alt=" " width="800" height="912"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Production Considerations: The Path to Smart Contracts
&lt;/h3&gt;

&lt;p&gt;It is important to note that this implementation is a structural primitive designed for educational purposes. A production-grade financial system requires several additional layers of robustness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Concurrency Control: Handling race conditions when multiple transactions occur simultaneously (e.g., using Optimistic Concurrency Control).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Persistence: Storing the event log in a durable database (e.g., PostgreSQL or a distributed log like Kafka).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Business Logic Validation: Currently, our Ledger accepts any transaction. In a real banking scenario, we must enforce rules, such as preventing overdrafts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The "Smart Contract" Evolution: This missing validation layer is exactly where Smart Contracts enter the picture in the blockchain world.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;While simple, this pattern illustrates the difference between storing data and storing facts. Whether you are building a banking system or a distributed ledger, the principle remains the same: State is a function of history.&lt;/p&gt;

&lt;p&gt;As you scale this pattern, the 'Ledger' evolves from a simple class into a distributed log, and eventually, into the decentralized consensus mechanisms we see in modern blockchain networks.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>architecture</category>
      <category>blockchain</category>
      <category>designpatterns</category>
    </item>
  </channel>
</rss>
