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.
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 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 Capa 2 — React Providers & Hooks
Capa de pegamento entre los clientes headless y la UI. CartProvider, WishlistProvider, SupabaseAuthProvider, hooks de listado y auth.
CartProviderWishlistProviderSupabaseAuthProvideruseCartuseWishlistuseProductsPage 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.
Cliente abre el storefront
UI Next.js 15 SSR. Página de listado busca productos en Elasticsearch vía ProductService (server-side).
Cliente busca un producto
UI → Headless Búsqueda facetada en Elasticsearch. Resultados con collapse por modelo, brands, categorías, productos relacionados vía Levenshtein.
Cliente hace login
Auth SupabaseAuthProvider abre flujo Supabase. Token vuelve al client + server. CartProvider sincroniza carrito local con Odoo.
Cliente agrega al carrito
React → Headless → Odoo useCart() llama CartService.addToCart(). Token Supabase atraviesa hacia Odoo vía OdooHttpClient. Estado se actualiza en React.
Checkout
Headless → Odoo AddressService busca direcciones. DeliveryCarriersService calcula envíos. SalesService confirma pedido en Odoo. Fiscal nativo (NF-e/NFS-e).
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.