FELIPE WINSCHFull Stack Developer
Back to projects

Backend · Domain modeling

OpenLedg

A .NET backend foundation for participant profiles, permissions and routing. Domain and PostgreSQL rules prepare for future integration with a financial ledger.

Work in progress

  • C#
  • .NET 10
  • ASP.NET Core
  • EF Core
  • PostgreSQL
  • Docker

My contribution

Felipe Winsch’s own project (felpzw): participant modeling, persistence, access restrictions, tests and architecture documentation. The reviewed public history attributes commits to felpzw.

Problem

How can individuals, companies and payment initiators follow different rules without mixing profile data with balances and ledger entries? An initiator must not receive a settlement account, including when a link is created directly through SQL.

Context and scope

The delivered scope is the OLGP foundation: domain, persistence, migration and local operation. Current endpoints expose service identification, /health/live and /health/ready. Registration endpoints and a payment journey are not available.

Architecture

Domain holds invariants without depending on EF Core. Application defines contracts; Infrastructure implements persistence with EF Core/Npgsql; Api wires dependencies and health checks in Kestrel.

PostgreSQL separates profiles, security metadata and routing into schemas. Account references use decimal text to preserve all 128 bits. Balances and ledger entries stay outside this model; the ILedgerAccountDirectory port does not yet have a TigerBeetle adapter.

  1. API / Kestrel · composition and health
  2. Infrastructure · EF Core / Npgsql
  3. PostgreSQL · profiles and routing
Implemented data-access path. Domain defines rules and Application defines contracts. TigerBeetle remains a future integration outside this flow.

Decisions and trade-offs

TPH stores participant types in one table and avoids inheritance joins. The trade-off is nullable subtype columns and CHECK migrations for new types. The ADR does not assume a performance benefit without measurement.

Composite foreign keys and CHECKs reinforce invariants outside the application. The API role can operate on profiles and routing, but has neither DDL privileges nor access to the security schema; bootstrap and migration use a separate role.

Separating the future ledger from profile data makes each store’s responsibility explicit. The trade-off is planning idempotency and reconciliation: no distributed transaction is implemented.

Tests and evidence

The inspected xUnit tests cover UUIDv4, initial compliance states, rejection of initiator accounts, UInt128 preservation, webhook configuration and layer dependencies.

The integration suite uses real PostgreSQL to check migrations, subtype persistence, unique idempotency keys, invalid links submitted through SQL and runtime-role privileges. This editorial review inspected test code; it did not run the .NET suite.

Limitations

Work in progress, without transfers, active authentication, DICT integration, real KYC/AML checks or webhook execution. CPF/CNPJ identifiers receive normalization and format checks, without registry or check-digit verification.

TigerBeetle is intended to own financial state and is included in the local environment, but the application does not query it yet. Readiness checks PostgreSQL, not payments or ledger availability. The local development replica does not represent a production cluster.

Explore the project

Start with the ADRs and participant model; compare SettlementRoute with the database-constraint tests. The links below pin the reviewed revision.

To explore locally, clone the repository and use the indicated revision. Docker with Compose v2+ is required, plus .NET SDK 10.0.300 or later in the 10.0 line for host-side tests. Copy .env.example to .env and configure local passwords before running the commands. The repository guide covers integration tests. No public demo has been verified.

./scripts/dev-up.sh
curl --fail http://localhost:8080/health/ready
dotnet tool restore
dotnet restore
dotnet build --no-restore
dotnet test tests/OpenLedg.Tests --no-build
./scripts/test-integration.sh
docker compose down

Sources checked on 2026-09-25 · Content v1 · Revision aca1e82.