index · all work
17 · fintech

ConstruCredit

The platform a Colombian lender runs on, from the public site where a family applies to the panel where an advisor approves.

Year2026
Statuslive
RoleSole developer · client work
Built withTypeScript · Next.js · React · Node · PostgreSQL · +9
construcredit.com.coopen ↗
ConstruCredit preview

Preview. Click it to open the live app.

01Overview

ConstruCredit lends to families building their own homes in Colombia, one wall at a time. I build the software the whole business runs on.

There are two faces to it. The public site is where a family picks a credit line and applies. Behind it sits the panel the staff live in: applications, clients, payments, notifications, reports, administration and audit, each screen filtered to what that person's role may see.

Under both sits the part that has to be right. The amortization engine works over outstanding balance and the Colombian business calendar, so a payment landing on a holiday behaves the way the business says it should. The three packages that do the arithmetic are pinned at 100% line and function coverage, and the integration tests run against a real Postgres they refuse to touch unless its name marks it as the test one.

The schema is 36 tables across 61 versioned migrations, 56 of them shipped with the file that rolls them back. Site and panel deploy on Vercel, the API runs on Cloud Run, and a worker handles WhatsApp notifications and scheduled jobs.

Closed source, so this page links the live site instead of a repo.

02The problem

A lender running on spreadsheets and WhatsApp can survive a hundred clients. It cannot survive a thousand. The arithmetic drifts, nobody can say who approved what, and every question about a balance costs an afternoon.

03Highlights
  • **The arithmetic is pinned at 100%.** Coverage thresholds hold `dominio`, `dinero` and `calendario` at 100% lines and functions with `autoUpdate: false`, so the number never lowers itself to match a bad day. Last full run: 2,289 tests across 132 files, with `dominio` and `dinero` at 100% on lines, functions and branches.
  • **Pesos are exact.** `packages/dinero` models money as its own type, so rounding is a decision the code makes on purpose.
  • **Dates answer to the Colombian calendar.** `packages/calendario` carries the country's holidays, so due dates and late interest land where the business says they land.
  • **61 migrations, 56 with a reverse.** Most schema changes ship beside the file that undoes them, and the row-level security policies are versioned the same way.
  • **The panel is gated per role.** Two-factor login required for the administrator role, provisional passwords rotated on first use and enforced server-side, and navigation filtered to the signed-in role across all seven modules.
  • **The test database cannot be the real one.** The integration suite truncates tables, so it refuses to start unless the connection string names a test database. Four Vitest projects keep unit and integration runs from masking each other.
04By the numbers
36
tables
61
versioned migrations
2,289
tests passing
121
PRs merged in 19 days
4
apps · 8 shared packages
◆What's inside8 parts
  • webapp

    The public site where a family reads the three credit lines and applies.

  • panelapp

    The internal system the staff works in: applications, clients, payments, notifications, reports, administration and audit, filtered per role.

  • apiservice

    The HTTP layer over clients, credits, payments, parameters, users and authentication, running on Cloud Run.

  • workerworker

    Scheduled jobs and the WhatsApp notification lane.

  • dominiolibrary

    The calculation engine: amortization over outstanding balance, late interest, balances. No IO, and CI holds it at 100% coverage.

  • dinerolibrary

    Exact peso arithmetic as its own type, so rounding never happens by accident.

  • calendariolibrary

    The Colombian business calendar the due dates and late interest are computed against.

  • dblibrary

    Schema, versioned migrations with their reverse files, and the row-level security policies.

·Tags
fintechmicrocreditclient workmonorepoPostgreSQLrole-based access
Full tech stack 14
TypeScriptNext.jsReactNodePostgreSQLDrizzle ORMZodTurborepopnpmVitestTailwind CSSVercelGoogle Cloud RunWhatsApp notifications