LUCIANO CARRIZO
Todos los proyectos
Finalizado

PhonEcommerce

E-commerce full-stack de teléfonos móviles: catálogo con filtros, checkout en 3 pasos, historial de órdenes y panel admin. El backend (Fastify 5 + PostgreSQL/Prisma) está armado con Clean Architecture por features y tres ADRs propios; el frontend es Next.js 16. Construido en 6 días con un flujo multiagente propio, 41 commits, todos míos.

Next.jsReactTypeScriptTailwind CSSFastifyPostgreSQLPrisma
Resumen

Un e-commerce completo, construido en 6 días

PhonEcommerce es una tienda online de teléfonos móviles, full-stack: catálogo con filtros, carrito, checkout en tres pasos, historial y cancelación de órdenes, perfil con direcciones y un panel de administración. El frontend es Next.js 16 con React 19, Zustand y Tailwind CSS 4; el backend, Fastify 5 sobre PostgreSQL con Prisma.

Es un proyecto 100% propio: 41 commits, todos míos, sin fork ni upstream que acreditar. El primer commit es del 2026-05-06 y el último del 2026-05-11 — una ventana de 6 días de punta a punta, ya incluido el panel admin.

Ese número es el que obliga a explicar dos cosas, y son las dos zonas que siguen: cómo está armado el backend (Clean Architecture por features, con tres ADRs escritos) y cómo se organizó el trabajo (un flujo multiagente con agentes especializados por dominio). El primero es lo que sostiene el proyecto; el segundo es lo que explica el calendario.

Clean Architecture

Cuatro capas, una vez por feature — no una vez por proyecto

El backend no está organizado por tipo de archivo (controllers/, services/, models/) sino por feature, y dentro de cada feature aparecen las cuatro capas de Clean Architecture. El primer commit del repo ya lo dice en su mensaje —“initial project setup with Clean Architecture backend and feature-based frontend”—, así que no es algo que se acomodó después: es el punto de partida.

backend/src/<feature>/
  domain/          ← entidades e interfaces, sin dependencias externas
  application/     ← use-cases
  infrastructure/  ← repositorios Prisma
  presentation/    ← controllers y routes Fastify

La dirección de las dependencias es lo que hace que esto valga la pena. domain/ no importa nada de afuera: define las entidades y, sobre todo, las interfaces de los repositorios. application/ contiene los use-cases y depende únicamente de esas interfaces. Recién en infrastructure/ aparece Prisma, implementándolas, y en presentation/ aparece Fastify. El resultado es que ni el ORM ni el framework HTTP están tocando las reglas del negocio: son detalles enchufados en los bordes.

Que el corte primario sea la feature y no la capa es la decisión propiamente dicha, y está escrita como ADR: docs/decisions/001-clean-architecture-by-features.md. Cada feature funciona como un contexto acotado con sus cuatro capas adentro, así que todo lo que hace falta para tocar “stock” o “órdenes” vive junto, en vez de repartido en cuatro carpetas lejanas del árbol.

Decisión

Tres decisiones escritas, no tres decisiones recordadas

El repo trae docs/decisions/ con tres ADRs: 001-clean-architecture-by-features.md, 002-jwt-with-refresh-tokens.md y 003-prisma-postgresql.md. Escribirlos es lo que separa una arquitectura elegida de una arquitectura heredada de un tutorial: cada uno deja registrado qué se decidió y por qué, y sirve de referencia cuando aparece la tentación de romper la regla por comodidad.

El costo: mucha más ceremonia por endpoint

Cuatro capas por feature significa que agregar una operación trivial toca varios archivos —entidad e interfaz en domain, use-case en application, repositorio en infrastructure, controller y route en presentation— donde un CRUD directo contra Prisma habría sido un archivo. Es el precio explícito de esta arquitectura, y se paga en cada feature nueva. Lo que se compra a cambio se ve en la zona de testing.

El frontend sigue el mismo criterio de corte, aunque sin las capas: features/<feature>/ con sus components, hooks, services y types, shared/ para lo reutilizable entre features, y app/ para las rutas del App Router de Next.js.

El flujo multiagente

Agentes especializados por dominio, con firma en el TODO

Los 6 días no salen de trabajar más horas: salen de cómo se repartió el trabajo. El proyecto se construyó con un flujo multiagente propio — el repo trae su propia carpeta .agents/ (agents, skills, workflows), el mismo patrón con el que está hecho este portafolio.

La evidencia más concreta está en docs/TODO.md, donde las entradas vienen firmadas por el agente que las agregó:

Agregado por: agente-principal - 2026-05-06
agregado por: agente-backend-stock - 2026-05-06

No es una anécdota de proceso: es exactamente el mismo corte que la arquitectura. Hay un agente-principal que coordina y agentes especializados por dominio —agente-backend-stock es el que quedó firmado— trabajando cada uno sobre su feature. Que el backend esté cortado por bounded context es lo que hace posible que varios frentes avancen sin pisarse: si el corte hubiera sido por capa, cualquier feature nueva habría tocado las mismas cuatro carpetas que todas las demás.

Dicho de otro modo: la arquitectura de la zona anterior no es solo una decisión de código, también es la que habilitó la forma de trabajo — y el calendario que salió de ella.

El producto

Tienda completa y panel de administración, no una demo de catálogo

El alcance no se quedó en la vidriera. Estas son las funcionalidades que el proyecto tiene terminadas, según el README del repo:

01

Catálogo con filtros

El listado de productos con filtrado, que es la puerta de entrada de la tienda.

02

Checkout en 3 pasos

El flujo de compra dividido en tres etapas, en vez de un formulario único.

03

Historial y cancelación de órdenes

El cliente ve sus compras anteriores y puede cancelar una orden — la parte de post-venta que suele quedar afuera de un proyecto de práctica.

04

Perfil con direcciones

Cuenta de usuario con gestión de direcciones de envío.

05

Panel admin

CRUD de productos, marcas y categorías; control de stock con historial de movimientos; y gestión de órdenes.

El panel admin es la mitad que decide si esto es una tienda o una maqueta: sin CRUD de catálogo ni control de stock, el catálogo del cliente sería contenido fijo. Acá el stock además guarda historial de movimientos, no solo el número actual.

Testing

34 tests en el backend, cero en el frontend, sin CI

Acá se cobra la ceremonia de las cuatro capas. Con los use-cases dependiendo de interfaces y no de Prisma, cada capa se puede testear aislada sin levantar una base de datos: el backend tiene 34 archivos de test corriendo con Vitest.

El otro lado del número es igual de real: el frontend tiene 0 tests, y no hay CI — no existe .github/ en el repo, así que esos 34 tests corren cuando alguien los corre a mano, no en cada push. Están escritos, no automatizados.

Lo digo tal cual porque el caso no mejora escondiéndolo: en 6 días se priorizó cubrir la lógica de negocio del backend, que es donde una regresión rompe datos, y quedó afuera todo lo demás. Es un proyecto real con su recorte real, no uno idealizado.

Cierre

Lo que queda de haber decidido antes de escribir

La autenticación es el ejemplo más chico y más claro de cómo funcionó esto: JWT con access token de 15 minutos más refresh token con rotación, decidido y escrito en docs/decisions/002-jwt-with-refresh-tokens.md antes de existir como código. La rotación no es lo que sale por defecto de un tutorial de JWT — es una decisión que se toma sabiendo qué se está mitigando.

El proyecto está finalizado: 41 commits propios, 6 días, un backend con Clean Architecture por features y tres ADRs, un flujo multiagente que lo construyó y un producto completo hasta el panel admin. Lo que me llevo es que las dos mitades se sostienen entre sí: la arquitectura por bounded context es lo que hizo posible repartir el trabajo entre agentes, y ese reparto es lo que explica el calendario. Ninguna de las dos, sola, da 6 días.

Siguiente paso

El caso muestra el código. Hablemos de lo que sigue.

PhonEcommerce está documentado end-to-end: arquitectura, decisiones y lo que quedó pendiente. Si tenés preguntas sobre el enfoque, escribime.

Hablemos

o directamente → LuchoC.dev@gmail.com