sqlstore

package
v1.786.216 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

manager.go is the PER-TENANT selector over the treasury Store: it resolves each request to its OWN Hanzo Base (SQLite) file instead of a process-wide singleton, so one tenant's finance/ledger writes can NEVER appear in another tenant's reads. This is the storage side of the standing Hanzo rule — Postgres stays a supported option (Formance, one layer up), but every tenant's books run live on its own Base file.

TWO file classes, one opener:

  • the HOUSE ledger — the platform's OWN reserve fund (fund:reserve, revenue:*, payout:*): a SINGLE single-writer, overdraw-guarded file. It CANNOT be split per tenant (the reserve overdraw guard is one atomic balance), so it is one fixed file — the pre-existing {DataDir}/treasury.db, kept verbatim so live reserve capital is never orphaned by a path change.
  • a CUSTOMER ledger — one isolated file per tenant at {DataDir}/finance/{slug}.db, opened on first use and cached.

It CONSUMES the treasury's canonical Base opener (Open, over github.com/hanzoai/ sqlite — the ONE Hanzo Base driver) rather than importing ledgercore's per-tenant opener: that opener is a test-only helper deliberately kept unexported because it registers modernc's database/sql "sqlite" driver, which would COLLIDE with the hanzoai/sqlite registration this store already carries. ledgercore's own contract is "production callers supply their own *bun.DB to New" — which Open does — so the per-tenant file selection lives HERE, over Open, and the slug guard matches ledgercore's per-tenant guard exactly.

Package sqlstore is the Hanzo Base (HIP-0105 per-tenant SQLite) adapter for the ledger core: it implements ledger.Store + ledger.Tx over one SQLite file, and nothing more. It carries the storage concern the core deliberately does not — the SAME single-connection + WAL pattern every clients/* store uses (referrals, crm, prompts), so it is Base-compatible and drops into the unified binary unchanged.

It imports the core (ledger) and the one Hanzo SQLite driver — never cloud, zip, or IAM. When the core is lifted to hanzoai/finance this adapter travels with it as the default backend; the driver import is the only thing a different Base backend would swap.

Index

Constants

View Source
const HouseSlug = "house"

HouseSlug names the platform's OWN reserve/house ledger — the single (single-writer, overdraw-guarded) book behind every backed payout. It is RESERVED: tenantSlug routes a literal "house" tenant to a hashed slug, so a caller can never open the house fund by naming its org "house".

Variables

This section is empty.

Functions

This section is empty.

Types

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager opens and caches one *Store per tenant. It is safe for concurrent use. Each distinct tenant maps to a distinct file; the mapping is INJECTIVE (it never folds "acme" and "ACME" into one bucket — that would itself be a cross-tenant break) and can never traverse the path or collide with the reserved house file.

func NewManager

func NewManager(dataDir string) (*Manager, error)

NewManager roots the per-tenant treasury stores under dataDir: the house ledger at {dataDir}/treasury.db (preserved) and customer ledgers under {dataDir}/finance/. The finance dir (and thus dataDir) is created if absent.

func (*Manager) Close

func (m *Manager) Close() error

Close closes every open store (house + tenants). Idempotent; returns the first close error, if any.

func (*Manager) Get

func (m *Manager) Get(tenant string) (*Store, error)

Get resolves the caller's OWN per-tenant store from the validated tenant key. The tenant is turned into a safe, injective, path-guarded slug FIRST, so a caller can only ever open its own file — never another tenant's, never the house fund, never a path outside the finance dir.

func (*Manager) House

func (m *Manager) House() (*Store, error)

House opens (once, then cached) the platform's reserve/house ledger — the single file the ledger-of-record binds to.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is the SQLite-backed ledger persistence. ONE file holds the whole chart of accounts, journal and policy for a deployment (the platform's own books — not per-org, unlike a tenant product store). Serialized on a single connection so the engine's balance-guard read-then-write is atomic under load.

func Open

func Open(path string) (*Store, error)

Open opens (creating + migrating) the ledger database at path.

func (*Store) Balance

func (s *Store) Balance(ctx context.Context, account string) (int64, error)

func (*Store) BalancesWithPrefix

func (s *Store) BalancesWithPrefix(ctx context.Context, prefix string) (map[string]int64, error)

func (*Store) Close

func (s *Store) Close() error

Close closes the underlying database.

func (*Store) Entries

func (s *Store) Entries(ctx context.Context, limit int) ([]ledger.Entry, error)

func (*Store) Policy

func (s *Store) Policy(ctx context.Context) (ledger.Policy, error)

func (*Store) SetPolicy

func (s *Store) SetPolicy(ctx context.Context, p ledger.Policy) error

func (*Store) Tx

func (s *Store) Tx(ctx context.Context, fn func(ledger.Tx) error) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL