Case Study · 01
Nivo
Nivo is a Turborepo monorepo powering five apps — a NestJS API (190+ source files, 120+ REST endpoints), a Next.js 14 admin + POS, a customer-facing storefront, and two React Native mobile apps — all sharing 84 TypeORM entities across isolated PostgreSQL databases per tenant. I designed and built the database-per-tenant middleware with in-memory connection pooling (each tenant's DataSource is created once and reused for every request after), a 3-level cascading pricing engine that eliminates thousands of redundant price rows, an offline-first POS sync pipeline via Dexie.js, and Nibbit — an agentic AI assistant powered by Gemini with 14 function-calling tools that drafts purchase requisitions and supplier emails autonomously. Nivo began as my bootcamp capstone: a multi-tenant POS MVP I shipped in three weeks as backend lead and project manager of a team where I was the only trained developer. This monorepo is its second life — a ground-up solo rebuild, every commit mine, of what we used to call "the base of the system of our dreams".
Multi-branch shoe retail is one of the hardest inventory problems in physical commerce. Every product explodes into a matrix — size × color × branch — that quickly multiplies into hundreds of thousands of possible SKU combinations; franchises sharing one platform must never see each other's records; the counter cannot stop selling when the connection drops; and the final price of a single shoe depends on global landed-cost bases, per-branch cost overrides, and per-list margin exceptions — all under Mexico's strict CFDI electronic-invoicing rules. Nivo was built to hold that entire problem at once, end to end.
Database-per-tenant pattern built on NestJS. A Master PostgreSQL database stores tenant records and Stripe subscriptions. On every request, a custom NestJS middleware extracts the subdomain (e.g. acme.nivo.app), queries the master DB to resolve the tenant, and hands a dedicated TypeORM DataSource for that tenant's isolated database to the request pipeline. Connections are pooled in-memory via a Map<string, DataSource>, so the cost of opening a tenant's connection is paid once — not on every request. Async workloads — tenant provisioning, low-stock alerts, invoice generation, report exports — are handled by BullMQ workers backed by Redis.
Offline-First Point of Sale
Every sale is written directly to IndexedDB via a Dexie.js database (NivoOfflineDB) using UUID primary keys, so the cashier never waits for a network round-trip. Pending sales are queued locally with a synced: false flag. When the browser fires the online event, a listener replays the entire queue via POST /sales/sync. The API processes each sale inside its own database transaction — validating stock, deducting inventory, creating payment records, and triggering async stock evaluation via setImmediate — then returns a per-item status report. UUID keys guarantee idempotency across offline and online sessions.
Cascading Fallback Pricing
The PricingService.calculatePrice() method resolves the final sale price through a strict 3-level fallback cascade. Step 1 — Purchase Cost: reads branch_variant_overrides for a branch-specific cost; falls back to the variant's global cost field. Step 2 — Base Price: multiplies cost by (1 + landed_cost_%), where landed cost is resolved from branch_setting_overrides, then tenant_settings, then zero. Step 3 — Sale Price: multiplies the base by (1 + margin_%), where margin is resolved from variant_price_margins for a specific price list, then the price list's default_margin_percentage. This eliminates thousands of redundant price rows — only exceptions are stored.
Matrix Variant Generation
The system models the physical world of footwear through a relational schema of size_groups (e.g. Men, Women, Kids), size_systems (MX, US, EU), and size_equivalencies that map each size across systems. Product variants store dynamic attributes as a JSONB column — { "Color": "Black", "Talla MX": "26" } — replacing rigid fixed columns. The frontend crosses active size groups with available colors to auto-generate the full Cartesian product of variants: a shoe in 3 colors and 12 sizes produces 36 SKUs with zero manual data entry, eliminating human error at cataloging time.
Agentic AI with Human-in-the-Loop
Nibbit is the platform's built-in AI agent, powered by Gemini (gemini-2.0-flash) via @google/generative-ai with 14 registered function declarations. Read-only tools query sales summaries, low-stock items, branch comparisons, and product catalogs by executing raw SQL against the tenant's isolated database. Mutation tools — draft_auto_requisition and draft_supplier_emails — scan inventory deficits, generate purchase requisition drafts, produce PDF attachments via Puppeteer, and compose supplier emails using a second Gemini call. Nibbit never executes final mutations: every draft is surfaced to the human administrator for review and approval before becoming a real Purchase Order.
Omnichannel Native Ecosystem
Two React Native / Expo Router apps operate as tenant-aware API clients sharing @nivo/types. The B2B app (mobile-b2b) transforms the device into a high-speed barcode scanner via expo-camera's CameraView — scanning EAN-13, UPC-A, and Code128 barcodes with haptic feedback (expo-haptics) for inventory audits, and tracks live delivery coordinates via expo-location's watchPositionAsync (high accuracy, 20 m interval) with proof-of-delivery photo capture. The B2C app (mobile-b2c) integrates @stripe/stripe-react-native for checkout, uses Haversine distance to auto-select the nearest pickup branch from the user's GPS position, and surfaces a loyalty ledger with tiered QR codes (Bronze → Silver → Gold → Wholesale) that auto-brighten the screen via expo-brightness for instant in-store scanning. Both apps use @tanstack/react-query for real-time cache consistency against the multi-tenant API.
Resolves subdomain to an isolated TypeORM DataSource, pooled in-memory via Map<string, DataSource> — the connection cost is paid once per tenant, not per request.










