Documentación técnica

Arquitectura headless en 4 capas

Cada capa con responsabilidad clara, dependencia solo en la de abajo. Cambia la UI sin tocar el carrito. Cambia el backend sin reescribir providers.

4

Capa 4 — App / Storefront

App Next.js 15 que compone las 3 capas en una tienda real. App router (rutas dinámicas vía Supabase), middleware (auth/rate limit), CMS para edición visual, integraciones con gateways de pago, SEO (sitemap, robots, metadata), deploy Vercel.

app routermiddleware.tsCMSpagossitemap/robotsVercel deploy
3

Capa 3 — UI

Componentes opinados (Tailwind + Radix). ~20 componentes de dominio (ProductCard, CartDrawer, ProductFilters, HeroCarousel, etc.) + primitives. Tema vía CSS vars HSL compatible con shadcn.

ProductCardCartDrawerProductGalleryProductFiltersGlobalHeaderFooter
2

Capa 2 — React Providers & Hooks

Capa de pegamento entre los clientes headless y la UI. CartProvider, WishlistProvider, SupabaseAuthProvider, hooks de listado y auth.

CartProviderWishlistProviderSupabaseAuthProvideruseCartuseWishlistuseProductsPage
1

Capa 1 — Clientes Headless

Sin React, sin Next.js. Clases puras con auth/logger/fetcher inyectables. Corre en cualquier runtime (Node, edge, worker).

OdooHttpClientProductServiceCartServiceSalesServiceAddressService

Principios de diseño

Lo que sostiene la coherencia de las libs.

Headless por defecto

Ninguna lib (excepto la capa React y UI) conoce React, Next.js o framework de UI. Todo acepta fetch, auth, logger y storage como dependencias inyectadas.

Config explícito

Ninguna lib lee process.env directamente. URLs, secrets y flags llegan vía constructor. Facilita tests y deploys multi-ambiente.

Reemplazable

Cada servicio es una clase; el consumidor puede subclassear o cambiar por un mock en tests sin tocar el resto. Sin vendor lock-in interno.

Tipado y testeado

TypeScript strict, ESM. Tests Vitest cubren helpers puros, HTTP client, cart, JWT, rate limit, storage. CI verde en GitHub Actions.

Flujo de datos típico

Desde el cliente abriendo la tienda hasta el pedido confirmado.

1

Cliente abre el storefront

UI

Next.js 15 SSR. Página de listado busca productos en Elasticsearch vía ProductService (server-side).

2

Cliente busca un producto

UI → Headless

Búsqueda facetada en Elasticsearch. Resultados con collapse por modelo, brands, categorías, productos relacionados vía Levenshtein.

3

Cliente hace login

Auth

SupabaseAuthProvider abre flujo Supabase. Token vuelve al client + server. CartProvider sincroniza carrito local con Odoo.

4

Cliente agrega al carrito

React → Headless → Odoo

useCart() llama CartService.addToCart(). Token Supabase atraviesa hacia Odoo vía OdooHttpClient. Estado se actualiza en React.

5

Checkout

Headless → Odoo

AddressService busca direcciones. DeliveryCarriersService calcula envíos. SalesService confirma pedido en Odoo. Fiscal nativo (NF-e/NFS-e).

6

Pago y fulfillment

Odoo

Pago vía Pix Cobrança / boleto-híbrido / tarjeta (gateway Odoo). Webhook llega a Odoo, libera fulfillment. Stock baja.

Seguridad y auth

Cookies HttpOnly, JWT, rate limit, logs estructurados.

Auth shopper vía Supabase

Token JWT de Supabase atraviesa a Odoo vía OdooHttpClient con getExtraHeaders. Sin replanillar usuarios, sin dos sistemas de contraseña.

Sesión admin con JWT en cookie HttpOnly

Paquete @kmee/admin-session: jose para JWT, helpers Next.js, getClientIp agnóstico de runtime, AdminRateLimiter con store enchufable (memoria default, Redis/KV en prod).

Rate limit configurable

Por IP, por endpoint, por usuario. Mitigación de brute force, abuso de API y scraping de catálogo.

Logs estructurados

Logger inyectable con niveles. Fácil de enchufar en Datadog, Sentry, Grafana, ELK. Sin PII en bruto en los logs por diseño.

¿Quiere hablar con la ingeniería de KMEE?

Tiene duda específica sobre flujo de auth, multi-tenant, integración con gateway? Agende una conversación técnica.