Arquitectura

Wafle es un SaaS multi-tenant pensado para que un LLM (Claude, principalmente) opere tu tienda como ciudadano de primera. Esto cambia varias decisiones de arquitectura comparado con Shopify o Tiendanube. Esta página resume el shape del sistema y para qué sirve cada pieza.

Diagrama de alto nivel

                              ┌──────────────────────────────────────┐
                              │            wafle.click               │
                              │       (nginx frontdoor + WAF)        │
                              └────┬───────────┬───────────┬─────────┘
                                   │           │           │
                  ┌────────────────▼─┐   ┌─────▼──────┐    ▼
                  │ landing :3010    │   │ admin :3005│   /wp-json/* → php-fpm (core)
                  │  (Next 14 SSG)   │   │ (Next 14)  │   /mcp/*    → mcp-gateway
                  └──────────────────┘   └─────┬──────┘
                                               │
                       ┌───────────────────────┴──────────────────────┐
                       │                                              │
                       ▼                                              ▼
           ┌─────────────────────────┐                   ┌──────────────────────────┐
           │  Control plane (shared) │                   │  Tenant containers (LXC) │
           │  · Auth, billing        │   ◄──────────►    │  one per store           │
           │  · Identity Graph       │                   │  · WP + waffle-core      │
           │  · Pixel ingest         │                   │  · MariaDB · Redis       │
           │  · MCP gateway          │                   │  · Meilisearch           │
           │  · Email orchestrator   │                   │  · Per-tenant secrets    │
           └────────┬────────────────┘                   └──────────┬───────────────┘
                    │                                               │
                    ▼                                               ▼
            R2 (assets)   Resend (email)   ClickHouse (events)   per-tenant volumes
Por qué un container por tenant
Aislar a nivel LXC nos da tres cosas que Shopify-style multi-tenant no: (1) el blast radius de un plugin malicioso es una sola tienda, (2) cada tenant puede tener versiones distintas del core durante migraciones, y (3) self-hosting Enterprise es literalmente “snapshotear el container”. El costo es overhead de operación, que absorbemos con automation.

Capas

1. Frontdoor (nginx)

Edge único. Termina TLS, hace WAF básico, ratea por host y path, distribuye a marketing SSG, admin Next, MCP gateway o WP core. Tiene rate-limit zones distintas por endpoint: Pixel /track es bursty (200 rps), API normal 20 rps.

2. Marketing site

Next.js 14, este sitio. Static + ISR. Cero estado, deployable a Cloudflare Pages o nginx static. Sirve /, /pricing, /features, /docs, /changelog, /compare.

3. Admin (control plane)

Next.js 14 App Router en /admin. Auth con session cookie firmada. Routes principales:

  • /admin/account — cuenta, billing, créditos AI, claves Anthropic.
  • /admin/stores/<slug>/agent — chat con el agente Claude de la tienda.
  • /admin/stores/<slug>/catalog/add — agregar producto (manual, upload, marketplace, claude).
  • /admin/stores/<slug>/integrations/anthropic — conectar/desconectar claves.
  • /admin/stores/<slug>/emails/{sender,flows,quota} — email marketing.
  • /admin/stores/<slug>/domains — dominio propio (CNAME + TXT).
  • /admin/stores/<slug>/marketing/360 — vista 360 de cliente.
  • /admin/stores/<slug>/payments — MP, Stripe, transferencias.
  • /admin/system/identity-graph — vista cross-tenant del Identity Graph (solo Wafle Network opt-in).

4. Core (WordPress + waffle-core)

Por tenant. WordPress 6.x con un mu-plugin waffle-core de 40+ módulos: catalog, orders, customers, integrations, AFIP, marketplace feeds, automations, warehouse, reviews. Expone /wp-json/waffle/v1/* con OpenAPI 3.1 auto-generada.

¿Por qué WP por debajo? Porque el ecosistema de plugins, gateways de pago AR, integración con AFIP y temas de checkout maduros está ahí. Lo usamos como motor; toda la UX moderna vive en el admin Next.

5. MCP Gateway

Servidor MCP en mcp.wafle.click. Multiplexa por API key tenant-scoped y traduce las tools (catalog.create, orders.fulfill, ads.update_campaign, …) a calls REST contra el container del tenant correcto. Soporta SSE y HTTP streaming.

Detalle de tools, scopes y autenticación en MCP Server.

6. Pixel + Identity Graph

El Pixel se inyecta automáticamente en todos los storefronts Wafle (no tenés que poner nada). Captura page_view, view_item, add_to_cart, begin_checkout, purchase y eventos custom. Persiste en ClickHouse y alimenta el Identity Graph compartido (opt-in del merchant).

Detalle en Pixel y Analytics y Wafle Network.

7. Storage de assets — R2

Imágenes de productos, attachments de chat, exports CSV: todo va a Cloudflare R2 con signed URLs. La quota está atada al plan; el plan Free tiene 5 GB.

8. Email transaccional + marketing — Resend

Wafle es zero-config para email: a los 5 minutos del signup ya estás mandando confirmaciones de orden, abandoned cart y win-back desde un sender pre-warm. Detalle en Email marketing con Wafle.

Multi-tenant: scoping y aislamiento

Tres niveles de aislamiento:

  • Container LXC por tienda — DB, Redis, Meili, filesystem propios. Sin crosstalk por construcción.
  • API keys con scope — formato wpk_ + payload firmado con tenant id, scopes (read/write por dominio) y expiry. Una key fuera de su tenant da 401 en el frontdoor antes de tocar el core.
  • MCP tools con permisos — cada tool declara los scopes que necesita; el gateway niega antes de invocar. Las write-tools requieren approval (ver MCP Server).

Storefront: headless o managed

Headless es el camino recomendado. Wafle te da REST + MCP + Pixel snippet, vos armás tu front en Astro/Next/Remix/Solid o lo que quieras. Para quien no quiere headless, cada tienda viene con un storefront managed en tu-slug.wafle.click con themes editables.

next/app/page.tsxtsx
// Storefront en Next 14, productos vía REST con ISR
const res = await fetch('https://wafle.click/wp-json/waffle/v1/products', {
  headers: { Authorization: `Bearer ${process.env.WAFLE_KEY}` },
  next: { revalidate: 60 },
});
const products = await res.json();

Trade-offs honestos

  • WP por abajo nos da plugin ecosystem y gateways AR, pero también significa que si querés meter mano de bajo nivel vas a encontrar PHP. Lo encapsulamos al mínimo necesario.
  • Container por tenant escala más lento que un schema-multi-tenant clásico. Asumimos esa complejidad nosotros para darte aislamiento real.
  • LLM-first implica que muchos flujos están diseñados pensando en que un agente los ejecuta. Si no querés usar Claude, el dashboard sigue siendo un dashboard común — solo que más liviano.

Siguientes