CATOCA · Sistema de ventas
Ventas, inventario por lotes, comisiones y prefacturación DIAN para una exportadora de café
- empresa:
- CATOCA (cliente)
- periodo:
- Sep 2026 — en curso
- NestJS 12
- Fastify
- Drizzle ORM
- PostgreSQL 18
- React 19
- Vite 8
- TanStack Router / Query
- Tailwind CSS 4
- Zod (contratos compartidos)
- Vitest
- Testcontainers
- Playwright
- Docker + Nginx
// problema
Las ventas de los vendedores, el inventario y las comisiones se llevaban por separado y a mano. La tienda en línea no descontaba inventario, y la contadora tenía que reconstruir cada factura para cargarla en Siigo.
// mi rol
Arquitectura y desarrollo completo por fases: modelo de datos, API NestJS con Drizzle sobre PostgreSQL 18, panel web en React, integración con la tienda en línea y con Wompi, y la estrategia de pruebas.
// arquitectura
La tienda en línea crea pedidos con API Key + HMAC y Wompi confirma el pago con un webhook firmado; ambos se convierten en ventas del canal web.
// decisiones técnicas
Dinero exacto y tarifas guardadas en cada venta
Montos en numeric(18,2), siempre en COP. El IVA se calcula acumulando la base por tarifa y redondeando una sola vez sobre el total (ROUND_HALF_UP). Cada venta guarda la tarifa de IVA y el porcentaje de comisión con que se calculó, y esas tarifas solo las cambia el admin, con historial.
Inventario por lotes con kardex y salida FIFO
Cada entrada exige fecha de lote y de tostión. Las ventas consumen los lotes más antiguos primero, cada movimiento queda en el kardex y el sistema no deja vender sin stock.
Ventas inmutables y auditadas
El vendedor siempre es el usuario autenticado y no puede editar una venta guardada. Solo el admin edita, con motivo obligatorio y revisión antes/después. Una anulación devuelve el inventario y anula la comisión (con ajuste negativo si ya se pagó); una devolución devuelve el inventario pero no toca la comisión.
Pruebas como especificación
Cobertura del 100 % obligatoria, pruebas de API contra PostgreSQL real con Testcontainers y E2E con Playwright. Una prueba ya commiteada nunca se modifica para que el código pase: un hook bloquea su edición y un script lo verifica contra main.
// impacto
- Cobertura de pruebas
- 100%
- Módulos del backend
- 14
- Canales de venta
- 3
- Contabilidad
- Siigo
umbral obligatorio en Vitest
vendedor · tienda web · admin
exporte .xlsx por rango de fechas





