Eduin Garcia
HolaPlace · Senior Software Developer · Jun 2020 – Dec 2023

A two-sided venuemarketplace, from scratch

A marketplace for booking event venues and the supplier services that go with them — listings and onboarding, availability calendars, a request and negotiation flow, chat between guests and hosts, reviews, invoicing and contracts. The hard parts were the money — Stripe Connect deposits, holds, split charges, payouts, claims and refunds — and keeping host calendars in sync in both directions over iCal.

HolaPlace venue search
HolaPlace — platform scale4 repositoriesSheet 01
~228k
Lines of TypeScript
399
REST endpoints
55
Mongoose models
152
Migrations
42
API domain modules
7
Socket.IO gateways
4
Repositories
3
AWS environments

~228k lines of TypeScript across four repositories, plus ~3.3k lines of Terraform across three environments.

01 · My role

Six-person team

02 · Architecture

Polyrepo · modular NestJS

03 · Backend

NestJS 9 · MongoDB · Stripe Connect
Runtime
Node.js 18, TypeScript 5 (ts-node, nest build)
Framework
NestJS 9, Express 4
Database
MongoDB 5 (replica set), Mongoose 6 + mongoose-autopopulate, mongo-migrate-ts (152 migrations)
Secondary stores
DynamoDB (cookie-consent audit log), Redis 7 (ioredis, cache-manager-redis-store)
Queues
Bull 4 on Redis — factory-built queues with event subscribers
Realtime
Socket.IO (@nestjs/websockets) + @socket.io/redis-adapter
Auth
Passport + passport-jwt, @nestjs/jwt, bcrypt, Facebook/Google social login
Validation
class-validator / class-transformer DTOs, Joi for env-schema validation
Payments
Stripe 8 Connect — connected accounts, KYC person mapping, payment intents, manual payouts, transfers & reversals, deposit claims, dual webhook listeners (platform + connect)
Email / CRM
Brevo (formerly Sendinblue) + EJS templates, Pipedrive deals, ClickUp bug intake, Slack Web API notifications
Messaging
WhatsApp & SMS services with per-domain message catalogs
Storage / media
AWS S3, Sharp + Jimp image processing, express-fileupload, JSZip
Documents
Puppeteer (invoice/contract PDFs from EJS views), csv-writer, ical-generator + node-ical
Geo
Mapbox, geolib, geo-tz, city/province/country seed data
Scheduling
@nestjs/schedule for in-process tasks; sitemap generation task pushing to S3
API docs
@nestjs/swagger → OpenAPI 3, Compodoc
Observability
Winston (nest-winston) with Loki + Slack-webhook transports, Morgan + rotating file streams, prom-client via @willsoto/nestjs-prometheus, OpenProfiling heap profiler
Security
Helmet, ip-range-check (webhook CIDR allowlisting), cookie-parser
CLI
nestjs-command — seeders and data-manager maintenance scripts (anonymization, backfills, S3 migration, payouts)
Testing
Jest 29, ts-jest, Supertest, mongodb-memory-server, @golevelup/ts-jest

04 · Frontend

React 18 · pnpm workspace
Core
React 18, TypeScript 4.7, Webpack 5 + Babel 7 (pnpm workspace on Node 22)
Routing
React Router 5 — 22 lazy-loaded route bundles
Styling
Tailwind CSS 3 + PostCSS and Sass, MUI 4 (core, lab, pickers) + @mui/base
Server state
TanStack Query 4 (+ devtools)
Client state
Redux 4 + React Redux 8 + Redux Saga, Immer
State machines
XState 4 + @xstate/react (booking/checkout flows)
Forms
React Hook Form 7, @eduinlight/input-validator, validator, react-text-mask
Payments
Stripe Elements (@stripe/react-stripe-js)
Maps
Leaflet + React Leaflet, Mapbox GL + mapbox-gl-leaflet, Google Places autocomplete
Realtime
socket.io-client
Dates
Day.js (+ @date-io/dayjs pickers adapter)
UI/UX
Notistack, Downshift, react-beautiful-dnd, react-virtuoso, Slick/Slideshow carousels, react-avatar-edit, emoji picker, ScrollReveal, Lucide icons
SEO / meta
react-helmet-async, react-snap prerendering, workbox service worker
Testing
Jest 29 + Testing Library + jsdom, Cypress 12 e2e
Build / deploy
Brotli + gzip compression plugins, webpack-s3-plugin (static assets → S3/CloudFront), served by Nginx

05 · Satellite services

SEO prerender · scheduler
apps/seo

Bun 1.x + Hono 4, rendering with puppeteer-core on system Chromium, Redis 7 caching the rendered HTML with an invalidation endpoint, Zod-validated config. A Traefik v3 HeaderRegexp(User-Agent, …) rule routes ~30 crawler and AI-bot agents here; everything else goes to the SPA, with static assets proxied through.

holaplace-scheduler

NestJS 8 on Node 16 with Croner 5 — a task registry of declarative cron expressions, task definitions and run records in DynamoDB, Axios + axios-retry callbacks into the API through a token service, Joi-validated env plus AWS Secrets Manager and Slack error reporting behind a health endpoint.

06 · Infrastructure & DevOps

Terraform · AWS eu-west-3

07 · Engineering highlights

Eight decisions
Stripe Connect money flow

The full marketplace lifecycle: deposit holds, split charges, transfers and reversals, manual payouts, deposit-claim adjudication with its own money service, and separate platform and connect webhook processors.

Externalized cron

The scheduler service holds every recurring job as a registry entry, invokes the API over authenticated callbacks, and writes an auditable run history to DynamoDB, so API instances stay stateless and horizontally scalable.

Bot-aware rendering split at the proxy

Traefik user-agent matching sends crawlers to a Bun + Hono + Puppeteer renderer with a Redis HTML cache and an invalidation API, replacing a paid Lambda@Edge / Prerender.io setup.

Two-way calendar sync

iCal generation plus node-ical/CalDAV ingestion, with a dedicated realtime gateway pushing availability changes to connected clients.

Runtime translation model

A response interceptor and @Lang() decorator localize payloads per request without duplicating endpoints.

Field-level response shaping

A family of pick-*/omit-fields interceptors projects entity responses per role and context, keeping host, guest and admin views on one controller.

Immutable infrastructure on plain EC2

No ECS or EKS — ASGs boot from S3-hosted compose files and deploys are instance refreshes, giving container-style rollout on a low-cost footprint.

Data-manager script suite

One-off maintenance commands (anonymization, timezone/geo backfills, upload→S3 migration, balance payouts) versioned alongside the 152-file migration history.

HolaPlace venue detail page
HolaPlace venue page on mobile
Previous: QollabiNext: Caxper