← /projects

Completed

Chiscame un Ollo

Plataforma web full-stack para negocio real (estudio fotográfico + espacio cultural)

Se entregó una aplicación web profesional que unifica dos marcas en una sola experiencia digital: Chíscame un Ollo (fotografía de autor, servicios y relación con clientes) y Chiscarte (programación cultural, talleres, archivo e inscripciones). El sistema incluye un sitio público con Angular SSR (SEO, rendimiento y accesibilidad), una API REST en NestJS con PostgreSQL y Prisma, y un panel de administración en Angular para que el equipo gestione contenido, sesiones privadas, inscripciones, pagos y comunicaciones sin depender de desarrolladores en el día a día.

AngularTailwind CSSNestJSPrismaPostgreSQLSwaggerHelmetCloudflareDockerTraefikJest
Captura de Chiscame un Ollo

El diferencial técnico más fuerte es el área privada del estudio: acceso sin contraseñas tradicionales mediante magic links, galerías con arquitectura anti-descarga (proxy de imágenes, tokens de vista de corta duración, cabeceras anti-caché, opciones de restricción de origen y marca de agua), selección de fotos, pedidos, briefing multietapa y entrega de ficheros hacia almacenamiento compatible S3 (Cloudflare R2), con notificaciones por correo y Telegram para operación interna.

Contexto de negocio

El cliente necesitaba algo más que una web corporativa: una herramienta operativa que respaldara el modelo de trabajo del estudio (entregas sensibles, confianza con el cliente final) y la actividad cultural de Chiscarte (visibilidad de programación, archivo vivo, inscripciones y condiciones legales editables). Eso obliga a combinar marketing, CMS, workflow B2C y cumplimiento (privacidad, cookies, condiciones de contratación) en un solo ecosistema.

Arquitectura general

    • Monolito modular en NestJS: límites claros por dominio (`auth`, `content`, `gallery`, `public`, `admin`, `private-client`, `private-admin`, `uploads` con R2, `orders`, `payments`, `enrollments`, `archive`, `activities`, `services`, `newsletter`, `mail`, `notify`, `shared`, etc.), facilitando evolución sin fragmentar operaciones en microservicios prematuros.
  • Contrato HTTP estable bajo prefijo `/api`, con CORS explícito por entorno, validación global de entrada y separación entre rutas públicas, admin y cliente privado.
  • Tres clientes Angular: el público prioriza SSR y metadatos por ruta; el admin prioriza productividad editorial y seguridad de sesión.

Lo más innovador y “rompedor”

  1. Galerías privadas sin URL pública del bucket El listado de imágenes no expone claves R2 al navegador. El cliente obtiene metadatos; para pintar cada foto se emite un JWT de vista de vida muy corta y se sirve el binario a través de un endpoint proxy que lee R2 en servidor, con políticas de caché estrictas. Opcionalmente se aplica marca de agua con Sharp en el flujo y restricción por Referer/Origin. Es honesto con el modelo de amenaza: no sustituye la confianza humana frente a capturas de pantalla, pero eleva muchísimo el coste del robo masivo y del hotlinking frente a enlaces firmados largos o URLs públicas.

  2. Magic links con alcance (scope) Flujo de acceso sin registro: el estudio genera enlaces; el usuario valida el token y recibe un JWT de sesión privada. Revocación y caducidad en base de datos, plantillas de email desacopladas del controlador.

  3. CMS híbrido: Markdown + bloques dinámicos Páginas legales y estáticas editables; en Chiscarte, evolución hacia `extraContent` estructurado (p. ej. talleres con bloques repetibles, CTA y subida a R2 por bloque) con render dinámico en el frontend y paridad con contenido legacy: demuestra capacidad de migrar modelo de datos sin romper producción.

  4. Operación integrada Emails transaccionales (inscripción, pedido de galería, briefing), notificaciones internas (Telegram en hitos críticos, avisos de lotes de subida), GA4 condicionado al consentimiento de cookies y banner CMP en el sitio público.

Resumen por aplicación

Frontend público (Angular SSR)

  • Home dividida en dos universos visuales (estudio / Chiscarte) con navegación rica y animaciones.
  • Estudio: páginas CMS (`quienes-somos`, `el-estudio`), listado y ficha de servicios con carrusel infinito, portfolio y lightbox, contacto con honeypot y manejo de errores/429.
  • Chiscarte: proyecto y talleres (CMS, talleres con contenido dinámico cuando aplica), programación agrupada por mes, ficha de actividad (hero, duración, mapa, sold out), inscripciones, archivo vivo (timeline) y entrada de archivo (markdown, carrusel, descargas firmadas).
  • Legales enlazados desde el pie: aviso legal, privacidad, cookies, condiciones de contratación (antes cancelaciones como alias).
  • Privado: ruta de consumo de magic link (`/acceso-privado`), área bajo `/privado/:slug` con galería (masonry, selección persistida con debounce, anti-interacción trivial en UI), pedido, briefing multistep; entrega de ficheros en ruta dedicada (`/entrega-ficheros`) con guarda de acceso.
  • Pagos estudio: rutas de checkout y retorno preparadas para integración con pasarela.
  • Transversal: consentimiento de cookies, eventos GA4 tras consentimiento, accesibilidad práctica (saltar al contenido, `:focus-visible`), proxy de desarrollo hacia API.

Backend (NestJS + Prisma + PostgreSQL)

  • Autenticación: login/logout admin, guards, CSRF en mutaciones admin.
  • Público: lecturas filtradas por `published`, contacto con throttle, newsletter, legal, servicios, actividades, archivo, medios de lectura controlada, inscripciones y enlaces legales de cancelación/contratación.
  • Magic links: creación, validación, revocación desde admin.
  • Privado (cliente): sesión por JWT, imágenes (listado, view-token, stream proxy), selección, pedidos (con `Payment` pendiente), briefing GET/PATCH/submit, subidas por lotes a R2.
  • Admin API: CRUD CMS (legal, estudio, chiscarte), servicios, actividades, archivo, media presign/confirm, derivación WebP, sesiones privadas, galerías, pedidos, briefings, lotes de envío, magic links, inscripciones, pagos, newsletter (listado/export), dashboard agregado.
  • Observabilidad y robustez: `/api/health`, `/api/health/ready` (DB), `/api/health/smtp`, logs estructurados, Helmet, Swagger solo no productivo.

Panel de administración (Angular SPA)

  • Login con credenciales, sesión por cookies + envío de `x-csrf-token` en peticiones mutantes.
  • Dashboard con KPIs agregados desde backend.
  • Contenido: listados y edición de páginas legales, información de estudio y Chiscarte (markdown / estados de publicación), servicios del estudio, archivo de Chiscarte con galerías y descargables (R2), Programación como vista sobre actividades.
  • Gestión operativa: magic links, sesiones privadas (detalle rico: galería, pedidos, envíos, lotes), galerías/pedidos agrupados, plantillas de briefing, entrega de ficheros (solicitudes con magic link), pagos.
  • UX interna: tablas reutilizables, editores (markdown / Toast UI donde corresponde), pickers de media con presign.

Impacto y métricas

  • Producto digital alineado con el negocio: una sola plataforma cubre presencia pública, archivo cultural, captación (newsletter, contacto) y ciclo de vida del cliente del estudio hasta entrega de material sensible.
  • Propiedad intelectual mejor defendida en galerías privadas mediante diseño en capas (API proxy, tokens cortos, CDN sin exposición directa de objetos al navegador, opciones de watermark y origen).
  • Autonomía del cliente: el equipo puede actualizar textos legales, servicios, actividades, archivo y páginas informativas sin tocar código; puede operar sesiones privadas, enlaces mágicos y estados de pago desde el admin.
  • Cumplimiento y confianza: CMP de cookies, integración GA4 consentida, SEO técnico, formularios con validación y límites de tasa, minimización de fugas de información en errores.

Galería