CATOCA · Sales system
Sales, batch inventory, commissions and DIAN pre-invoicing for a coffee exporter
- company:
- CATOCA (client)
- period:
- Sep 2026 — ongoing
- NestJS 12
- Fastify
- Drizzle ORM
- PostgreSQL 18
- React 19
- Vite 8
- TanStack Router / Query
- Tailwind CSS 4
- Zod (shared contracts)
- Vitest
- Testcontainers
- Playwright
- Docker + Nginx
// problem
Sales reps' sales, inventory and commissions were tracked separately and by hand. The online store didn't deduct inventory, and the accountant had to rebuild every invoice to load it into Siigo.
// my role
Architecture and full development in phases: data model, NestJS API with Drizzle on PostgreSQL 18, React web panel, integration with the online store and Wompi, and the testing strategy.
// architecture
The online store creates orders with an API key + HMAC and Wompi confirms payment through a signed webhook; both become sales in the web channel.
// technical decisions
Exact money and rates stored on every sale
Amounts in numeric(18,2), always in COP. VAT is calculated by accumulating the base per rate and rounding once on the total (ROUND_HALF_UP). Each sale stores the VAT rate and commission percentage it was calculated with, and only the admin can change those rates, with history.
Batch inventory with a stock ledger and FIFO
Every stock entry requires a batch date and a roast date. Sales consume the oldest batches first, every movement is recorded in the stock ledger and the system won't sell without stock.
Immutable, audited sales
The seller is always the authenticated user and can't edit a saved sale. Only the admin edits, with a mandatory reason and a before/after revision. A cancellation returns the inventory and voids the commission (with a negative adjustment if already paid); a return restores inventory but doesn't touch the commission.
Tests as the specification
100% coverage is mandatory, API tests run against real PostgreSQL with Testcontainers and E2E with Playwright. A committed test is never changed to make the code pass: a hook blocks editing it and a script checks it against main.
// impact
- Test coverage
- 100%
- Backend modules
- 14
- Sales channels
- 3
- Accounting
- Siigo
mandatory Vitest threshold
sales rep · online store · admin
.xlsx export by date range





