Saltar al contenido
Caso · 06 / 09← Todos los trabajos

Maderera Juan B. Justo

Una sola plataforma para una maderera: sitio, tienda, mostrador, aserradero, facturación y portales de clientes.

Rol
Diseño y desarrollo full-stack
Stack
Next.js 16 (App Router), React 19, TypeScript, Postgres + Drizzle ORM, Better Auth, Tailwind CSS 4
Sitio público
Sitio públicoCada integración tiene un proveedor de demostración
(01) El problema

Maderera Juan B. Justo vende madera en Mar del Plata desde 1981, con dos sucursales. Ventas, stock, cortes y facturas tenían que vivir en un solo lugar. El mostrador, el aserradero y la tienda online tocan el mismo stock. Clientes y profesionales necesitan cada uno su propia vista de precios y cuenta corriente.

Mi rolDiseñé y construí toda la plataforma, desde el esquema de la base hasta cada pantalla.
(02) ResultadosContados en el código
108páginas en la app
100tablas en Postgres
721tests sobre plata y lógica de corte
(03) Arquitectura

Tres decisiones que lo definieron.

  1. 01

    Cada integración tiene un proveedor de demostración

    Por qué. ARCA, Mercado Pago, WhatsApp y el correo dependen de credenciales que tramita el cliente. Sin ellas, cada módulo usa un proveedor de demostración detrás de la misma interfaz. El circuito completo anda y la pantalla lo avisa.

    El costo. Dos implementaciones por integración para mantener alineadas. La demo puede separarse de la API real sin que nadie lo note.

  2. 02

    Sin RLS: una sola capa de datos en el servidor

    Por qué. La credencial de la base nunca llega al navegador. Toda lectura pasa por el DAL y filtra por el usuario de la sesión. Toda escritura es una Server Action que valida la sesión y después el input con Zod.

    El costo. El DAL es la única línea de defensa. Una query suelta en un componente lo saltearía, y eso solo lo frena la revisión de código.

  3. 03

    El mostrador vende sin internet

    Por qué. Que se corte internet no puede frenar una venta en el mostrador. El mostrador guarda una copia local del catálogo y encola las ventas en IndexedDB. Cada venta lleva un número provisorio por caja y se sube cuando vuelve la conexión.

    El costo. Los precios locales pueden quedar viejos y los números provisorios hay que conciliarlos. El turno no cierra con ventas pendientes.

(04) GaleríaSeguí scrolleando →
Sitio público
Sitio público · La portada del sitio público y la tienda.
Corte a medida
Corte a medida · El cliente arma su despiece en milímetros y ve cómo entra en la placa.
Mostrador
Mostrador · El punto de venta, pensado para el teclado y capaz de trabajar sin conexión.
Facturación
Facturación · Las facturas electrónicas para ARCA, emitidas desde el panel de gestión.
(05) Qué haría después
01Sumar tests de Playwright para la compra, la sincronización offline del mostrador y la emisión de facturas. Hoy no hay tests de interfaz.
02Armar un CI que corra lint, tipos, tests y build en cada push. El repo todavía no tiene pipeline.
03Mandar los errores del servidor a un tracker. Las lecturas degradadas solo van a console.error y en producción nadie las ve.
Próximo proyecto · 07 / 09
El Rey Jesús →Sitio y administrador de contenido para una iglesia
Caso · 06 / 09

Maderera Juan B. Justo

Una sola plataforma para una maderera: sitio, tienda, mostrador, aserradero, facturación y portales de clientes.

Rol
Diseño y desarrollo full-stack
Stack
Next.js 16 (App Router), React 19, TypeScript, Postgres + Drizzle ORM, Better Auth, Tailwind CSS 4
Maderera Juan B. Justo
(01) El problema

Maderera Juan B. Justo vende madera en Mar del Plata desde 1981, con dos sucursales. Ventas, stock, cortes y facturas tenían que vivir en un solo lugar. El mostrador, el aserradero y la tienda online tocan el mismo stock. Clientes y profesionales necesitan cada uno su propia vista de precios y cuenta corriente.

Mi rolDiseñé y construí toda la plataforma, desde el esquema de la base hasta cada pantalla.
(02) Resultados
108páginas en la app
100tablas en Postgres
721tests sobre plata y lógica de corte
(03) Arquitectura

Tres decisiones que lo definieron.

01

Cada integración tiene un proveedor de demostración

Por qué. ARCA, Mercado Pago, WhatsApp y el correo dependen de credenciales que tramita el cliente. Sin ellas, cada módulo usa un proveedor de demostración detrás de la misma interfaz. El circuito completo anda y la pantalla lo avisa.

El costo. Dos implementaciones por integración para mantener alineadas. La demo puede separarse de la API real sin que nadie lo note.

02

Sin RLS: una sola capa de datos en el servidor

Por qué. La credencial de la base nunca llega al navegador. Toda lectura pasa por el DAL y filtra por el usuario de la sesión. Toda escritura es una Server Action que valida la sesión y después el input con Zod.

El costo. El DAL es la única línea de defensa. Una query suelta en un componente lo saltearía, y eso solo lo frena la revisión de código.

03

El mostrador vende sin internet

Por qué. Que se corte internet no puede frenar una venta en el mostrador. El mostrador guarda una copia local del catálogo y encola las ventas en IndexedDB. Cada venta lleva un número provisorio por caja y se sube cuando vuelve la conexión.

El costo. Los precios locales pueden quedar viejos y los números provisorios hay que conciliarlos. El turno no cierra con ventas pendientes.

(04) Galería
Sitio público
Sitio público · La portada del sitio público y la tienda.
Corte a medida
Corte a medida · El cliente arma su despiece en milímetros y ve cómo entra en la placa.
Mostrador
Mostrador · El punto de venta, pensado para el teclado y capaz de trabajar sin conexión.
Facturación
Facturación · Las facturas electrónicas para ARCA, emitidas desde el panel de gestión.
(05) Qué haría después
01Sumar tests de Playwright para la compra, la sincronización offline del mostrador y la emisión de facturas. Hoy no hay tests de interfaz.
02Armar un CI que corra lint, tipos, tests y build en cada push. El repo todavía no tiene pipeline.
03Mandar los errores del servidor a un tracker. Las lecturas degradadas solo van a console.error y en producción nadie las ve.
Próximo proyectoEl Rey Jesús →
Nahuel SantillánES