PRODUCTO SAAS v1.0

Plataforma de Reservas SaaS

Sistema de reservas online con pagos integrados para profesionales y pequeños negocios de servicios.

Cronología

3 Semanas

Rol

Full Stack Developer

Slide 1
1 / 19

El Problema

Muchos profesionales de servicios (clases, consultas, sesiones creativas) gestionan sus reservas de forma manual a través de WhatsApp, email o calendarios no sincronizados, lo que genera errores, pérdidas de tiempo y citas desaprovechadas.

  • Reservas desorganizadas entre múltiples canales.
  • Cancelaciones y no-shows sin control.
  • Falta de pagos anticipados o señalización.
  • Herramientas genéricas poco adaptadas a su flujo real.

La Solución

Diseñé y desarrollé una plataforma SaaS que centraliza la gestión de reservas, clientes y pagos en un único sistema, permitiendo a los profesionales automatizar su agenda y reducir fricción operativa.

Autenticación y Control de Acceso

Sistema de autenticación flexible y seguro que soporta múltiples métodos de acceso y separa claramente los roles de administradores, proveedores y clientes.

  • Login con Google OAuth, Email/Password y Magic Links.
  • Verificación OTP en registros por email.
  • RBAC con portales diferenciados (Admin, Provider, Client).
  • Protecciones activas contra abuso: rate limiting, CAPTCHA y honeypots.

Motor de Reservas Avanzado

Motor de reservas configurable que permite a los profesionales definir servicios, disponibilidad y reglas complejas sin fricción para el cliente final.

  • Servicios flexibles: duración, precio, capacidad (1-on-1 o grupos).
  • Disponibilidad híbrida con reglas semanales y excepciones por fecha.
  • Buffers automáticos entre citas para evitar solapamientos.
  • Gestión de concurrencia por servicio y límites globales.

Sincronización con Google Calendar

Sincronización bidireccional con Google Calendar para evitar dobles reservas y mantener la agenda siempre actualizada.

  • Importación automática de eventos externos.
  • Bloqueo de horarios ocupados en tiempo real.
  • Actualización automática ante cancelaciones o reprogramaciones.

Pagos y Monetización Integrada

Sistema de pagos completo con Stripe que permite cobros anticipados, payouts automáticos y un modelo SaaS escalable.

  • Pagos upfront para confirmar reservas.
  • Stripe Connect Express para que cada proveedor cobre directamente.
  • Soporte para comisiones de plataforma por transacción.
  • Planes de suscripción mensual o anual para proveedores.

Gestión de Reservas Recurrentes

Soporte nativo para reservas periódicas, ideal para clases, terapias y servicios continuos.

  • Configuración semanal o mensual.
  • Generación automática de sesiones futuras.
  • Gestión centralizada de cancelaciones y cambios.

Internacionalización (i18n)

Plataforma preparada para audiencias internacionales con soporte completo multi-idioma.

  • Interfaz totalmente traducida a inglés y español.
  • Detección automática de idioma mediante middleware.
  • Emails y mensajes de error localizados.

Automatización y Notificaciones

Sistema de automatización que reduce tareas manuales y mantiene informados a clientes y proveedores.

  • Recordatorios automáticos 24h y 1h antes de la cita.
  • Emails transaccionales para confirmaciones y cancelaciones.
  • Cron jobs ejecutados de forma serverless.

Analíticas y Panel de Control

Dashboard interactivo para que los proveedores entiendan el rendimiento de su negocio.

  • Métricas de ingresos y volumen de reservas.
  • Servicios más populares.
  • Visualizaciones claras mediante gráficos interactivos.

Stack Tecnológico

Next.js 14

Framework

TypeScript

Language

PostgreSQL

Database

Prisma

ORM

Auth.js

Auth

Stripe Connect

Payments

Resend

Email

TailwindCSS

Styling

Shadcn/UI

UI

Zod

Validation

React Hook Form

Forms

next-intl

i18n

Retos Técnicos

Handling Webhook Idempotency

Asegurar que los webhooks de Stripe se procesen exactamente una vez. Retries de red podían causar registros duplicados si no se manejaban correctamente.

webhook-handler.ts
const handleWebhook = async (req, res) => {
  const event = req.body;
  
  // 1. Check Redis for Idempotency Key
  const isProcessed = await redis.get(event.id);
  if (isProcessed) {
    return res.status(200).send("Already processed");
  }

  // 2. Process Business Logic
  try {
    if (event.type === 'invoice.paid') {
      await updateInvoiceStatus(event.data.object);
    }
    
    // 3. Mark as processed for 24h
    await redis.set(event.id, 'processed', 'EX', 86400);
    res.json({ received: true });
  } catch (err) {
    console.error(err);
    res.status(500).send();
  }
};