# blnkfinance/blnk architecture

> Architecture diagram of the GitHub repository blnkfinance/blnk, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/blnkfinance/blnk
- Repository: https://github.com/blnkfinance/blnk

## Overview

1. **What this repository is**
   - Blnk is a Go-based financial ledger system, not just a library: it exposes an HTTP API, persists ledger state, and runs background workers for transaction processing, reconciliation, search indexing, and webhooks.
   - The core business model is double-entry accounting with accounts, balances, ledgers, identities, API keys, transactions, and lineage/audit records.

2. **Top-level runtime shape**
   - The main executable paths live under `cmd/`: `server.go` starts the API server, `workers.go` starts async processors, `migrate.go` applies schema changes, and `verify_chain.go` checks integrity.
   - This is effectively a multi-process Go service: one HTTP-facing component and one or more worker components sharing the same database and queue infrastructure.

3. **HTTP API boundary**
   - The `api/` package is the external contract surface. It contains handlers for accounts, balances, ledgers, transactions, identities, API keys, reconciliation, search, metadata, admin functions, and hooks.
   - `api/middleware/` enforces request auth, scope checks, metrics/security concerns, and request sizing before handlers reach domain logic.
   - The API layer maps requests to internal models and database operations, and returns structured API errors from `internal/apierror`.

4. **Domain and business objects**
   - Root-level files like `account.go`, `balance.go`, `ledger.go`, `transaction.go`, `identity.go`, `lineage.go`, `reconciliation.go`, `webhooks.go`, and `queue.go` represent the core business workflows.
   - The `model/` and `api/model/` directories hold shared domain/schema representations and API DTOs, separating transport shapes from storage-oriented forms.

5. **Persistence layer**
   - `database/` is the Postgres-backed repository layer. It contains repository methods and query helpers for accounts, balances, ledgers, identities, API keys, transactions, reconciliation, lineage, and queue state.
   - SQL migrations live in `sql/`, and `cmd/migrate.go` suggests schema evolution is first-class and bundled with the service.
   - The repository pattern is strong here: API and business logic depend on repository interfaces, with tests and mocks under `database/mocks/`.

6. **Transaction processing and ledger integrity**
   - Transaction flow is more than a single insert: files such as `transaction_execution.go`, `transaction_queue.go`, `transaction_inflight.go`, `transaction_bulk.go`, `transaction_refunds.go`, and `transaction_rejection.go` show multiple lifecycle states.
   - `lineage_*` and `chain_worker.go` indicate an audit/immutability layer that tracks transaction lineage and likely maintains ordered processing or hash-chain style integrity.
   - The system supports inflight transactions, recovery, batch processing, coalescing, scheduled work, and bulk operations, which makes the worker pipeline part of correctness, not just performance.

7. **Asynchronous subsystems**
   - `queue.go`, `queue_recovery.go`, `lineage_worker.go`, and `chain_worker.go` point to background processing driven by durable queue state.
   - `internal/notification/` and `webhooks.go` show outbound event delivery as an async concern.
   - The presence of recovery components suggests the system is designed to rehydrate or replay unfinished financial workflows after failure.

8. **Search and indexing**
   - `internal/search/` and `search.go`/`api/search_api_test.go` show a dedicated search subsystem, with `infrastructure/k8s-manifests/typesense-*` indicating Typesense as the search backend.
   - `internal/search/reindex.go` implies ledger data is indexed asynchronously rather than queried directly from Postgres for search-heavy use cases.

9. **Identity and tokenization**
   - Identity management is a first-class subsystem: identities are stored, queried, and linked to balances/transactions.
   - `internal/tokenization/` suggests PII tokenization is built into the platform, likely to support safer handling of sensitive identity data without exposing raw values broadly through the API or search layers.

10. **Reconciliation**
   - `reconciliation.go`, `database/reconciliation.go`, and reconciliation-focused tests show a subsystem for matching internal ledger records against external statements or provider feeds.
   - This is a separate domain workflow from transaction posting: it consumes ledger data and matching rules to produce reconciliation results and status.

11. **Infrastructure and external dependencies**
   - The Kubernetes manifests in `infrastructure/k8s-manifests/` define separate deployments for server, worker, Postgres, Redis, Typesense, Prometheus, and Jaeger.
   - This makes the intended production topology explicit: Postgres is the system of record, Redis supports queue/cache behavior, Typesense supports search, Prometheus handles metrics, and Jaeger handles tracing.
   - `docker-compose.yaml` and `docker-compose.dev.yaml` support local stack bring-up with the same service boundaries.

12. **Observability and operational tooling**
   - `internal/metrics/`, `internal/traces/`, and `docs/metrics.md` show built-in metrics and OpenTelemetry tracing support.
   - `internal/monitoringexporter/` suggests logs/telemetry may be exported with redaction, which matters for financial data safety.
   - Tests around logging, metrics security, request size, and tracing indicate operational behavior is part of the contract.

13. **Request/data flow summary**
   - External client request enters `api/` → middleware authenticates/authorizes and validates → handlers invoke domain logic → domain uses `database/` repositories → Postgres persists the authoritative state.
   - For workflows that must continue after the request, work is enqueued or recovered by workers → workers update lineage/chain, dispatch notifications/webhooks, and trigger search reindexing or reconciliation.
   - The main architectural boundary is therefore synchronous API handling versus asynchronous ledger-processing and delivery pipelines.

14. **How to draw the architecture**
   - Model the system as a Go monolith split into: API edge, domain services, repository layer, and async workers.
   - Show Postgres as the primary datastore, Redis as queue/coordination support, Typesense as search, and external observability services as sidecars/infra dependencies.
   - Treat ledger integrity/lineage, reconciliation, and webhook delivery as distinct internal workflows rather than simple CRUD endpoints.

Main entry points: [`api/api.go`](https://github.com/blnkfinance/blnk/blob/main/api/api.go) (API), [`cmd/workers.go`](https://github.com/blnkfinance/blnk/blob/main/cmd/workers.go) (Workers), [`transaction_execution.go`](https://github.com/blnkfinance/blnk/blob/main/transaction_execution.go) (Transactions), [`database/repository.go`](https://github.com/blnkfinance/blnk/blob/main/database/repository.go) (Repository)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime"]
  node_cmd_server["Server<br/>http process<br/>[server.go]"]
  node_cmd_workers["Workers<br/>worker process<br/>[workers.go]"]
  node_cmd_migrate["Migrate<br/>schema tool<br/>[migrate.go]"]
end

subgraph group_edge["API Edge"]
  node_api_layer["API<br/>http boundary<br/>[api.go]"]
  node_api_middleware["Middleware<br/>request control<br/>[middleware.go]"]
  node_api_models["DTOs<br/>api schemas<br/>[model.go]"]
end

subgraph group_domain["Domain"]
  node_domain_accounts["Accounts<br/>ledger entity<br/>[account.go]"]
  node_domain_transactions["Transactions<br/>posting engine"]
  node_domain_lineage{{"Lineage<br/>audit chain<br/>[lineage.go]"}}
  node_domain_reconciliation["Reconciliation<br/>matching workflow<br/>[reconciliation.go]"]
  node_domain_search["Search<br/>indexing workflow<br/>[search.go]"]
  node_domain_webhooks["Webhooks<br/>delivery workflow<br/>[webhooks.go]"]
end

subgraph group_persistence["Persistence"]
  node_db_repo[("Repository<br/>postgres repo<br/>[repository.go]")]
  node_db_transactions[("Txn Store<br/>transaction store<br/>[transaction.go]")]
  node_db_lineage[("Lineage Store<br/>audit store<br/>[lineage.go]")]
  node_db_reconciliation[("Recon Store<br/>[reconciliation.go]")]
end

subgraph group_async["Async Workflows"]
  node_workers_queue["Queue<br/>[queue.go]"]
  node_workers_chain["Chain Worker<br/>integrity worker<br/>[chain_worker.go]"]
  node_workers_lineage["Lineage Worker<br/>audit worker<br/>[lineage_worker.go]"]
  node_workers_hooks["Hook Worker<br/>delivery worker<br/>[worker.go]"]
  node_workers_reindex["Reindexer<br/>index worker<br/>[reindex.go]"]
  node_workers_notify["Notifier<br/>event delivery<br/>[notification.go]"]
end

subgraph group_infra["Infra"]
  node_infra_postgres[("Postgres<br/>system of record")]
  node_infra_redis[("Redis<br/>coordination store")]
  node_infra_typesense[("Typesense<br/>search backend")]
  node_infra_obs["Observability<br/>metrics tracing"]
end

node_cmd_server -->|"serves"| node_api_layer
node_cmd_server -->|"uses"| node_db_repo
node_cmd_workers -->|"consumes"| node_workers_queue
node_cmd_workers -->|"runs"| node_workers_chain
node_cmd_workers -->|"runs"| node_workers_lineage
node_cmd_workers -->|"runs"| node_workers_hooks
node_cmd_workers -->|"runs"| node_workers_reindex
node_cmd_migrate -->|"migrates"| node_infra_postgres
node_api_layer -->|"guards"| node_api_middleware
node_api_layer -->|"maps to"| node_api_models
node_api_layer -->|"calls"| node_domain_accounts
node_api_layer -->|"calls"| node_domain_transactions
node_api_layer -->|"calls"| node_domain_reconciliation
node_api_layer -->|"calls"| node_domain_search
node_api_layer -->|"calls"| node_domain_webhooks
node_domain_accounts -->|"persists via"| node_db_repo
node_domain_transactions -->|"persists via"| node_db_transactions
node_domain_transactions -->|"enqueues"| node_workers_queue
node_domain_transactions -->|"records"| node_domain_lineage
node_domain_lineage -->|"persists via"| node_db_lineage
node_domain_reconciliation -->|"persists via"| node_db_reconciliation
node_domain_search -->|"triggers"| node_workers_reindex
node_domain_webhooks -->|"dispatches"| node_workers_hooks
node_workers_chain -->|"reads/writes"| node_db_lineage
node_workers_lineage -->|"reads/writes"| node_db_lineage
node_workers_hooks -->|"uses"| node_workers_notify
node_workers_reindex -->|"indexes to"| node_infra_typesense
node_db_repo -->|"backed by"| node_infra_postgres
node_workers_queue -->|"backed by"| node_infra_redis
node_api_layer -->|"emits"| node_infra_obs
node_cmd_workers -->|"emits"| node_infra_obs

click node_cmd_server "https://github.com/blnkfinance/blnk/blob/main/cmd/server.go"
click node_cmd_workers "https://github.com/blnkfinance/blnk/blob/main/cmd/workers.go"
click node_cmd_migrate "https://github.com/blnkfinance/blnk/blob/main/cmd/migrate.go"
click node_api_layer "https://github.com/blnkfinance/blnk/blob/main/api/api.go"
click node_api_middleware "https://github.com/blnkfinance/blnk/blob/main/api/middleware/middleware.go"
click node_api_models "https://github.com/blnkfinance/blnk/blob/main/api/model/model.go"
click node_domain_accounts "https://github.com/blnkfinance/blnk/blob/main/account.go"
click node_domain_transactions "https://github.com/blnkfinance/blnk/blob/main/transaction_execution.go"
click node_domain_lineage "https://github.com/blnkfinance/blnk/blob/main/lineage.go"
click node_domain_reconciliation "https://github.com/blnkfinance/blnk/blob/main/reconciliation.go"
click node_domain_search "https://github.com/blnkfinance/blnk/blob/main/search.go"
click node_domain_webhooks "https://github.com/blnkfinance/blnk/blob/main/webhooks.go"
click node_db_repo "https://github.com/blnkfinance/blnk/blob/main/database/repository.go"
click node_db_transactions "https://github.com/blnkfinance/blnk/blob/main/database/transaction.go"
click node_db_lineage "https://github.com/blnkfinance/blnk/blob/main/database/lineage.go"
click node_db_reconciliation "https://github.com/blnkfinance/blnk/blob/main/database/reconciliation.go"
click node_workers_queue "https://github.com/blnkfinance/blnk/blob/main/queue.go"
click node_workers_chain "https://github.com/blnkfinance/blnk/blob/main/chain_worker.go"
click node_workers_lineage "https://github.com/blnkfinance/blnk/blob/main/lineage_worker.go"
click node_workers_hooks "https://github.com/blnkfinance/blnk/blob/main/internal/hooks/worker.go"
click node_workers_reindex "https://github.com/blnkfinance/blnk/blob/main/internal/search/reindex.go"
click node_workers_notify "https://github.com/blnkfinance/blnk/blob/main/internal/notification/notification.go"
click node_infra_postgres "https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/postgres-statefulset.yaml"
click node_infra_redis "https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/redis-deployment.yaml"
click node_infra_typesense "https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/typesense-deployment.yaml"
click node_infra_obs "https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/prometheus-deployment.yaml"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cmd_server,node_cmd_workers,node_cmd_migrate toneBlue
class node_api_layer,node_api_middleware,node_api_models toneAmber
class node_domain_accounts,node_domain_transactions,node_domain_lineage,node_domain_reconciliation,node_domain_search,node_domain_webhooks toneMint
class node_db_repo,node_db_transactions,node_db_lineage,node_db_reconciliation toneRose
class node_workers_queue,node_workers_chain,node_workers_lineage,node_workers_hooks,node_workers_reindex,node_workers_notify toneIndigo
class node_infra_postgres,node_infra_redis,node_infra_typesense,node_infra_obs toneTeal
```

## Components

### Runtime

Executable entrypoints and process roles

- [Server](https://github.com/blnkfinance/blnk/blob/main/cmd/server.go): http process · Starts the API server process · `cmd/server.go`
- [Workers](https://github.com/blnkfinance/blnk/blob/main/cmd/workers.go): worker process · Starts background processors for ledger workflows · `cmd/workers.go`
- [Migrate](https://github.com/blnkfinance/blnk/blob/main/cmd/migrate.go): schema tool · Applies database schema changes · `cmd/migrate.go`

### API Edge

HTTP boundary and request handling

- [API](https://github.com/blnkfinance/blnk/blob/main/api/api.go): http boundary · External request surface for accounts, balances, ledgers, transactions, identities, search, reconciliation, hooks, and admin · `api/api.go`
- [Middleware](https://github.com/blnkfinance/blnk/blob/main/api/middleware/middleware.go): request control · Authentication, scopes, sizing, and metrics/security checks · `api/middleware/middleware.go`
- [DTOs](https://github.com/blnkfinance/blnk/blob/main/api/model/model.go): api schemas · Transport models used by the HTTP layer · `api/model/model.go`

### Domain

Ledger business workflows and models

- [Accounts](https://github.com/blnkfinance/blnk/blob/main/account.go): ledger entity · Accounts, balances, ledgers, identities, API keys, and metadata · `account.go`
- [Transactions](https://github.com/blnkfinance/blnk/blob/main/transaction_execution.go): posting engine · Transaction execution, bulk processing, inflight handling, refunds, rejection, and batching · `transaction_execution.go`
- [Lineage](https://github.com/blnkfinance/blnk/blob/main/lineage.go): audit chain · Immutability, ordering, and audit lineage for ledger events · `lineage.go`
- [Reconciliation](https://github.com/blnkfinance/blnk/blob/main/reconciliation.go): matching workflow · Matches internal ledger records against external statements or feeds · `reconciliation.go`
- [Search](https://github.com/blnkfinance/blnk/blob/main/search.go): indexing workflow · Search and reindex orchestration for ledger data · `search.go`
- [Webhooks](https://github.com/blnkfinance/blnk/blob/main/webhooks.go): delivery workflow · Outbound event delivery and webhook processing · `webhooks.go`

### Persistence

Postgres repositories and schema

- [Repository](https://github.com/blnkfinance/blnk/blob/main/database/repository.go): postgres repo · Repository interfaces and query helpers for ledger entities and workflows · `database/repository.go`
- [Txn Store](https://github.com/blnkfinance/blnk/blob/main/database/transaction.go): transaction store · Queries and state for transaction queues, inflight state, recovery, grouping, and refunds · `database/transaction.go`
- [Lineage Store](https://github.com/blnkfinance/blnk/blob/main/database/lineage.go): audit store · Persistence for lineage, chain, and outbox records · `database/lineage.go`
- [Recon Store](https://github.com/blnkfinance/blnk/blob/main/database/reconciliation.go): recon store · Persistence for reconciliation jobs and results · `database/reconciliation.go`

### Async Workflows

Background processing and outbound delivery

- [Queue](https://github.com/blnkfinance/blnk/blob/main/queue.go): durable queue · Durable queue state, enqueue, and recovery · `queue.go`
- [Chain Worker](https://github.com/blnkfinance/blnk/blob/main/chain_worker.go): integrity worker · Background integrity and chain maintenance · `chain_worker.go`
- [Lineage Worker](https://github.com/blnkfinance/blnk/blob/main/lineage_worker.go): audit worker · Background lineage processing and recovery · `lineage_worker.go`
- [Hook Worker](https://github.com/blnkfinance/blnk/blob/main/internal/hooks/worker.go): delivery worker · Async webhook notification dispatch · `internal/hooks/worker.go`
- [Reindexer](https://github.com/blnkfinance/blnk/blob/main/internal/search/reindex.go): index worker · Async search indexing and reindexing · `internal/search/reindex.go`
- [Notifier](https://github.com/blnkfinance/blnk/blob/main/internal/notification/notification.go): event delivery · Notification fanout used by webhook and async workflows · `internal/notification/notification.go`

### Infra

Supporting services and deployment manifests

- [Postgres](https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/postgres-statefulset.yaml): system of record · Primary database for ledger state and workflow state · `infrastructure/k8s-manifests/postgres-statefulset.yaml`
- [Redis](https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/redis-deployment.yaml): coordination store · Queue and coordination support · `infrastructure/k8s-manifests/redis-deployment.yaml`
- [Typesense](https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/typesense-deployment.yaml): search backend · Dedicated search backend for indexed query use cases · `infrastructure/k8s-manifests/typesense-deployment.yaml`
- [Observability](https://github.com/blnkfinance/blnk/blob/main/infrastructure/k8s-manifests/prometheus-deployment.yaml): metrics tracing · Prometheus, Jaeger, and telemetry export support · `infrastructure/k8s-manifests/prometheus-deployment.yaml`

## Connections

- Server → API: serves · HTTP server exposes the API boundary
- Server → Repository: uses · Server handlers depend on repositories and DB access
- Workers → Queue: consumes · Workers process durable queue state
- Workers → Chain Worker: runs · Starts integrity maintenance worker
- Workers → Lineage Worker: runs · Starts lineage processing worker
- Workers → Hook Worker: runs · Starts webhook delivery worker
- Workers → Reindexer: runs · Starts search reindexing worker
- Migrate → Postgres: migrates · Applies schema changes to Postgres
- API → Middleware: guards · Requests pass through auth and policy middleware
- API → DTOs: maps to · Handlers translate between HTTP DTOs and domain shapes
- API → Accounts: calls · Account, balance, ledger, identity, and key operations
- API → Transactions: calls · Transaction posting and query operations
- API → Reconciliation: calls · Reconciliation endpoints drive matching workflows
- API → Search: calls · Search endpoints query or trigger indexing flows
- API → Webhooks: calls · Hook/admin endpoints manage outbound delivery
- Accounts → Repository: persists via · Domain state is stored through repository interfaces
- Transactions → Txn Store: persists via · Posting engine reads and writes transaction state
- Transactions → Queue: enqueues · Long-running or deferred transaction work is queued
- Transactions → Lineage: records · Transaction execution feeds audit lineage
- Lineage → Lineage Store: persists via · Lineage and chain records are stored durably
- Reconciliation → Recon Store: persists via · Reconciliation jobs and results are stored durably
- Search → Reindexer: triggers · Indexing is handled asynchronously
- Webhooks → Hook Worker: dispatches · Webhook delivery is delegated to async workers
- Chain Worker → Lineage Store: reads/writes · Integrity worker maintains chain and audit records
- Lineage Worker → Lineage Store: reads/writes · Lineage worker processes audit/outbox state
- Hook Worker → Notifier: uses · Webhook delivery relies on notification fanout
- Reindexer → Typesense: indexes to · Search documents are pushed into Typesense
- Repository → Postgres: backed by · Repositories use Postgres as system of record
- Queue → Redis: backed by · Queue/coordination state uses Redis support
- API → Observability: emits · API and middleware feed metrics and tracing
- Workers → Observability: emits · Workers are instrumented for metrics and tracing
