Video summary

Golang Microservices Full Course #07 - Double-Entry Ledger System (Introduction)

Main summary

Key takeaways

Educational

Main ideas / lessons

  • Problem with relying only on “wallet” balance tables

    • If you only store balances (e.g., a wallet table) and the data is hacked or corrupted, you can’t reliably answer where the money came from.
    • In other words: you lose provenance / an audit trail.
  • Purpose of a double-entry ledger system

    • Record every money movement as ledger entries that are immutable:
      • Immutability goal: ledger entries should not be deleted or updated.
      • No update/delete rule: only insert new entries to represent transactions/mutations.
    • Ledger entries provide an accountable, auditable source of truth:
      • Credit when money comes in.
      • Debit when money comes out.
    • Ledger supports reconciliation:
      • Compare the computed ledger-derived balance vs. the stored wallet balance.
      • If they differ, treat it as inconsistent (e.g., illegal transaction, bug, or tampering).
  • Implementation approach shown

    • Introduce a Go module structure for the ledger:
      • model, repository, service (notably no handlers—aligned with the lesson that ledger shouldn’t allow mutation operations like update/delete).
    • Create database tables and repository functions to:
      • Insert ledger entries
      • Query ledger entries
      • Compute balance from ledger entries
    • Add a ledger service method that:
      • Retrieves wallet info
      • Calculates balance from ledger entries
      • Reconciles and returns:
        • wallet mutation history (ledger entries)
        • reconciliation consistency boolean and balances

Methodology / step-by-step instructions (as presented)

1) Project structure for ledger (Go)

  • Create directories/packages:
    • internal/ledger/model
    • internal/ledger/repository
    • internal/ledger/service
  • Implement:
    • Model representing a ledger entry.
    • Repository implementing DB interactions with transactions where needed.
    • Service orchestrating reconciliation and mutation history.

2) Ledger entry data model (key fields described)

Use a struct/table with fields roughly like:

  • ID (UUID)
  • WalletID (string; reference to wallet)
  • TransactionID (string; ties entries to a transaction)
  • EntryType (credit or debit; conceptually “credit plus / debit minus”)
  • Amount (floats discussed; later note mentions DB migration may use decimal)
  • CreatedAt (time.Time)

The example references MySQL usage (with “ledger” DB context mentioned in subtitles).

3) Ledger repository interface (functions)

Create a ledger_repository interface with methods including:

Insert ledger entry

  • Insert into ledger_entries with fields such as:
    • ID, WalletID, TransactionID, EntryType, Amount, CreatedAt
  • Emphasis: the ledger table should be appended to, not edited.

Get balance by wallet ID

  • Compute balance as:
    • Sum credits as +amount
    • Sum debits as -amount
  • Use SQL like:
    • SUM(CASE WHEN entry_type = 'credit' THEN amount ELSE -amount END)
  • Mentioned null-safety approach:
    • Use COALESCE(..., 0) to avoid null scan issues.

Get entries by wallet ID

  • Query ledger entries filtered by wallet_id
  • Return ordered results by created_at
  • Select fields:
    • ID, WalletID, TransactionID, EntryType, Amount, CreatedAt

4) Reconciliation logic (service layer)

Create a ledger service interface with functions including:

Wallet balance reconciliation

  • Steps described:
    1. Fetch wallet and its current balance (via wallet_repo.getByUserID / wallet repository usage).
    2. Calculate “ledger balance” by summing ledger entries for that wallet.
    3. Compare:
      • wallet_balance == ledger_calculated_balance
    4. Return:
      • isConsistent boolean
      • walletBalance
      • ledgerBalance

Get mutation history

  • “Mutation history” is the list of ledger entries for the user’s wallet:
    • getEntriesByWalletID(walletID)

5) Database NULL-handling detail

  • If the ledger entries table has no records for a wallet:
    • SQL SUM(...) can return NULL
  • Use COALESCE so the sum becomes 0
  • This prevents errors when scanning into Go numeric variables.

6) Git workflow shown (course workflow)

  • Commit and push changes to a feature branch:
    • feature 007 ledger system
  • Push origin for that branch
  • Create/merge a pull request into master
  • Delete the feature branch after merge
  • Verify with:
    • go run cmd/main.go (ensuring no runtime errors)

Speakers / sources featured

  • Speaker: The course instructor (unnamed in the subtitles; leading “Hello back to this course …” and providing step-by-step implementation guidance).
  • Referenced systems/technologies (not direct speakers):
    • MySQL (used in the example)
    • CockroachDB, Google Cloud Spanner, YugabyteDB (mentioned as ledger-related DB options)
    • Tiger Beetle, Amazon DQL DB (mentioned)
    • “Generic ledger database” concepts (immutability, cryptographic verifiability, transparency)
    • SQL concepts: SUM, CASE WHEN, COALESCE for null handling

Rate this summary

Your feedback will help improve summaries.

Improve this summary

Reprocess with a stronger model when the summary feels incomplete or inaccurate.

Pro

Translate summary in another language

Pro

Ask questions to this video

Chat for follow-up questions, clarifications, and source-backed answers.

Coming soon

Share this summary

Original video