--- id: EPIC-MCH-029 type: Epic title: "MCH-029: Infraestructura SaaS Avanzada" code: MCH-029 status: Planificado phase: 7 priority: P0 created_at: 2026-01-10 updated_at: 2026-01-10 simco_version: "4.0.1" dependencies: blocks: ["MCH-030", "MCH-032", "MCH-033"] depends_on: [] --- # MCH-029: Infraestructura SaaS Avanzada ## Metadata - **Codigo:** MCH-029 - **Fase:** 7 - Expansion - **Prioridad:** P0 (Critica) - **Estado:** Planificado - **Story Points:** 24 - **Sprint Objetivo:** Sprint 6-7 ## Descripcion Implementar infraestructura SaaS empresarial que incluye sistema de Email Multi-proveedor, Storage Abstracto en la nube, Redis como cache/queue, Webhooks Outbound con reintentos y Rate Limiting por plan. Esta epica es la base para las capacidades SaaS avanzadas. ## Objetivos 1. Establecer sistema de email multi-proveedor con fallback 2. Implementar storage abstracto compatible con S3/R2/MinIO 3. Configurar Redis para cache y colas 4. Habilitar webhooks outbound con estrategia de reintentos 5. Implementar rate limiting por plan de suscripcion ## Alcance ### Incluido - Email transaccional con SendGrid, SES y SMTP - Storage cloud con URLs firmadas - Redis cache con TTL configurable - BullMQ para procesamiento en background - Rate limiting con token bucket - Webhooks con firma HMAC-SHA256 ### Excluido - Push notifications (ver MCH-034) - Email marketing masivo - CDN para assets estaticos ## Arquitectura ``` ┌─────────────────────────────────────┐ │ MCH-029: Infraestructura │ └─────────────────────────────────────┘ │ ┌──────────────┬──────────────┼──────────────┬──────────────┐ ▼ ▼ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Email │ │ Storage │ │ Redis │ │ Webhooks │ │ Rate │ │ Provider │ │ Provider │ │ Cache │ │ Outbound │ │ Limiting │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ │ ┌────┴────┐ ┌────┴────┐ │ ┌────┴────┐ │ │SendGrid │ │ S3 │ │ │ BullMQ │ │ │ SES │ │ R2 │ │ │ Queue │ │ │ SMTP │ │ MinIO │ │ │ │ │ └─────────┘ └─────────┘ │ └─────────┘ │ │ │ ┌─────┴────────────────────────────┘ │ Redis Server │ └──────────────────────────────────┘ ``` ## Entregables | Entregable | Estado | Sprint | Ubicacion | |------------|--------|--------|-----------| | Email module con multi-provider | Planificado | 6 | `apps/backend/src/modules/email/` | | Storage module abstracto | Planificado | 6 | `apps/backend/src/modules/storage/` | | Redis cache/queue config | Planificado | 6 | `apps/backend/src/modules/redis/` | | Webhooks module | Planificado | 7 | `apps/backend/src/modules/webhooks/` | | Rate limiting guard | Planificado | 7 | `apps/backend/src/common/guards/` | | DDL storage schema | Planificado | 6 | `database/schemas/12-storage.sql` | | DDL webhooks schema | Planificado | 7 | `database/schemas/15-webhooks.sql` | ## Dependencias ### Depende de - Ninguna (epica base de infraestructura) ### Bloquea a - MCH-030 (Auth Social) - requiere email para verificacion - MCH-032 (Feature Flags) - requiere Redis para cache - MCH-033 (Onboarding) - requiere infraestructura completa --- ## Historias de Usuario ### MCH-US-101: Email Multi-proveedor **Como** administrador del sistema **Quiero** enviar emails transaccionales via multiples proveedores **Para** garantizar entrega y tener fallback **Story Points:** 5 **Criterios de Aceptacion:** - [CA-101-1] Soporta SendGrid como proveedor principal - [CA-101-2] Soporta AWS SES como fallback - [CA-101-3] Soporta SMTP generico como ultimo recurso - [CA-101-4] Templates reutilizables con variables Handlebars - [CA-101-5] Tracking de entrega (opens, clicks si proveedor soporta) - [CA-101-6] Rate limiting por tenant (max emails/hora) **Tareas:** | ID | Tarea | Tipo | SP | |----|-------|------|-----| | MCH-TT-101-01 | DDL tabla email_templates | DDL | 0.5 | | MCH-TT-101-02 | DDL tabla email_logs | DDL | 0.5 | | MCH-TT-101-03 | Servicio EmailProviderFactory | Backend | 0.5 | | MCH-TT-101-04 | Implementar SendGridProvider | Backend | 1 | | MCH-TT-101-05 | Implementar SESProvider | Backend | 1 | | MCH-TT-101-06 | Implementar SMTPProvider | Backend | 0.5 | | MCH-TT-101-07 | Controlador EmailController | Backend | 0.5 | | MCH-TT-101-08 | Tests unitarios | Test | 0.5 | | MCH-TT-101-09 | Documentacion INT-010 | Docs | 0 | --- ### MCH-US-102: Storage Abstracto **Como** usuario **Quiero** subir archivos (imagenes, facturas) a la nube **Para** tener respaldo seguro y acceso desde cualquier dispositivo **Story Points:** 8 **Criterios de Aceptacion:** - [CA-102-1] Soporta AWS S3 como proveedor principal - [CA-102-2] Soporta Cloudflare R2 como alternativa economica - [CA-102-3] Soporta MinIO para desarrollo local - [CA-102-4] Limites de almacenamiento por plan (Basic: 1GB, Pro: 10GB, Enterprise: 100GB) - [CA-102-5] Organizacion de archivos en carpetas virtuales - [CA-102-6] URLs firmadas con expiracion configurable - [CA-102-7] Metadata de archivos (size, mime_type, upload_date) - [CA-102-8] Validacion de tipos MIME permitidos **Tareas:** | ID | Tarea | Tipo | SP | |----|-------|------|-----| | MCH-TT-102-01 | DDL schema storage (files, folders, usage) | DDL | 1 | | MCH-TT-102-02 | Servicio StorageProviderFactory | Backend | 0.5 | | MCH-TT-102-03 | Implementar S3Provider | Backend | 1.5 | | MCH-TT-102-04 | Implementar R2Provider | Backend | 1 | | MCH-TT-102-05 | Implementar MinIOProvider | Backend | 0.5 | | MCH-TT-102-06 | Controlador StorageController | Backend | 1 | | MCH-TT-102-07 | Middleware limite por plan | Backend | 0.5 | | MCH-TT-102-08 | Generacion URLs firmadas | Backend | 0.5 | | MCH-TT-102-09 | Tests unitarios e integracion | Test | 1 | | MCH-TT-102-10 | Documentacion INT-011 | Docs | 0.5 | --- ### MCH-US-103: Redis Cache y Queue **Como** sistema **Quiero** utilizar Redis como cache y queue **Para** mejorar rendimiento y procesar tareas en background **Story Points:** 3 **Criterios de Aceptacion:** - [CA-103-1] Cache de sesiones JWT con TTL - [CA-103-2] Cache de configuracion de tenant - [CA-103-3] Queue para emails, webhooks, notificaciones via BullMQ - [CA-103-4] Health check endpoint de Redis - [CA-103-5] Metricas de uso (hits/misses, queue length) **Tareas:** | ID | Tarea | Tipo | SP | |----|-------|------|-----| | MCH-TT-103-01 | Configuracion Redis module | Backend | 0.5 | | MCH-TT-103-02 | Cache service con TTL | Backend | 0.5 | | MCH-TT-103-03 | BullMQ integration | Backend | 0.5 | | MCH-TT-103-04 | Queue processors base | Backend | 0.5 | | MCH-TT-103-05 | Health check endpoint | Backend | 0.25 | | MCH-TT-103-06 | Tests | Test | 0.5 | | MCH-TT-103-07 | Documentacion INT-013 | Docs | 0.25 | --- ### MCH-US-104: Webhooks Outbound **Como** administrador de tenant **Quiero** configurar webhooks para recibir notificaciones de eventos **Para** integrar con sistemas externos **Story Points:** 5 **Criterios de Aceptacion:** - [CA-104-1] CRUD de endpoints webhook por tenant - [CA-104-2] Seleccion de eventos a suscribirse (order.created, payment.completed, etc) - [CA-104-3] Firma de payloads con HMAC-SHA256 - [CA-104-4] Reintentos con exponential backoff (1s, 2s, 4s, 8s, 16s) - [CA-104-5] Logs de entregas con response status **Tareas:** | ID | Tarea | Tipo | SP | |----|-------|------|-----| | MCH-TT-104-01 | DDL schema webhooks (endpoints, deliveries) | DDL | 0.5 | | MCH-TT-104-02 | Servicio WebhookService | Backend | 1 | | MCH-TT-104-03 | Job processor con BullMQ | Backend | 1 | | MCH-TT-104-04 | Firma HMAC de payloads | Backend | 0.5 | | MCH-TT-104-05 | Controlador WebhooksController | Backend | 0.5 | | MCH-TT-104-06 | UI en portal admin | Frontend | 0.5 | | MCH-TT-104-07 | Tests | Test | 0.5 | | MCH-TT-104-08 | Documentacion INT-014 | Docs | 0.5 | --- ### MCH-US-112: Rate Limiting por Plan **Como** sistema **Quiero** limitar las solicitudes API segun el plan del tenant **Para** garantizar uso justo y proteger la infraestructura **Story Points:** 3 **Criterios de Aceptacion:** - [CA-112-1] Limite de requests/minuto configurable por plan - [CA-112-2] Limite de requests/dia configurable por plan - [CA-112-3] Headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset - [CA-112-4] Respuesta 429 Too Many Requests con Retry-After - [CA-112-5] Bypass para webhooks internos y health checks **Tareas:** | ID | Tarea | Tipo | SP | |----|-------|------|-----| | MCH-TT-112-01 | Implementar middleware RateLimitGuard | Backend | 0.5 | | MCH-TT-112-02 | Configuracion limites en plans | Backend | 0.5 | | MCH-TT-112-03 | Almacenamiento contadores en Redis | Backend | 0.5 | | MCH-TT-112-04 | Headers de respuesta | Backend | 0.25 | | MCH-TT-112-05 | Tests | Test | 0.5 | | MCH-TT-112-06 | Documentar en ADR-0009 | Docs | 0.25 | --- ## Resumen de Story Points | Historia | SP | Sprint | |----------|-----|--------| | MCH-US-101: Email Multi-proveedor | 5 | 6 | | MCH-US-102: Storage Abstracto | 8 | 6 | | MCH-US-103: Redis Cache y Queue | 3 | 6 | | MCH-US-104: Webhooks Outbound | 5 | 7 | | MCH-US-112: Rate Limiting | 3 | 7 | | **TOTAL** | **24** | 6-7 | --- ## Criterios de Aceptacion de Epica - [ ] Email enviado exitosamente con cada proveedor - [ ] Archivos subidos a S3 con URL firmada funcional - [ ] Redis cache reduce latencia en >50% - [ ] Webhook entregado con reintentos exitosos - [ ] Rate limiting bloquea requests excedentes - [ ] Cobertura de tests >80% - [ ] Documentacion de integraciones completa ## Notas Tecnicas - **Redis:** Puerto 6379, DB 0 para cache, DB 1 para queues - **S3 Region:** us-east-1 (default) - **R2 Region:** auto - **Email Rate:** Max 1000/tenant/hora en plan Pro ## Integraciones Relacionadas - [INT-010: Email Providers](../02-integraciones/INT-010-email-providers.md) - [INT-011: Storage Cloud](../02-integraciones/INT-011-storage-cloud.md) - [INT-013: Redis Cache](../02-integraciones/INT-013-redis-cache.md) - [INT-014: Webhooks Outbound](../02-integraciones/INT-014-webhooks-outbound.md) ## ADRs Relacionados - [ADR-0006: Storage Abstraction](../97-adr/ADR-0006-storage-abstraction.md) - [ADR-0007: Webhook Retry Strategy](../97-adr/ADR-0007-webhook-retry-strategy.md) - [ADR-0009: Rate Limiting Strategy](../97-adr/ADR-0009-rate-limiting.md) - [ADR-0011: Email Multi-provider](../97-adr/ADR-0011-email-multi-provider.md) --- ## Especificaciones Tecnicas Detalladas ### Email: Templates Incluidos (Ref: SAAS-013) | Key | Descripcion | |-----|-------------| | welcome | Email de bienvenida | | password_reset | Reset de contrasena | | invitation | Invitacion a tenant | | notification | Notificacion generica | | order_confirmation | Confirmacion de pedido | | payment_reminder | Recordatorio de pago (fiados) | ### Storage: Flujo de Upload (Ref: SAAS-011) ``` 1. Cliente solicita upload URL POST /storage/upload-url Body: { filename, mimeType, sizeBytes, folder?, visibility? } 2. Backend valida: - Tipo MIME permitido - Extension no bloqueada - Tamano dentro de limite - Espacio disponible 3. Backend genera presigned URL (AWS SDK v3) - Expira en 15 minutos - Limite de tamano 4. Cliente sube directo a S3/R2 PUT [presigned-url] 5. Cliente confirma POST /storage/confirm Body: { uploadId, metadata? } 6. Backend crea registro en storage.files ``` ### Storage: Limites por Plan | Plan | Storage | Max Archivo | |------|---------|-------------| | Changarrito | 500 MB | 10 MB | | Tiendita | 2 GB | 50 MB | | Tienda Pro | 10 GB | 100 MB | ### Webhooks: Eventos Disponibles (Ref: SAAS-010) | Evento | Descripcion | Payload | |--------|-------------|---------| | sale.created | Venta registrada | Sale object | | sale.cancelled | Venta cancelada | { saleId } | | customer.created | Cliente creado | Customer | | fiado.created | Fiado registrado | Fiado | | fiado.payment | Abono a fiado | FiadoPayment | | inventory.low | Stock bajo | { productId, current, min } | | order.created | Pedido WhatsApp | Order | | order.status_changed | Cambio estado pedido | Order + prevStatus | | subscription.created | Nueva suscripcion | Subscription | | subscription.cancelled | Suscripcion cancelada | Subscription | ### Webhooks: Logica de Reintentos ``` Intento 1: Inmediato Intento 2: +1 minuto Intento 3: +5 minutos Intento 4: +30 minutos Intento 5: +2 horas Intento 6: +6 horas Despues: Marcar como fallido ``` ### Webhooks: Headers Enviados ``` X-Webhook-Signature: t=1704067200000,v1=abc123... X-Webhook-Id: X-Webhook-Event: sale.created X-Webhook-Timestamp: 1704067200000 X-Webhook-Delivery: ``` ### Webhooks: Limites por Plan | Plan | Webhooks | Eventos/mes | |------|----------|-------------| | Changarrito | 2 | 5,000 | | Tiendita | 5 | 20,000 | | Tienda Pro | 10 | 100,000 | ### Rate Limiting: Limites por Plan | Plan | Requests/min | Requests/dia | |------|--------------|--------------| | Changarrito | 60 | 10,000 | | Tiendita | 120 | 50,000 | | Tienda Pro | 300 | 200,000 | --- ## Referencia Template-SaaS Esta epica esta alineada con los siguientes modulos de template-saas: | Modulo SAAS | Version | Elementos Integrados | |-------------|---------|---------------------| | SAAS-010 Webhooks | 1.0.0 | Eventos, reintentos, firma HMAC | | SAAS-011 Storage | 1.0.0 | Presigned URLs, limites, providers | | SAAS-013 Email | 1.0.0 | Multi-provider, templates | Ver documentacion fuente en `projects/template-saas/docs/01-modulos/` --- **Ultima actualizacion:** 2026-01-13 **Autor:** Architecture Team **Alineacion:** template-saas v1.0.0