← /projects

In Progress

diSastre

Desarrollo full stack de tienda online de indumentaria femenina argentina

Di Sástre es una tienda online de indumentaria femenina argentina, construida desde cero como un sistema full-stack de producción. El proyecto va mucho más allá de un e-commerce convencional: integra un backend orientado a eventos con procesamiento asíncrono, cumplimiento legal completo con la legislación argentina de protección de datos, notificaciones push, comunicaciones masivas automatizadas y un panel de administración propio. El stack combina Angular en el frontend con NestJS en el backend, orquestando cinco servicios externos (Strapi, Firebase, Resend, Cloudflare R2 y Redis) en una arquitectura modular, segura y lista para escalar.

AngularTailwindCSSNestJSSwaggerFirebaseAxiosCloudflareRedis
Captura de diSastre

El Problema que Resuelve

Las marcas de moda independientes en Argentina necesitan algo más que un carrito de compras. Necesitan cumplir con la Ley 25.326 de Protección de Datos Personales y la Ley 24.240 de Defensa del Consumidor, gestionar comunicaciones con su base de clientes, y tener control total sobre su contenido sin depender de plataformas cerradas. Di Sástre fue diseñado para cubrir exactamente eso: una plataforma propia, extensible y legalmente sólida.

Frontend — Angular 19 con Arquitectura Moderna

El frontend está construido con Angular usando exclusivamente Standalone Components, eliminando por completo los NgModules tradicionales. Esto reduce el boilerplate, mejora el tree-shaking y hace que cada componente sea una unidad autónoma y testeable.

Gestión de Estado con Signals

Uno de los elementos más modernos del proyecto es el uso de Angular Signals para la gestión de estado reactivo, en particular en el carrito de compras. En lugar de depender de soluciones externas como NgRx o BehaviorSubjects, el estado del carrito vive en signals nativos del framework, lo que garantiza reactividad granular y un rendimiento óptimo sin overhead adicional.

Lazy Loading y Performance

Todas las rutas de la aplicación implementan lazy loading mediante la API de rutas standalone de Angular. El resultado es un bundle inicial de apenas 259 KB — un número excelente para una aplicación de esta complejidad. Las imágenes se optimizan con `NgOptimizedImage`, que gestiona automáticamente el lazy loading nativo del navegador y los atributos de tamaño para evitar el Cumulative Layout Shift (CLS).

Interceptores HTTP Estratificados

La capa HTTP del frontend está gestionada por cuatro interceptores encadenados:

  • Auth Interceptor: Inyecta el token JWT en cada request autenticado.
  • Error Interceptor: Centraliza el manejo de errores HTTP, mostrando mensajes contextuales al usuario.
  • Strapi Interceptor: Transforma automáticamente la estructura de respuesta de Strapi (con su formato `data.attributes`) al modelo de dominio de la aplicación, desacoplando el frontend del CMS.

Módulo de Tienda Completo

La experiencia de compra cubre el flujo completo:

  • Catálogo con grid de productos, filtros por categoría y búsqueda en tiempo real.
  • Detalle de producto con galería de imágenes, selector de talles y colores, y descripción enriquecida renderizada desde el editor Quill del CMS.
  • Carrito lateral (drawer) con gestión de cantidades, eliminación de ítems y aplicación de **códigos promocionales** con validación en tiempo real.
  • Checkout con formulario de dirección, resumen de pedido y confirmación.
  • Historial de pedidos con seguimiento de estado desde la cuenta del usuario.

Panel de Administración Integrado

El frontend incluye un panel de administración completo protegido por un guard de rol. Desde ahí, el administrador puede:

  • Gestionar el catálogo de productos y categorías.
  • Ver y gestionar usuarios registrados.
  • Revisar y procesar solicitudes ARCO.
  • Crear y enviar comunicaciones masivas a segmentos de clientes.
  • Gestionar suscriptores al newsletter.
  • Enviar notificaciones push segmentadas.

SEO y Accesibilidad de Producción

El SEO no fue un añadido posterior: cada página tiene meta tags dinámicos, Open Graph tags para redes sociales y JSON-LD Schema.org para productos y organización. La aplicación incluye `sitemap.xml` y `robots.txt` configurados.

En accesibilidad, se implementaron ARIA labels y roles en todos los componentes interactivos, navegación completa por teclado, skip links para lectores de pantalla y estructura HTML semántica.

Backend — NestJS con Arquitectura Orientada a Eventos

El backend es donde la complejidad técnica del proyecto se hace más evidente. Construido con NestJS, sigue una arquitectura modular estricta donde cada dominio de negocio es un módulo independiente con sus propios controladores, servicios y DTOs.

Gateway de Webhooks

El módulo de webhooks actúa como el sistema nervioso central del backend. Recibe eventos de Strapi (creación y actualización de registros) y los enruta al procesador correspondiente. Cada webhook se valida con un token secreto en el header `X-Strapi-Webhook-Token` antes de ser procesado.

Este patrón desacopla completamente el CMS del backend: Strapi no sabe qué hace el backend con los eventos, solo los emite. El backend decide cómo procesarlos.

Sistema ARCO — Cumplimiento con la Ley 25.326

Este es uno de los módulos más innovadores del proyecto. La Ley Argentina 25.326 obliga a las empresas a responder solicitudes de ciudadanos sobre sus datos personales en plazos definidos. El sistema ARCO (Acceso, Rectificación, Cancelación, Oposición) automatiza completamente este proceso.

Cuando un usuario ejerce un derecho desde su cuenta:

  • 1. El frontend crea la solicitud en Strapi.
  • 2. Strapi dispara un webhook al backend.
  • 3. El backend encola la tarea en Redis/Bull para procesamiento asíncrono.
  • 4. El procesador correspondiente ejecuta la lógica específica:
    • Access: Genera un PDF con todos los datos del usuario usando PDFKit y lo envía por email.
    • Rectification: Actualiza los datos del usuario en Strapi según lo solicitado.
    • Deletion: Anonimiza los datos del usuario (cumpliendo el derecho al olvido sin romper la integridad referencial de órdenes históricas).
    • Opposition: Marca al usuario como opuesto al tratamiento de datos, bloqueando futuras comunicaciones de marketing.
  • 5. El estado de la solicitud se actualiza en Strapi en tiempo real.
  • 6. El usuario recibe un email de confirmación con el resultado.

Todo esto ocurre de forma completamente automatizada, sin intervención manual del administrador.

Comunicaciones Masivas con Rate Limiting Inteligente

El módulo de comunicaciones masivas permite enviar emails a segmentos específicos de clientes:

  • `all_customers`: Todos los usuarios con cuenta confirmada.
  • `marketing_consent`: Solo usuarios que dieron consentimiento explícito de marketing.
  • `newsletter_subscribers`: Suscriptores al newsletter.

El sistema resuelve un problema real: los servicios de email tienen límites de envío. La solución implementada divide los destinatarios en lotes de hasta 50 emails, con un delay configurable de 600ms entre lotes para respetar el rate limit de Resend (~100 emails/minuto). El procesamiento ocurre en background mediante colas Bull, y los contadores de enviados/fallidos se actualizan en Strapi en tiempo real para que el administrador pueda monitorear el progreso.

También se implementaron comunicaciones programadas mediante cron jobs de NestJS Schedule, permitiendo programar envíos para fechas y horas específicas.

Colas Asíncronas con Bull + Redis

Tanto el procesamiento ARCO como las comunicaciones masivas utilizan Bull sobre Redis para el procesamiento asíncrono. Esto garantiza:

  • Resiliencia: Si el backend se reinicia durante un procesamiento, las tareas pendientes se retoman automáticamente.
  • Reintentos: Backoff exponencial en caso de fallos transitorios.
  • Desacoplamiento: El webhook responde inmediatamente (HTTP 200) y el trabajo pesado ocurre en background.

Notificaciones Push con Firebase Cloud Messaging

El módulo de notificaciones integra Firebase Admin SDK para enviar notificaciones push a dispositivos suscritos. Los usuarios pueden suscribirse desde el frontend, y el administrador puede enviar notificaciones broadcast o segmentadas desde el panel de admin.

Almacenamiento en Cloudflare R2

La integración con Cloudflare R2 usa el SDK de AWS S3 (R2 es compatible con la API de S3), lo que demuestra conocimiento de las APIs de almacenamiento en la nube y la capacidad de reutilizar SDKs existentes para servicios alternativos más económicos. R2 se usa para almacenar los PDFs generados por las solicitudes ARCO y otros archivos estáticos.

Seguridad en Capas

La seguridad no es un módulo, es una preocupación transversal:

  • Helmet: Configura automáticamente headers HTTP de seguridad (CSP, HSTS, X-Frame-Options, etc.).
  • CORS restrictivo: Solo los orígenes configurados explícitamente pueden hacer requests.
  • Rate Limiting: 100 requests por minuto por IP con `@nestjs/throttler`.
  • Guards duales: Los endpoints de gestión requieren API Key; los webhooks requieren token de validación específico.
  • Validación de entrada: Todos los DTOs usan `class-validator` con validación estricta. El pipe de validación global rechaza propiedades no declaradas (`whitelist: true, forbidNonWhitelisted: true`).
  • Sanitización HTML: Utilidad dedicada para sanitizar contenido HTML antes de procesarlo.

Logging Estructurado con Winston

El sistema de logging usa Winston con formato JSON estructurado, lo que facilita la ingesta en sistemas de observabilidad como Datadog o CloudWatch. El interceptor de logging registra automáticamente cada request con método, ruta, status code y tiempo de respuesta.

Integración con Strapi como Headless CMS

Strapi actúa como el sistema de gestión de contenido y datos del proyecto. Gestiona:

  • Catálogo de productos y categorías.
  • Órdenes de compra.
  • Usuarios y sus datos extendidos.
  • Solicitudes ARCO.
  • Comunicaciones masivas.
  • Consentimientos de privacidad.
  • Suscriptores al newsletter.
  • Reclamos de consumidores.
  • Códigos promocionales.
  • Páginas legales y FAQ.
  • Guías de talla.

La relación entre el backend NestJS y Strapi es bidireccional: el backend consume la API REST de Strapi para leer y escribir datos, y Strapi notifica al backend de eventos relevantes mediante webhooks.

Cumplimiento Legal — Un Diferenciador Real

Pocos proyectos de e-commerce independientes implementan cumplimiento legal real. Di Sástre lo hace de forma completa:

Ley 25.326 — Protección de Datos Personales:

  • Sistema ARCO completamente automatizado.
  • Registro de consentimientos con timestamp y versión de política.
  • Política de privacidad dinámica gestionada desde el CMS.
  • Derecho al olvido implementado con anonimización (no eliminación) para preservar integridad de datos históricos.

Ley 24.240 — Defensa del Consumidor:

  • Formulario de reclamos con número de seguimiento.
  • Botón de arrepentimiento de compra.
  • Información clara de precios y condiciones.
  • FAQ gestionado desde el CMS.

Gestión de Cookies:

  • Banner de consentimiento de cookies.
  • Categorización de cookies (necesarias, analíticas, marketing).
  • Persistencia de preferencias del usuario.

Impacto y métricas

  • La marca tiene control total sobre su plataforma, sin depender de Shopify, WooCommerce u otras soluciones cerradas.
  • El cumplimiento legal automatizado elimina el riesgo de sanciones por incumplimiento de la Ley 25.326.
  • El panel de administración integrado permite gestionar toda la operación desde una sola interfaz.
  • La arquitectura headless permite cambiar el frontend sin tocar el backend ni el CMS.

Galería