J. Castillo
Language

Work

Each one says what it is, how it is built and with what. The full argument — the alternative I rejected and what is not built yet — lives inside each project.

01

corebank

A complete digital bank: accounts, transfers between customers, transaction history, and an AI assistant you ask about your balances in plain language.

Architecture

A Go API between two stores: TigerBeetle holds the money and PostgreSQL holds everything else. There is no distributed transaction — the row uuid is the transfer id in the ledger.

Backend Go 1.26 · chi · pgxLedger TigerBeetle 0.17.9Data PostgreSQL 17 · gooseFrontend React 19 · Vite 6 · TanStack Query · Tailwind 4Assistant MCP · Anthropic SDK for GoInfrastructure Docker Compose · nginx · GitHub Actions

What I take away

An invariant that really matters is not defended with a check: it is defended by removing the possibility. There is no balance column, so it cannot fall out of sync; the model cannot confirm, so a prompt injection does not scale into a loss; the spend cap compares and increments in one statement, so there is no race to win. In all three the cost was losing a convenience.

corebank dashboard: the available balance, 32,354.53 dollars, with its composition bar and the caption that nothing is held, and on the right the assistant answering a question about how much money there is.

02

loklflow

A system for running a whole restaurant: order taking, kitchen display, floor plan, inventory, cash close-out and per-role permissions.

Architecture

The server — NestJS and PostgreSQL — runs inside the premises on a UPS, and the till, the waiters and the kitchen talk to it over the internal WiFi. The cloud only takes the remote dashboard and the backup.

Backend NestJS 11 · TypeORM · Socket.ioData PostgreSQL 16 · versioned migrationsFrontend Next.js 16 · React 19 · Tailwind 4 · ZustandTesting Jest · Vitest · supertestInfrastructure Docker · GitHub Actions

What I take away

In a system that has to survive without a network, the half you cannot add afterwards is the server half. Having a replayed operation return the state instead of duplicating the charge had to exist before the queue on the device did: you cannot get there in the other order, because by then the double charges are already in the database.

loklflow kitchen display: three columns — pending with three orders, preparing with two, ready with one — where each card carries the order number, the table and the elapsed time, grey at two minutes and red at twenty-four.

03

mundial-2026-ml

A World Cup 2026 predictor: it estimates how each match ends and simulates the whole tournament five thousand times to give each team its chance of winning.

Architecture

A four-step pipeline — data, features, models and backtest — over 49,509 matches stored in SQLite, with the features built forward in time and a dashboard at the end.

Data pandas · numpy · SQLiteModelling scikit-learn · GradientBoosting · PoissonRegressor · Dixon-ColesEvaluation expanding-window backtest · hand-written RPSSimulation Monte Carlo, 5,000 tournamentsInterface Streamlit · plotly

What I take away

Hunting the leak in my own code was worth more than pushing accuracy up. I found five contaminated features out of fourteen and published them along with what fixing them would cost, so the metrics in the repository are an optimistic ceiling — and I am the one saying it, before whoever reads the code does.

The predictor's interface. Two team selectors showing Argentina and France, and below them the calibrated probabilities as bars: Argentina win 47.1%, draw 22.7%, France win 30.2%. Underneath, the Poisson score matrix with the Dixon-Coles correction as a seven-by-seven heatmap, with the predicted score's cell outlined.

Other projects

Code of mine that exists but is not substantial enough for a case study. It is here so nobody mistakes it for the three above.

mi-cartera ↗

Turborepo · NestJS · TypeORM · PostgreSQL · Next.js

Personal finance app with accounts, transactions, categories and investments. Turborepo monorepo, NestJS API with TypeORM, Next.js frontend. It is at an early stage — five commits — and I say so here so nobody confuses it with the three cases above.