Pargo
Multi-tenant SaaS POS for restaurants and hotels on Colombia's Caribbean coast
- company:
- Personal project
- period:
- Jul 2026 — ongoing
- NestJS 12
- Fastify
- TypeScript
- PostgreSQL (RLS)
- Valkey
- React
- TanStack Query
- Next.js
- Turborepo + pnpm
- Zod
- OpenTelemetry
- Docker
- Testcontainers
- Playwright
- Anthropic / OpenAI / Gemini
// problem
Restaurants on Colombia's Caribbean coast deal with frequent internet outages, mandatory electronic invoicing and generic POS systems that neither deduct inventory nor reconcile the cash drawer. The reference projects I analyzed had serious flaws: the client set the totals, anyone could sign up as admin and payment webhooks weren't idempotent.
// my role
I design and build it end to end: technical plan, 11 ADRs, multi-tenant PostgreSQL data model, NestJS API, POS and back office in React, public site in Next.js, multi-provider AI package, hardened Docker infrastructure and a local verification pipeline that runs on every push. It is my personal project and I built it with AI-assisted development: the AI speeds up the implementation, while the architecture, the data model and every technical decision are mine, documented and justified in the ADRs.
// architecture
Modular monolith: the same codebase deployed as three processes with different database permissions. Electronic invoicing currently runs against a simulated provider while Factus is integrated.
// technical decisions
Fail-closed multi-tenancy with Row Level Security
Every table has RLS ENABLE + FORCE and composite foreign keys (tenant_id, id); database roles are not superusers and cannot bypass RLS, and the API refuses to start if its role could. Without a business context a query returns nothing, and there are A↔B isolation tests for reading, updating, deleting, inserting and referencing.
Offline POS with a lease and signed events
While online, the POS requests a 24-hour lease with a snapshot of the catalog and a sales cap. Offline, each sale is an event signed with the device's non-exportable ECDSA key and stored encrypted in IndexedDB. On sync, the server verifies the signature and recalculates prices from the stored snapshot, never from what the tablet sends; suspicious cases are flagged for manager review instead of losing money that was actually collected.
Inventory as a ledger with recipes and average cost
Each sale deducts ingredients according to the recipe of the variant and its modifiers (a large snapper with patacón doesn't use the same as a medium one with coconut rice). Purchases, waste, adjustments and physical counts are movements in a per-location ledger, so stock can always be rebuilt and audited.
Multi-provider AI with a deterministic score
Review analysis returns structured outputs validated with Zod on Anthropic, OpenAI or Gemini. The reputation score is computed deterministically from stored data, not estimated by the model; review replies always require human approval, each business has a budget and there is an evaluation suite against prompt injection.
AI-assisted development, human-owned decisions
I used AI as a pair programmer to build faster as a single developer, but every decision starts from a real constraint and is recorded in an ADR: a modular monolith because one person can deploy and operate it, with module boundaries that allow splitting it later; RLS so that tenant isolation is enforced by the database rather than depending on every query remembering a filter; an offline POS because internet outages on the coast must not stop sales; and an inventory ledger so stock can be audited. No change gets in without tests against real PostgreSQL, which is how I verify that the generated code does what was decided.
// impact
- Automated tests
- 751
- Documented decisions
- 11 ADRs
- Selling without internet
- 24 h
- Processes
- 3
+ 8 Playwright E2E against the real stack
signed lease with a sales cap
api · public-api · worker
// screenshots








