Portfolio

Producto propio

Pullstok: ERP SaaS completo con tienda online

Mi producto propio: un ERP SaaS multi-tenant que diseño, construyo y opero. Punto de venta, stock, facturación electrónica ARCA, contabilidad (en desarrollo), tienda online por subdominio, Mercado Pago, bots con IA y un agente de impresión local. Monorepo con 5 apps, API en Node con Prisma y PostgreSQL.

2025 Side project En curso
ReactNode.jsExpressPrismaPostgreSQLAstroSaaS multi-tenantARCA

Stack tecnológico

Las tecnologías usadas y por qué.

UI React
Build Vite
Ruteo React Router
Data fetching TanStack Query
Estilos Tailwind CSS
Lenguaje TypeScript
API Express
ORM Prisma
Base de datos PostgreSQL
Validación Zod
Landing y tienda Astro
Testing Jest
Runtime Node.js
Componentes shadcn/ui
Tiempo real Socket.io
Testing Vitest
Observabilidad Sentry
Storage Cloudflare R2
Pagos Mercado Pago
IA Groq
Servidor Nginx
CI/CD GitHub Actions

Capturas

Pantalla de login de PullstokPanel de productos y control de stockGestión de categorías de productosMódulo de presupuestosMódulo de pedidosMódulo de ventasMódulo de remitosGestión de clientesTienda online conectada al catálogoMódulo de facturaciónPanel de superadmin para gestionar comercios


El problema

Una empresa que vende, minorista o mayorista, con una o varias sucursales, suele tener la operación repartida: el stock en una planilla, la facturación en otro sistema, el cobro con QR en otra app, la contabilidad por fuera y la tienda online por separado. Cada herramienta suelta es un lugar más donde cargar los mismos datos dos veces y una fuente más de inconsistencias.

Pullstok es mi respuesta a eso: un ERP SaaS multi-tenant que junta toda la operación de una empresa en un solo lugar, desde el mostrador hasta la contabilidad. No es un trabajo para un cliente: es un producto propio, que diseño, construyo, despliego y opero de punta a punta.

Un solo sistema

Del presupuesto a la venta y de la venta a la factura electrónica, sin volver a cargar nada. El siguiente paso, en desarrollo: que cada operación genere su asiento contable.

Cada comercio, aislado

Todos los comercios comparten la plataforma, pero cada uno ve solo sus productos, sus clientes y sus ventas.

Conectado al mostrador

Impresoras térmicas, balanzas con etiqueta de peso, lector de códigos con la cámara y cobro con QR de Mercado Pago.

Qué hace

Venta y mostrador

Circuito comercial

Fiscal y contable

Canales digitales

Plataforma

Arquitectura

Pullstok es un monorepo con pnpm workspaces y cinco aplicaciones, cada una con una responsabilidad clara:

LandingAstro
App ERPReact · Vite · TanStack Query
TiendaAstro SSR · islas React
Print agentNode SEA · Windows
HTTPS · JWT · Socket.io
APIExpress · TypeScript · Zod · Prisma 7
datos e integraciones
PostgreSQL70 modelos
Cloudflare R2imágenes y backups
ARCAWSAA · WSFEv1 · padrón
Mercado PagoQR · OAuth
GroqLLM para los bots

Multi-tenancy y seguridad

Decisiones técnicas destacadas

01

Aislamiento de comercios en el ORM

En un SaaS multi-tenant, el peor bug posible es que un comercio vea datos de otro. En lugar de confiar en acordarme de filtrar en cada consulta, el filtro vive en una extensión de Prisma alimentada por AsyncLocalStorage. Olvidarse el filtro deja de ser posible: la consulta falla.

02

ARCA desde cero, sobre SOAP

Sin SDK de terceros: firma del ticket de acceso como CMS/PKCS#7 con node-forge, WSAA para autenticar y WSFEv1 para autorizar comprobantes. El ticket se cachea solo en memoria y la clave privada de cada comercio se guarda cifrada con AES-256-GCM. Cada comercio sube su propio certificado y puede probar en homologación antes de pasar a producción.

03

Puente nube a hardware local

Un navegador no puede imprimir RAW en una térmica. El print agent es un ejecutable único de Node (SEA) que escucha solo en localhost con lista de orígenes permitidos y manda bytes ESC/POS al spooler de Windows. Para imprimir desde el celular, el agente se vincula con un código y consulta la API por trabajos de impresión, con heartbeat y backoff.

04

Plata en centavos, fiscal correcto

La conversión de venta a factura calcula el neto desde precios con IVA incluido y transforma descuentos y recargos en líneas propias, para que lo facturado coincida exactamente con lo cobrado. Los asientos contables se generan con reglas puras, todo en centavos enteros.

05

Ventas que no se pierden

El POS sigue vendiendo sin internet y sincroniza después de forma idempotente. El cobro con QR de Mercado Pago se crea, se consulta hasta que se acredita y recién ahí la venta lo reclama de forma atómica, para que un pago nunca quede asociado a dos ventas.

Calidad y testing

Infra y deploy

Cómo lo construyo

Cada cambio arranca con una especificación escrita: objetivo, decisiones, hallazgos de la exploración del código, qué entra y qué no, y una lista de tareas. Trabajo con un flujo de desarrollo guiado por specs y asistido por IA, donde yo defino la arquitectura y las decisiones, y uso agentes para explorar, implementar y revisar, con memoria persistente entre sesiones y una revisión antes de cada push. Los commits siguen conventional commits.

Números

1.100+ commits

Con conventional commits y deploy continuo a producción.

70 modelos de datos

Alrededor de 100 migraciones de Prisma sobre PostgreSQL.

~280 endpoints

Repartidos en unos 57 routers de la API.

500+ archivos de test

Entre la API, el front y el agente de impresión.

Estado

Pullstok está en producción y en desarrollo activo. Hoy el foco está en el módulo contable. Cada módulo nuevo (las balanzas, el POS offline, el cobro con QR, la contabilidad) sale de necesidades reales de los comercios que ya lo usan.