Core Concepts

  • Movements — directed flows of value from one account to another, not debit/credit legs
  • Batches — linked movements sharing a batch ID for compound transactions
  • Same-exponent rule — movements between accounts with different exponents are rejected (currency conversion must be explicit)
  • Integer amounts — stored as int64 in the smallest currency unit
  • Hierarchical accounts — Type:Product:AccountID:Address

.goluca Plain Text Format

# A dividend payment
2026-02-07 * Dividend payment
  Asset:Cash → Equity:Capital "Dividend" 200.00 GBP

# Linked payroll movements
2026-02-01 * Payroll
  +Income:Salary → Asset:Bank "net salary" 4000.00 GBP
  +Income:Salary → Expense:Tax "income tax" 1000.00 GBP

# Pending transaction
2026-03-01 ! Pending invoice
  Asset:Bank → Expense:Food 15.50 GBP

Import / Export

Read and write .goluca files with tree-sitter-powered parsing.

// Import
l.Import(file, nil)

// Export
l.Export(os.Stdout)

Balance Queries

Current, point-in-time, path-aggregated, and daily balances.

l.Balance(acctID)
l.BalanceAt(acctID, t)
l.BalanceByPath("Asset:", t)
l.DailyBalances(acctID, from, to)

Interest Engine

Daily interest accrual computed in-transaction with live balance projections.

l.RecordMovementWithProjections(
  from, to, amt, t, desc,
)

Documentation

DocumentDescription
READMEProject overview and chart of accounts
Plain text syntax.goluca format reference (arrow variants, linked movements, parameters)
Ledger interfaceInterface method groups, backend capabilities (SQL/Mem), bitemporal notes, future directions
QueriesEvery query's shape and cost in scale terms, the shapes chosen against, each reader's budget, and the measured figures
Database schemaTable definitions, columns, indexes, and ER diagrams (generated by tbls)
BenchmarksPerformance benchmarks and analysis
Balance typesBIGINT vs DOUBLE vs NUMERIC — sub-ms lookups at 36M rows
Compound movementsWrite-time projection: ~586 TPS, eliminates batch processing
SCVSingle Customer View generation and query optimisation
Ledger backendsMemLedger vs SQLLedger vs API — performance across backends
NumbersGo decimal/money library comparison for amount representation

Quick Start

go get github.com/drummonds/go-luca

import (
    "github.com/drummonds/go-luca"
    _ "git.bytestone.uk/hum3/go-postgres"
)

l, _ := luca.NewLedger(":memory:")
defer l.Close()

cash, _ := l.CreateAccount("Asset:Cash", "GBP", -2, 0)
bank, _ := l.CreateAccount("Asset:Bank", "GBP", -2, 0)
l.RecordMovement(cash.ID, bank.ID, 10000, time.Now(), "Transfer")

References