Saltar a contenido

Web de huéspedes y recepción

La web permite registrar un huésped cada vez. Se abre en el navegador del teléfono o de un dispositivo de recepción; no requiere activar una tablet de firmas. No tiene sesión de tablet, service worker, instalación PWA ni cola offline.

Enlaces y QR

Usa el dominio público de la web, no el de Swagger o la API:

Uso Formato
QR permanente de recepción https://checkin.example.com/?site=las-torres&mode=reception
Invitación de una reserva https://checkin.example.com/?site=las-torres#token=<token-devuelto-por-la-API>

La referencia de reserva no autoriza el acceso; lo hace el token opaco de 43 caracteres. BC debe conservarlo de forma segura y componer el enlace del correo/QR tras provisionar la reserva. No incluyas el secreto administrativo ni credenciales BC en el enlace.

El token va en el fragmento #token=, nunca en ?token=. Al leerlo, la web elimina el fragmento de la barra de direcciones, mantiene el modo reserva y conserva el token solo en memoria. Los tokens vacíos, mal formados, repetidos o en query string se rechazan. Una invitación inválida o caducada no cambia automáticamente a recepción.

Para volver a una reserva después de recargar, abre otra vez el enlace original del correo/QR. La URL ya limpiada no conserva la credencial. Trata el enlace original como privado, incluso si el fragmento no llega al servidor HTTP.

Recorrido del huésped

  1. Abre el enlace y espera a que la API confirme el establecimiento o la reserva. En reserva verá referencia, registrados y plazas restantes.
  2. Elige idioma si lo necesita y rellena los datos personales, documento, domicilio y contacto.
  3. Corrige los campos indicados en el resumen de validación y envía. Los campos se bloquean mientras se espera la respuesta.
  4. Guarda la referencia del recibo si necesita soporte. El formulario limpia los datos después de un éxito confirmado.
  5. Pulsa el botón de siguiente huésped cuando haya plazas, o para otro registro de recepción. Se vuelve a consultar el contexto.

La pantalla de éxito confirma almacenamiento en el servicio. No confirma que la persona ya esté creada en BC. La comprobación de entrega es una tarea del operador, mediante Estados y operación.

Idiomas y teléfono

Están disponibles español (es), inglés (en), francés (fr), alemán (de), neerlandés (nl), italiano (it) y portugués (pt). El idioma inicial es español, salvo elección manual previa válida. El selector con banderas cambia etiquetas, ayuda, validación y estados; actualiza también el idioma del documento. La única preferencia guardada en localStorage es el idioma.

El teléfono se introduce como prefijo internacional editable y número nacional. Se sugieren +34, +44, +33, +49, +31, +39 y +351 según el idioma. Un cambio de idioma solo cambia esa sugerencia mientras el número esté vacío y el prefijo no se haya editado manualmente. Un teléfono ya introducido se conserva. La API recibe un único phone, no dos campos nuevos.

Las traducciones necesitan revisión por hablantes nativos antes de la apertura pública. El idioma no determina nacionalidad, país emisor ni país de residencia.

Datos y reglas visibles

Los campos y límites de la API son también la referencia para el formulario. El servidor valida de nuevo todos los datos.

  • La fecha de nacimiento es obligatoria. La edad mostrada se calcula con referenceDate, proporcionada por el establecimiento; no se escribe manualmente ni se envía como otro campo.
  • Menores de 14 años deben indicar su relación con el titular de la reserva o de la estancia. En el cumpleaños 14 deja de ser obligatoria. Es texto libre, también en recepción.
  • Sexo y nacionalidad son obligatorios. Nacionalidad, país emisor del documento y país de residencia son independientes.
  • Los tipos son DNI/documento nacional (dni), Pasaporte (passport) y NIE (nie). Para un documento nacional extranjero se usa dni con su país emisor; NIE requiere España.
  • Segundo apellido, soporte del documento, fecha de expedición y caducidad son opcionales. Una caducidad ya pasada no impide por sí sola el envío. La expedición no puede preceder al nacimiento ni estar en el futuro; la caducidad no puede preceder a una expedición informada.
  • Los documentos siguen siendo obligatorios para menores. El tratamiento de quienes no tienen documento propio sigue pendiente de decisión.

Si se pierde la conexión

No cierres ni recargues la página mientras el resultado sea incierto. Un timeout no demuestra que la API haya rechazado el registro.

Situación Comportamiento y acción
Error de red, timeout de 20 segundos, error de servidor o respuesta no válida La web conserva en memoria el envío completo y su UUID, bloquea la edición y permite reintentar exactamente ese envío. No hay reintentos automáticos.
Rechazo explícito de validación o negocio Se permite corregir los datos o se indica que el enlace/cupo ya no permite continuar.
idempotency_conflict Se bloquea un nuevo envío y se requiere asistencia de recepción. No se crea otro UUID automáticamente.
Registro confirmado Se limpian datos e intento pendiente; el siguiente huésped inicia una operación nueva.
Recarga o cierre durante la incertidumbre Se pierden token e intento en memoria. Recepción debe conciliar antes de registrar de nuevo, especialmente en recepción, donde no hay deduplicación por documento de reserva.

No se guardan huéspedes, documentos, tokens ni recibos en almacenamiento del navegador. Esta decisión protege los datos en dispositivos compartidos, pero impide recuperar un intento tras cerrar la página. No es un modo offline.

Marca y privacidad

checkin-web/src/brands/config.ts, desde la raíz del repositorio, define las-torres y la marca genérica base. Configura nombre, ubicación, logo, ilustración, paleta opcional y privacyUrl. Dentro de esa aplicación, los recursos están en public/brands/ y las banderas en public/flags/. Las rutas actuales de recursos presuponen publicación en la raíz del dominio.

Para otro establecimiento, añade su configuración y recursos aprobados, autoriza su slug en CHECKIN_SITE_SLUGS y, si procede, añade su destino BC. Cambiar ?site= solo selecciona la marca; no crea un establecimiento ni concede acceso a otra reserva. El backend rechaza sitios no autorizados y una marca desconocida se muestra como no disponible.

El texto/enlace definitivo de privacidad aún no está configurado; la web muestra un aviso pendiente. No inventa un consentimiento obligatorio. Acuerda el contenido y acceso a datos antes de recoger información real.

Prueba visual de desarrollo

Con Vite en desarrollo puedes usar /?site=las-torres&mode=reception&demo=1. Para reserva existe /?site=las-torres&demo=1#token=demo-reservation. La interfaz lo identifica como demo, usa datos temporales y no guarda nada en la API. El modo demo no se incluye en el paquete de producción.

Usa datos ficticios. La demo no verifica PostgreSQL, cupos concurrentes ni Business Central. Para probar el recorrido real sigue el anexo local; para publicarlo usa Desplegar API, web y documentación en Coolify, con los ajustes específicos de la web.