Isaí Céspedes · Frontend-leaning full stack engineer · Web & AI
I build web and AI products that work in production.
Frontend-leaning full stack engineer with 4+ years shipping TypeScript, React and Next.js for client teams in the US, UK and Spain. In 2026 I built four products on my own with an AI-augmented, spec-driven workflow. Scroll through each one: what it does, the hardest call, and the proof.
Santa Cruz, Bolivia · Remote-first · CET / UTC-4 flexible. Spanish (native), English (professional)
20222023202420252026
Stack BuildersFull Stack Software Developer. Consulting firm delivering SaaS and B2B products for international clients across the US, UK, and Spain.Jan 2024 – Jun 2026
Pylon DataFull Stack Software Developer. Solar energy management platform serving electricity providers across the United States.Oct 2022 – Feb 2023
MicroversePeer Technical Mentor. Hired as staff while enrolled, to support early-stage developers.Jan 2022 – Oct 2023
Chapter 1 of 4
ChurchOS
ChurchOS: church admin, out of the spreadsheet.
Free, Spanish-first church management for small congregations, with each church's data isolated by the database itself.
Small Bolivian churches run on Excel and paper, mostly from a phone. The pastor should see giving totals, never who gave what.
What I built
and with what
01Multi-church accounts with 4 roles; the pastor sees giving totals, never individual donors.
02People and households, with Excel/CSV import and duplicate merge.
03QR attendance check-in from any phone.
04Offerings with funds and batches, expense month-close, PDF donor statements and treasurer reports.
05Spanish and English, audit log, GDPR erasure and full data export.
Next.js 16
React 19
TypeScript
Postgres (Neon) with RLS
Drizzle
better-auth
Tailwind CSS 4
react-pdf
Vercel Blob
Resend
Sentry
Vitest
Playwright
Demo
16:9 loop, fake data
Architecture
system map
Phone UI → Next.js on Vercel: HTTPS
Next.js on Vercel → better-auth session: session
Next.js on Vercel → withTenant() + can(): server actions
withTenant() + can() → Postgres with RLS (Neon): transaction-local tenant id
Next.js on Vercel → Vercel Blob: files
Next.js on Vercel → Resend: email
CI migrator role → Postgres with RLS (Neon): migrations
Next.js on Vercel → Sentry: errors
Hardest decision
why it matters
Enforce church isolation inside Postgres, with forced row-level security keyed on a transaction-local tenant id.
instead of
App-level WHERE filters on every query.
Session-scoped database settings.
why
A forgotten filter fails silently and becomes a breach. Session settings could leak the previous church through the connection pool. A cross-tenant test suite fails the build if any new route or server action isn't registered.
Result
proof
In production at church-os.com.
About 2,400 automated test cases, including 25 Playwright specs.
CI gates on typecheck, dependency boundaries, lint and end-to-end tests.
Unattended production migrations and a point-in-time recovery drill.
Paddle webhooks → /api/v1 (auth, CSRF): signed events
Cron prune → Postgres (Neon) + Drizzle: prune
Hardest decision
why it matters
A custom job-import runner persisted in Postgres, not Vercel Workflow SDK.
instead of
Vercel Workflow SDK, which I tested first and which worked.
why
It added a public flow route with weak auth, 381 packages and 2 high audit advisories. My runner is a Postgres state machine with lease-guarded steps tied to maxDuration, so a failed Claude call never re-runs paid steps.
Result
proof
Live demo at www.pilotboard.dev; payments and email are switched off.
Production smoke test: 12/12 passing.
About 2,000 unit and integration test cases, plus ~160 end-to-end.
Security-review gate before every milestone merge.
Jarvis: a voice assistant that asks before it acts.
An always-on bilingual voice assistant for macOS that runs on Claude and starts, steers and approves live Claude Code sessions.
status
Personal tool in daily use (private repo)
period
Sep 2026 – Present
The problem
for whom
Hands-free control of my Mac, the web and my accounts. Voice was easy; the hard part was letting an AI act on real accounts only with my approval.
What I built
and with what
01Local wake word → Whisper speech-to-text → Claude → streaming ElevenLabs voice, with barge-in.
02Permission tiers enforced in code: read, local, outward, forbidden; outward actions need a spoken yes.
03Taint tracking, so text from the web or a repo can't trigger outward actions.
04Background coding and research jobs in isolated git worktrees (up to 3), steered from a three.js HUD.
05WhatsApp channel, linked-notes memory, and self-update in its own worktree.
Python 3.12
uv
Claude Agent SDK
openWakeWord
Whisper large-v3-turbo (MLX)
Silero VAD
ElevenLabs Flash 2.5
three.js
macOS LaunchAgent
Demo
16:9 loop, fake data
Architecture
system map
Mic + wake word → Whisper STT: audio
Whisper STT → Mind (Claude): text
Mind (Claude) → Policy gate: tool call
Policy gate → Tools / Mac: allowed
Mind (Claude) → Speaker (ElevenLabs): reply
Mind (Claude) → Claude Code in worktrees: jobs
Mind (Claude) → HUD (SSE): events
WhatsApp → Mind (Claude): messages
Hardest decision
why it matters
Enforce permissions in code, not in the prompt.
instead of
Prompt-only rules.
The first version's closed-set intent classifier.
why
A prompt can be argued with; a policy gate can't. General tools behind the gate, plus taint tracking, kept Jarvis flexible without trusting the model. A security review of self-update still found real holes, like a debug port treated as local. They're fixed.
A multi-tenant store and point-of-sale platform for Bolivian small businesses: subdomain storefronts, map-pin checkout, QR payments and courier hand-off.
status
Shipped · ran in production Jun–Oct 2026 · now paused
period
Jun 2026 – Oct 2026
The problem
for whom
Small Bolivian shops: addresses are unreliable, so checkout needs a map pin, and each payment must settle into the shop's own bank account.
What I built
and with what
01A storefront per shop, on its own subdomain.
02Map-pin checkout with a tax-invoice option.
03Per-shop QR payments: encrypted credentials, webhook plus a reconciliation cron.
04Order state machine with price snapshots and live tracking by magic link.
05Shop admin with reports and CSV, in-person POS with receipts, push alerts, courier API.
Next.js 16
React 19
TypeScript
Postgres (Neon)
Drizzle
zod
Tailwind CSS 4
MapLibre
web-push
Cloudflare R2
Caddy (on-demand TLS)
AWS EC2
GitHub Actions
Vitest
Playwright
PostHog
Demo
16:9 loop, fake data
Architecture
system map
Customer → Caddy (on-demand TLS): HTTPS
Caddy (on-demand TLS) → Next.js (tenant from Host)
Next.js (tenant from Host) → Postgres (Neon) + RLS
Next.js (tenant from Host) → QR payment provider: create QR
QR payment provider → Next.js (tenant from Host): webhook + reconcile
Next.js (tenant from Host) → Cloudflare R2 images: images
Next.js (tenant from Host) → Courier API: hand-off
Next.js (tenant from Host) → Web push → shop admin: order alerts
Magic-link tracking → Next.js (tenant from Host): order status
Hardest decision
why it matters
Per-shop QR payments, with a dormant fallback adapter.
instead of
Six other providers, evaluated after the first one turned out to be dead.
why
I rejected rails that forced a bank, settled in USDC, pooled every shop’s money, or needed sales onboarding. Per-shop QR pays each business straight into its own account. The fallback adapter keeps a second provider ready.
Result
proof
Shipped and ran in production Jun–Oct 2026; now paused.
I'm open about it: AI agents write a lot of my code. What makes it shippable is the process around them. Every feature starts as a written spec. Agents build in isolated branches. Separate review passes, and I, check the result. Nothing merges until types, lint, tests and CI pass. Sensitive work also gets a security review.
01SpecWrite down what "done" means first: scope, edge cases, and the tests that must pass.
02BuildAgents implement against the spec, each in its own git worktree, in parallel.
03GateTypecheck, lint, unit, integration and end-to-end tests in CI, plus security review on risky changes.
04ShipDeploy through CI, with migrations automated and a recovery path tested.
Speed isn't the risk. Skipping the checks is.
What the people I worked with say
Isaí consistently supports teammates and contributes to team productivity by collaborating on complex features, helping unblock others, and refining tasks before implementation. He communicates proactively to resolve blockers with both the team and client, follows strong engineering practices, and demonstrates openness to feedback during code reviews.
Cristian MotocheTech Lead · Stack Builders
Isaí takes strong ownership of the tasks he works on, asking the right questions and ensuring features are delivered polished and production-ready. He contributes positively to team collaboration, supports technical alignment between client and team, improves development workflows, and provides thoughtful code reviews at a peer engineering level.
Jota MartinezSoftware Engineer · Stack Builders
Isaí consistently delivers high-quality work and is recognized as a reliable and collaborative engineer, making him a great teammate to work with across teams and projects.
KieranClient · Stack Builders engagement
Isaí shows strong curiosity and initiative when improving the development environment, experimenting with tooling such as linters and editor extensions. He adapts quickly, learns fast, and provides reliable support during demanding periods while contributing to cleaner and more maintainable frontend code.