Marco Rivera

Marco Rivera

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.

Selected workTrabajo seleccionado

The loyalty program that was actually a coupon

El programa de lealtad que en realidad era un cupón

Loyverse POS API · Node.js · funnel analysis · custom dashboard

Problem
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.

From spreadsheet to an auditable data layer, without losing a point

De hoja de cálculo a capa de datos auditable, sin perder un solo punto

PostgreSQL / Supabase · Node.js · Railway · scheduled sync

Problem
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.

StackStack