Saltar al contenido principal

Turismo · Tour operador en San Pedro de Atacama, Chile · Desarrollo Web

Dashboard TurismoChileTours

Una sola herramienta para correr toda la operación diaria de una agencia de turismo en pleno desierto de Atacama. Migra los flujos atrapados en Power Apps a una web moderna, suma módulos que antes vivían en Excel y WhatsApp, y le da al equipo una fuente de verdad común. Diseñado para que ventas, operaciones, guías y administración trabajen sobre los mismos datos — con permisos, auditoría y exportes pensados para el día a día real.

Next.js 16React 19TypeScriptTailwind CSSPrismaPostgreSQLBetter AuthTanStack QueryTanStack TableTanStack FormTanStack VirtualZodZustand@react-pdf/rendererExcelJSRechartsResend

Cliente

TurismoChileTours

Duración

≈7 meses, octubre 2025 – mayo 2026, con scope creciente: surgieron mejoras durante el camino que extendieron el cronograma original.

En producción

Junio 2026 (previsto) — actualmente en UAT con el jefe y operadoras como usuarios reales.

Mockup ilustrativo. El sistema real es privado por acuerdo con el cliente — sin capturas ni datos reales.

El problema

La empresa operaba sobre una Power Apps heredada usada por el jefe y las operadoras: cubría lo básico (ventas, cotizaciones, traspasos, pasajeros y tours), pero con controles nativos pensados para uso casual, no para un equipo que pasa horas adentro. La UX y la búsqueda eran tediosas, las validaciones débiles, sin auditoría real y con poca garantía de integridad referencial.

Encima, faltaban módulos clave que la operación ya necesitaba pero no tenía dónde vivir: calendario operativo visual, recepciones de pasajeros en hoteles, validaciones estrictas con auditoría, búsqueda y edición rápida con filtros server-side, permisos granulares por módulo y exportes operativos (hoja de ruta diaria, planillas administrativas).

La Power Apps además era 11 años de operación (2015–2026) viviendo sobre Microsoft Lists, con esquema inconsistente, columnas agregadas y renombradas a lo largo del tiempo, y referencias entre listas mantenidas a mano. Migrar al dominio normalizado de Postgres no era un volcado directo: requería un proceso explícito de extracción, limpieza y normalización por períodos.

La solución

La nueva web cubre todos los flujos que estaban atrapados (ventas, pasajeros, traspasos, tours, asignación de operadores) con UX moderna, tablas virtualizadas, filtros server-side y formularios reactivos con validación Zod compartida cliente/servidor.

Suma flujos nuevos que la Power Apps no soportaba: calendario de eventos con drag-and-drop y validación de conflictos en servidor, módulo de recepciones, facturación mayorista, comisiones, flujo de caja con múltiples divisas (CLP/USD), analytics y alertas, aprobaciones y exportes PDF/Excel por día / rango / selección.

El dashboard es un sistema independiente del sitio corporativo y del ecommerce de San Pedro: repos y bases de datos completamente separados. Es la tercera pieza del ecosistema digital del cliente, pero no comparte modelo de datos con las otras dos — cada plataforma tiene su propia responsabilidad y su propio ciclo de vida.

Sistema de roles con permisos por módulo (RoleModulePermission). Perfiles típicos: administración (jefe), operadoras (ventas, cotizaciones, recepciones, traspasos, asignación de operadores). Cada rol ve solo los módulos que necesita.

Migración de 11 años de data en tres pasos: extracción de las Microsoft Lists conectadas a la Power Apps a un Excel maestro, limpieza y normalización en un segundo Excel derivado (tipos, referencias reconciliadas, mapeo a Prisma) e importación por períodos con un script Node que validó cada lote contra el schema Zod compartido.

En números

22

módulos de dominio

Carpetas en src/project/ (ventas, eventos, caja, comisiones, …).

11 años

de data histórica migrada

2015–2026 desde Microsoft Lists a Postgres por períodos.

~3 min → ~45 s

registrar una venta multicanal

Estimación UAT vs Power Apps — menos pantallazos, validación inline.

3 → 1

fuentes de verdad

Power Apps + Excel + WhatsApp → un solo Postgres con auditoría.

Arquitectura

Aplicación Next.js 16 con App Router, Server Actions como capa de mutación (sin API routes salvo casos puntuales) y React Server Components por defecto. La organización sigue clean architecture por feature ("screaming architecture"): cada dominio vive en src/project/{domain}/ con su actions/, components/, schemas/, types/ y columns/. 22 módulos de dominio (ventas, eventos, calendario, caja, comisiones, proveedores, etc.) y 40+ modelos Prisma con 49+ migraciones. Persistencia en PostgreSQL (Neon) vía Prisma 7. Auth con Better Auth 1.4 (email + password) y permisos granulares por módulo modelados en DB. Tablas y filtros server-side con TanStack Table + paginación cursor-based; formularios con TanStack Form + Zod; estado de servidor con TanStack Query. Archivos (vouchers, PDFs, imágenes) en Vercel Blob; emails transaccionales con Resend + React Email. Exportes generados client-side con @react-pdf/renderer y ExcelJS, importados dinámicamente para no inflar el bundle. Deploy en Vercel con Turbopack y React Compiler. Workflow de desarrollo con SDD (Spec-Driven Development).

Decisiones técnicas

Next.js 16 (App Router + Server Actions)

Necesitábamos formularios pesados con validación server-side y mutaciones transaccionales (venta + pasajeros + eventos en un solo flujo). Server Actions evitan armar una API REST paralela y mantienen todo type-safe end-to-end.

React 19 + React Compiler

El dashboard tiene tablas grandes y filtros reactivos; el compiler memoiza automáticamente sin tener que ensuciar el código con useMemo/useCallback en cada handler.

Prisma 7 + PostgreSQL (Neon)

El modelo de dominio tiene relaciones densas (venta → pasajeros → evento → proveedor → comisión) que no perdonan tipos vagos. Prisma da migraciones versionadas y type-safety end-to-end; Neon suma branching de DB para previews de Vercel.

Better Auth 1.4

Necesitaba permisos por módulo, no solo roles. Better Auth es lo bastante flexible para modelar RoleModulePermission sin pelearse con un provider rígido tipo NextAuth.

TanStack Table + Virtual

Listados de ventas/pasajeros con cientos de filas y filtros combinados. Virtualización + columnas tipadas + paginación server-side fueron requisito desde el día uno.

TanStack Form + Zod 4

Formularios largos (venta multicanal, evento con N pasajeros) con validación compartida cliente/servidor. Un solo schema Zod corre en ambos lados.

shadcn/ui + Tailwind 4 + Radix

Control total sobre los componentes (los copiamos al repo), accesibilidad de Radix y Tailwind 4 con theming vía CSS vars para soporte oscuro/claro sin librería de themes.

DnD Kit

Calendario de eventos con drag-and-drop accesible por teclado y un único DndContext compartido entre las vistas mes / semana / día.

@react-pdf/renderer + ExcelJS

Exportes operativos (hojas de ruta del día, planillas para administración) generados client-side y descargables al toque. Dynamic import para no cargar las libs hasta que el usuario abre el menú de exportar.

MapLibre GL

Visualización geográfica de rutas/tours sin lock-in con Mapbox ni costos por load.

Resend + React Email

Emails transaccionales (vouchers, confirmaciones) con templates en JSX, deliverability decente y SDK Node simple.

Vercel Blob + Vercel hosting

Vouchers PDF y fotos de tours sin infra extra; deploys por PR con preview URLs e integración nativa con Neon branching.

Funcionalidades

Calendario operativo con drag-and-drop

Tres vistas (mes / semana / día) sobre un único DndContext de DnD Kit. Cada drop dispara un Server Action que valida en transacción conflictos de disponibilidad de proveedores y pasajeros, y exige motivo obligatorio del cambio para auditoría. Si hay conflicto, el evento vuelve a su lugar con un toast explicando qué chocó.

Análisis y reportes con filtros

Analytics con Recharts (ventas, ocupación, voucher promedio, países atendidos) sobre filtros server-side, sumado a exportes operativos: PDF (hoja de ruta diaria, voucher de pasajero, detalle de venta) y Excel (planillas operativas y administrativas) en alcances día / rango / selección, con branding consistente.

Facturación mayorista con exportes

El módulo de Facturación permite seleccionar ventas de un mayorista (Ekatours, Despegar, etc.) dentro de un rango de fechas, marcar varias con multiselect, y generar un PDF de cobro consolidado con el detalle de cada venta (voucher, pasajero, fechas, monto) listo para mandarle al mayorista. El mismo flujo soporta exporte a Excel para conciliación administrativa. Antes era una operación manual mensual repartida entre la Power Apps, planillas Excel y correo; ahora una operadora arma el cobro en menos de un minuto con totales calculados y registro en sistema.

Recepciones y traspasos entre agencias

San Pedro funciona como un ecosistema chico de agencias que se pasan pasajeros entre sí. Dos módulos hermanos resuelven el flujo: Recepciones registra pasajeros recibidos de otras agencias y los inserta en el calendario operativo como cualquier venta (voucher, evento, hoja de ruta); Traspasos manda pasajeros propios a otra agencia con voucher de traspaso, dejando rastro de qué venta original derivó qué pasajero a qué destino. Antes vivía en WhatsApp y Excel — ahora es un canal B2B operable con auditoría.

Migración de 11 años de data

Extracción de Microsoft Lists (2015–2026) a Excel maestro, normalización y reconciliación de referencias en un Excel derivado, y carga por períodos con un script Node que valida cada lote contra el schema Zod compartido con la app antes de tocar producción.

Línea de tiempo

  1. Octubre 2025

    Kickoff

    Primer contacto con TurismoChileTours, definición de scope y decisión de migrar la Power Apps a una web propia. Primeras carpetas de dominio (auth, agency).

  2. Oct 2025 – May 2026

    Desarrollo iterativo

    ≈7 meses con scope creciente. Hitos internos: receptions/transfers/providers (nov 2025), billing/departures/analytics (ene 2026), roles + permisos / alerts / commissions / approvals (feb 2026), calendar (mar 2026), drag-and-drop + exportes PDF/Excel (abr 2026), multiselect facturación + hover cards + sale detail accordions (may 2026).

  3. Mayo 2026

    UAT con usuarios reales

    En curso con el jefe y operadoras. Migración de data histórica 2015–2026 desde Microsoft Lists corriendo en paralelo.

  4. Junio 2026

    Lanzamiento previsto

    Salida a producción tras cierre de UAT y carga final de data histórica.

¿Tienes un proyecto similar?

Construyo sistemas a medida de extremo a extremo. Conversemos.