Solutions Engineer — I build integrations that solve real operational problems.
Solutions Engineer — construyo integraciones que resuelven problemas operativos reales.
I run a bubble tea business in Mexico City and built the systems it operates on: POS integrations,
an auditable loyalty ledger, and the dashboards that decide what we do next. These run in production,
against real customers and real money — every number below came out of a system I still maintain.
Discovery, building the thing, and explaining it to someone non-technical is already how I spend my week.
Dirijo un negocio de bubble tea en la Ciudad de México y construí los sistemas sobre los que opera:
integraciones con el punto de venta, un libro mayor auditable de lealtad, y los tableros con los que
decidimos qué sigue. Todo corre en producción, con clientes y dinero reales — cada número de aquí
abajo salió de un sistema que sigo manteniendo. Hacer discovery, construir la solución y explicársela
a alguien no técnico ya es en lo que se me va la semana.
We paid a signup bonus to 464 customers — roughly $9,300 MXN — with no way to tell whether it
bought loyalty or just discounts.
What I asked first
What's the correct denominator? Is the sample large enough to support a trend line? And what am
I actually measuring — customer behavior, or program usage? Only 11–15% of receipts carry a customer
ID, so it's the latter. That caveat ships on the dashboard itself, not buried in a README.
What I built
A three-part pipeline: cursor-paginated extraction from the Loyverse API with defensive backoff,
a local cache so recomputation never hits the API, and a funnel view that reads generated JSON — no
hardcoded numbers. Customer data is gitignored; the repo ships aggregate sample data so it renders
for anyone who clones it.
Problema
Pagamos un bono de registro a 464 clientes — unos $9,300 MXN — sin forma de saber si eso compraba
lealtad o solamente descuentos.
Qué pregunté primero
¿Cuál es el denominador correcto? ¿Alcanza la muestra para justificar una línea de tendencia? ¿Y
qué estoy midiendo en realidad — comportamiento del cliente o uso del programa? Solo 11–15% de los
recibos traen identificador de cliente, así que es lo segundo. Ese caveat va visible en el tablero,
no escondido en un README.
Qué construí
Un pipeline de tres partes: extracción de la API de Loyverse con paginación por cursor y backoff
defensivo, caché local para que recalcular nunca golpee la API, y una vista de embudo que lee un JSON
generado — ningún número hardcodeado. Los datos de clientes están en gitignore; el repo incluye datos
agregados de muestra para que renderice sin exponer a nadie.
Impact
The obvious metric said 53.9% activation. I found that 87% of "post-signup purchases" happened on the
signup day itself — that's the discount being applied, not a return visit. The honest number is
23.7%: roughly 3 in 4 enrolled customers never came back on a different day. The program was
operating as a single-use coupon.
Impacto
La métrica obvia decía 53.9% de activación. Encontré que el 87% de las "compras post-registro"
ocurrían el mismo día del registro — o sea, era el descuento aplicándose, no un retorno. El número
honesto es 23.7%: cerca de 3 de cada 4 registrados nunca volvieron en un día distinto. El
programa operaba como cupón de un solo uso.
Loyalty balances for 475 customers lived in Google Sheets via Apps Script. A balance was a number
in a cell — no history, no audit trail, no way to answer "why does this customer have 340 points?"
What I asked first
Can every balance be reconstructed from transactions? What happens if the sync runs twice? And does
this script write anything back to the POS? I grep-audited it before running: one call, GET,
no writes.
What I built
A ledger-backed schema in PostgreSQL — a balance is the sum of its transactions, each tagged with a
reason and a tenant ID, multi-tenant by design. Partial unique indexes make duplicate opening balances
structurally impossible. A nightly sync runs on Railway alongside the inventory scheduler.
Problema
Los saldos de lealtad de 475 clientes vivían en Google Sheets vía Apps Script. Un saldo era un
número en una celda — sin historial, sin auditoría, sin forma de responder "¿por qué este cliente
tiene 340 puntos?"
Qué pregunté primero
¿Se puede reconstruir cada saldo desde transacciones? ¿Qué pasa si el sync corre dos veces? ¿Y este
script escribe algo de vuelta en el punto de venta? Lo audité por grep antes de correrlo: una sola
llamada, GET, cero escrituras.
Qué construí
Un esquema con libro mayor en PostgreSQL — un saldo es la suma de sus transacciones, cada una con
su razón y su identificador de tenant, multi-tenant por diseño. Índices únicos parciales hacen que un
saldo de apertura duplicado sea estructuralmente imposible. Un sync nocturno corre en Railway junto al
scheduler de inventario.
Impact
475 customers migrated, 700 ledger entries, zero duplicates and zero orphans — verified against
the database, not against what the script printed. The first automated run detected and corrected 225
balances that an earlier integer column had silently rounded, and left a record of every adjustment.
The system caught the bug the system was built to catch.
Impacto
475 clientes migrados, 700 asientos en el libro mayor, cero duplicados y cero huérfanos —
verificado contra la base de datos, no contra lo que imprimió el script. La primera corrida automática
detectó y corrigió 225 saldos que una columna entera anterior había redondeado en silencio, y dejó
constancia de cada ajuste. El sistema atrapó justo el error para el que fue construido.
Reconciling two signup channels against one customer database
Reconciliar dos canales de registro contra una sola base de clientes
Data reconciliation · Loyverse API · Node.js · CSV cross-reference
Problem
Signups arrived through two channels — an external form and the website — and both were supposed
to land in the POS customer database. Nobody had ever verified that they did. Every person who filled
the form was promised a cash bonus.
What I asked first
What's the join key, and is it reliable? Am I comparing against the full customer list or a sample?
I pulled all 434 customers through the API rather than eyeballing a page of results — a reconciliation
run against a sample is worse than none, because it produces a number people trust.
What I built
A script that normalizes and deduplicates 399 form submissions down to 374 unique emails, pulls the
complete paginated customer list from the API, and reports the exact set difference in both directions.
Problema
Los registros llegaban por dos canales — un formulario externo y el sitio web — y ambos debían
aterrizar en la base de clientes del punto de venta. Nadie había verificado nunca que así fuera. A cada
persona que llenó el formulario se le prometió un bono en efectivo.
Qué pregunté primero
¿Cuál es la llave de cruce y qué tan confiable es? ¿Estoy comparando contra la lista completa de
clientes o contra una muestra? Traje los 434 clientes por API en lugar de mirar una página de
resultados — una reconciliación contra muestra es peor que ninguna, porque produce un número en el que
la gente confía.
Qué construí
Un script que normaliza y deduplica 399 respuestas del formulario a 374 correos únicos, trae la
lista completa y paginada de clientes por API, y reporta la diferencia exacta en ambas direcciones.
Impact
98.4% matched, which confirmed the low identification rate was real and not an artifact of an
uncounted parallel customer base — that validated the entire analysis above it. It also surfaced
6 people who were promised a bonus and never received it, one of them pending for over six
months, and revealed that 85% of the customer base came from a channel nobody considered primary.
Impacto
98.4% de coincidencia, lo que confirmó que la baja tasa de identificación era real y no un artefacto
de una base paralela de clientes sin contar — eso validó todo el análisis anterior. También sacó a la
luz 6 personas a las que se les prometió un bono y nunca lo recibieron, una de ellas pendiente
por más de seis meses, y reveló que el 85% de la base de clientes venía de un canal que nadie
consideraba principal.