Departamento de Marketing · Documentación Oficial

Manual del Sistema de Operaciones v6

Guía técnica completa — rondas de inspección, ventanas horarias A&B, dashboard gerencial, notificaciones push, arquitectura del sistema y flujos operacionales.

4 Turnos diarios
37 Zonas AM-1
12 Secciones
v6 Versión actual
📱 App Operadores 📊 Intelligence Center 🔔 Push OneSignal 🤖 IA Gemini 2.5 📄 PDF + Postmark
Scroll para explorar
01

Descripción General

Plataforma web integral que digitaliza las rondas de control operacional de Rosa Agustina Conference, conectando operadores en terreno con gerencia en tiempo real vía push, correo y dashboard BI.

📱

App de Operadores

Interfaz móvil optimizada para celular. Sin descarga. Funciona en cualquier navegador. Rondas por turno con checklist zona a zona.

PWA · Sin instalación
📊

Intelligence Center

Dashboard gerencial con KPIs en tiempo real, tabla con colores por área, 5 gráficos BI y resumen ejecutivo con IA Gemini 2.5 Flash.

Solo Supervisores
🔔

Notificaciones Push

Alertas automáticas vía OneSignal. Warning inmediato, aviso de turno, cierre de ronda. Diferenciadas por severidad.

OneSignal · Automático
📄

Informe PDF + Correo

Al cerrar turno se genera PDF en Drive y correo HTML vía Postmark. Zonas excluidas por ventana horaria quedan documentadas explícitamente.

Postmark · Google Drive
🤖

IA Gemini 2.5 Flash

Analista Copilot en el dashboard. Lee las observaciones del período y genera resumen ejecutivo con las 3 urgencias mayores y patrones operacionales.

Backend seguro
👥

Modo Colaborativo

Múltiples operadores en la misma ronda. Polling 30s detecta zonas de otros operadores y muestra toast con nombre y zona específica.

Tiempo real
🔧
Stack tecnológico: Google Apps Script (backend) · Google Sheets (5 hojas de datos) · HTML5/JS vanilla (frontend) · Postmark (correo transaccional) · OneSignal (push) · Gemini 2.5 Flash (IA) · Google Drive (PDFs + fotos)
URL
App:       https://marketing.rosaagustina.cl/webapp/operaciones/
Dashboard: https://marketing.rosaagustina.cl/webapp/operaciones/dashboard/
Manual:    https://marketing.rosaagustina.cl/webapp/operaciones/manual/
02

Acceso y Login

Autenticación por nombre y PIN de 4 dígitos. Sesión válida 8 horas, persiste aunque se cierre el navegador. Recuperación automática de PIN por correo sin intervención del supervisor.

1

Seleccionar operador

Lista cargada desde Google Sheets al iniciar. Si aparece "Error — recarga la página", el servidor Apps Script está saturado (503). El sistema reintenta automáticamente hasta 3 veces con backoff de 2s-4s-6s antes de mostrar el error.

2

Ingresar PIN de 4 dígitos

Usar el teclado numérico en pantalla. Personal e intransferible — cada zona registrada queda vinculada al nombre del operador que ingresó con ese PIN.

3

Sesión activa por 8 horas

No es necesario re-autenticar entre turnos del mismo día. El token UUID se almacena en localStorage y se valida en cada llamada al servidor.

4

Recuperación automática de PIN

Clic en "🔑 Olvidé mi PIN" → seleccionar nombre de la lista (sin tipeo, evita errores) → ingresar correo registrado → Postmark envía link de uso único válido 30 minutos. Redirige a pantalla de nuevo PIN. No requiere al supervisor.

⚠️
Error "No encontramos ese nombre y correo": La comparación es case-insensitive. Si persiste, verificar que el correo esté registrado en la hoja "Usuarios" de Google Sheets. El log de Apps Script muestra qué llega vs qué hay en la hoja.
03

Módulo de Operaciones

Flujo completo de una ronda. La app persiste el progreso en localStorage — si el operador cierra la pantalla y vuelve durante el mismo turno, el sistema detecta las zonas guardadas y ofrece continuar.

1

Seleccionar turno del día

Pantalla de estado muestra AM-1, AM-2, PM-1, PM-2. Los ya realizados muestran operador y hora de cierre. Los vencidos sin realizar aparecen como "No Realizada" en rojo.

2

Recorrer zonas del checklist

Cada zona despliega sus campos. Los ítems A&B bloqueados por ventana horaria no se muestran — el contador de progreso los excluye y el aviso debajo de la barra los explica con hora de habilitación.

3

Anti-mafia: mínimo 30 segundos entre zonas

El botón "Guardar zona" permanece bloqueado hasta que transcurran 30s desde la zona anterior. Impide registros masivos sin inspección física real. Tiempo mínimo de ronda ≈18 minutos.

4

Cerrar ronda

Se habilita cuando todas las zonas disponibles están guardadas. Al cerrarlo: genera PDF, envía correo Postmark, envía push de cierre. Las zonas A&B excluidas por ventana horaria quedan documentadas en la pantalla de éxito, el PDF y el correo.

Simulador de Ronda
Prueba cómo funciona el checklist en la práctica
0 / 3 zonas completadas
04

Bloques de Turno y Zonas

4 bloques diarios cubren el hotel las 24 horas. Selecciona un turno para ver exactamente qué zonas cubre y su recuento.

📋
Base total por turno: AM-1 = 37 zonas · AM-2 = 18 · PM-1 = 34 · PM-2 = 11. El total visible en la app puede ser 1 menor cuando una zona A&B está bloqueada por ventana horaria — es correcto y esperado. El aviso debajo de la barra de progreso lo indica con hora de habilitación.
05

Campos de Control

6 campos por zona. Todos obligatorios excepto las observaciones de texto. Clic en cada campo para ver el criterio de uso.

🔄

Estado

ONOFF
Clic para ver criterio →
ON = zona activa y operativa en ese momento. OFF = zona cerrada, fuera de servicio o sin actividad en ese bloque de turno. La elección no afecta los otros campos pero queda registrada en el reporte.
👥

Dotación

OKOBS
Clic para ver criterio →
OK = personal completo y en funciones. OBS = falta personal, llegada tarde, dotación reducida o situación que justifica registro. Requiere descripción de texto (máx 80 chars). Genera alerta ámbar en dashboard.
📦

Provisión

OKOBS
Clic para ver criterio →
OK = stock completo de insumos. OBS = falta stock, insumos agotados o por agotar antes del próximo turno. Descripción precisa: qué falta, en qué cantidad aprox. "Falta café y endulzante" — no párrafos.
⚙️

Operación

OKOBS
Clic para ver criterio →
OK = procedimientos ejecutándose según protocolo. OBS = desviación de protocolo, proceso incompleto o situación operacional irregular. Documentar qué proceso está fuera de estándar.
🔧

Equipos

OKOBS
Clic para ver criterio →
OK = equipamiento e infraestructura en buen estado. OBS = equipo con falla, en mantención, deteriorado o que requiere revisión técnica. Si es falla crítica → usar Warning en Incidencia.
🚨

Incidencia

Out of serviceWarning
Clic para ver criterio →
Out of service = sin incidencias, zona normal. Warning = incidencia crítica que requiere atención inmediata. Obliga descripción de texto (campo bloqueado hasta completar). Dispara push urgente 🚨 a todos los suscriptores con área, zona y descripción. Fila en rojo en dashboard y correo.
06

Ventanas Horarias A&B

Las zonas de Alimentos & Bebidas solo son registrables dentro de su ventana. Fuera de ella, el ítem se bloquea automáticamente y no aparece en el checklist.

ServicioÍtemTurnoDisponible desdeBloqueo definitivo
🍳 DesayunoAperturaAM-107:4508:30
🍳 DesayunoCierreAM-110:1511:00
🍽 AlmuerzoAperturaAM-212:4513:30
🍽 AlmuerzoCierreAM-214:4515:30
☕ OnceAperturaPM-117:4518:30
☕ OnceCierrePM-118:4519:30
🍷 CenaAperturaPM-220:1521:00
🍷 CenaCierrePM-221:4522:30
☕ Cafetería LobbyApertura AMAM-110:1511:15
☕ Cafetería LobbyCierre AMAM-213:1514:00
☕ Cafetería LobbyApertura PMAM-214:1515:15
☕ Cafetería LobbyCierre PMPM-222:1523:00
¿Cómo funciona el bloqueo?
El sistema compara la hora actual con el rango desde → hasta de cada ítem. Si la hora está fuera del rango, la zona no aparece en el checklist y el contador de progreso la excluye. El aviso debajo de la barra muestra: ⏰ 1 zona fuera de horario · habilita HH:MM.
🔒¿Se puede forzar el registro fuera de horario?
No. El bloqueo es en el frontend (ítem oculto) y en el backend (VENTANAS_AB en Apps Script). No existe forma de saltar la restricción sin modificar el código fuente. El dato de bloqueo queda en logs del servidor.
📊¿Por qué el dashboard muestra 37 pero la app muestra 36?
El dashboard muestra el total base (37 ítems AM-1 en CHECKLIST_DATA). La app descuenta los ítems actualmente bloqueados por ventana horaria. La diferencia de 1 indica que hay un ítem A&B cuya ventana aún no ha llegado o ya pasó. El aviso ⏰ 1 zona fuera de horario · habilita HH:MM en el KPI del dashboard explica esto.

Si se cierra un turno con zonas bloqueadas, el sistema las documenta explícitamente en 3 lugares:

📱

Pantalla de Éxito (App)

Caja ámbar con lista de zonas excluidas, nombre, área y ventana de servicio. Texto: "✓ Incluidas en el PDF y correo como Excluidas por horario".

📄

PDF de la Ronda

Tabla separada al final del PDF con fondo crema/ámbar. Columnas: Zona / Área / Ventana Horaria / Motivo. Nota: "No representan un error del operador".

📧

Correo HTML

Sección oscura con borde ámbar antes del footer del correo. Tabla con las mismas columnas. Misma nota al pie.

07

Incidencias y Fotos

El campo de incidencia es el más crítico del sistema. Un Warning activa el protocolo completo de alerta en tiempo real.

Out of service

Estado normal. Sin incidencias. La zona funciona según protocolo. Es el estado esperado en condiciones normales de operación.

No dispara push · Fila normal en dashboard

🚨

Warning — Crítico

Incidencia que requiere atención inmediata. Descripción obligatoria — botón bloqueado hasta completarla. Máximo 80 caracteres.

Push inmediato → gerencia · Fila roja · KPI warnings +1

📷

Adjuntar fotos (hasta 4)

Botón de cámara abre selector de archivos. Compatible con cámara directa del celular. Las fotos se suben a Google Drive como archivos compartidos con permiso de solo lectura. Los links aparecen en el correo como iconos clicables y en el PDF como URLs. Máximo 4 fotos por zona.

✏️

Regla de observaciones: 80 caracteres

Breve y precisa. Qué, dónde, cuánto. "Falta café y endulzante en estación" ✓ — un párrafo extenso ✗. El campo tiene maxlength="80" en el HTML y el servidor valida el contenido antes de guardar.

08

Dashboard Gerencial

Intelligence Center disponible solo para Supervisores. El botón "📊 Dashboard" en la app solo aparece si el operador tiene rol Supervisor.

📋

Control de Turnos Diario

4 cards AM-1/AM-2/PM-1/PM-2 con estado, progreso "X/Y zonas", operadores activos y hora de cierre. Polling 30s actualiza los cards sin recargar la página completa.

🔍

Tabla de Inspecciones

Todas las zonas con fondo de color por área (8 colores distintos), borde izquierdo para alertas (rojo=Warning, ámbar=OBS), ordenadas por área canónica con separador visual entre grupos.

Nota de ventanas en KPI: Si las zonas revisadas son menores al total esperado, aparece ⏰ 1 zona fuera de horario · habilita HH:MM bajo el número de Zonas Revisadas.

Panel con 5 gráficos Chart.js, activados al hacer clic en la pestaña "📊 Panel BI & Inteligencia Artificial". Filtrable por rango de fechas y turno.

Evolución histórica

Line chart — tendencia de warnings y observaciones en el tiempo.

Radar por Área Operativa

Radar chart — score de alertas por AO (SOPORTE, HOTEL, A&B, etc.).

Riesgo por Turno

Doughnut chart — distribución de incidencias por bloque de turno.

Comparativa Operadores

Bar chart — volumen de zonas registradas por operador.

Tipos de Incidencia

Polar chart — proporción OK vs OBS vs Warning.

Botón "🤖 Generar Resumen con IA" envía las observaciones del período filtrado al servidor. El servidor (no el browser) llama a Gemini 2.5 Flash vía UrlFetchApp con la API key en PropertiesService.

🔒
Seguridad: La API key de Gemini nunca sale al frontend. El navegador solo llama al endpoint de Apps Script, que internamente llama a Google AI. El modelo retorna el resumen en texto plano al dashboard.
Prompt template
Sistema: Gerente de Inteligencia Operativa · Rosa Agustina Resorts
Instrucciones: Párrafo resumen con áreas críticas + lista de 3 urgencias/patrones
Tono: Profesional, corporativo, orientado a acción
Input: JSON con observaciones del período filtrado
⚠️
Sin auto-refresh: El dashboard no tiene recarga automática de la tabla completa. Esto evita el error "Demasiadas invocaciones simultáneas" de Google Sheets cuando hay múltiples usuarios activos. Usar el botón "↻ Actualizar datos" manualmente.

El polling liviano cada 30s solo llama a getRondaProgress (sin autenticación, solo lectura) para actualizar los cards de turno. No toca la tabla. Un flag cargandoData previene llamadas simultáneas al forzar actualización manual.

09

Notificaciones Push

OneSignal con el app ID configurado. Los dispositivos deben aceptar permisos de notificación al ingresar por primera vez a la app. Botón "🔔 Activar Notificaciones" visible en la pantalla de login.

🚨

Warning registrado — inmediato

Disparado cuando un operador guarda una zona con Warning. Título: "🚨 WARNING — [Área]: [Zona]". Cuerpo: hora, operador, descripción. Link: dashboard filtrado por turno y fecha.

📍

Observación registrada — solo si hay obs.

Solo cuando hay texto real en dotación, provisión, operación o equipos. No se envía si todo es OK. Evita spam de notificaciones en turnos sin novedades.

Turno cerrado

Ícono varía: 🚨 si hay warnings, 📝 si hay observaciones, ✅ si todo OK. Incluye total zonas, responsable de cierre y link al dashboard.

⚠️

Turno no realizado

Disparado en los primeros 20 min del siguiente bloque si el turno anterior no tiene estado "Realizada" en Control Rondas v6. Verificado con flag en PropertiesService para no enviar duplicados.

Turno por comenzar

Aviso 20 minutos antes de AM-1, AM-2, PM-1, PM-2. Ejecutado por verificarAlertasAutomaticas() — función de Apps Script configurada como trigger por tiempo cada 10 minutos.

☀️

Buenos días equipo

Enviado una vez al día entre 08:00 y 08:20. Flag de fecha en PropertiesService evita envíos duplicados si el trigger se ejecuta varias veces en ese rango.

⚙️
Configuración de triggers: En Apps Script → Editores → Activadores. verificarAlertasAutomaticas debe estar configurado como trigger "Basado en tiempo → Cada 10 minutos". Sin ese trigger, los avisos automáticos no funcionan.
10

Reglas de Uso y Disciplina Operativa

El sistema tiene controles técnicos que hacen imposible el registro falso. Las reglas complementan los controles automáticos.

🔒PIN personal e intransferible
Cada zona registrada queda con el nombre del operador que ingresó con ese PIN en la columna "Operador" de Google Sheets. Prestar el PIN = asumir responsabilidad sobre todos los registros generados. No existe forma de reasignar un registro ya guardado.
Freno anti-mafia: 30 segundos mínimo
El botón "Guardar zona" permanece bloqueado hasta que transcurran 30 segundos desde la última zona guardada. Un turno AM-1 con 37 zonas requiere mínimo ~18 minutos para completarse. Es físicamente imposible hacer una ronda completa en menos tiempo del que tarda en recorrer el hotel.
Ventanas horarias A&B
Fuera de la ventana horaria, el ítem no aparece en el checklist. Si se cierra el turno con ítems bloqueados, quedan documentados en PDF y correo. No hay forma de forzar el registro fuera de horario sin modificar el código fuente del servidor.
✏️Observaciones: máximo 80 caracteres
Restricción técnica (maxlength="80" en el input). Fuerza redacción precisa: qué, dónde, cuánto. "Sin endulzante en estación desayuno" es correcto. "El día de hoy al revisar la zona me percaté de que..." no es aceptable y no cabe. Si se necesita más detalle, adjuntar fotos.
🚨Warning obliga descripción
Al seleccionar Warning como incidencia, el campo de descripción se vuelve obligatorio y el botón "Guardar zona" permanece bloqueado hasta completarlo. No existe forma de guardar una zona con Warning sin descripción. Esto garantiza que todo push de alerta tenga contexto suficiente para que gerencia pueda actuar.
📊Trazabilidad completa
Cada zona guardada registra en Sheets: timestamp ISO, fecha, hora de ronda, hora de zona, turno, operador, rol, AO, área, nombre de zona, alerta calculada, y los 5 campos con sus observaciones. Los turnos no realizados quedan identificados por ausencia de registro en Control Rondas v6 para ese día y turno.
11

Hoja de Ruta

Funcionalidades confirmadas para las próximas versiones. La migración a Supabase elimina la dependencia de Google Sheets y el techo de invocaciones simultáneas.

v7 · Próximo

📱 Verificación por QR físico

  • QR adherido en cada área del hotel
  • Sin escaneo = zona bloqueada aunque esté en el checklist
  • Elimina registros sin presencia física comprobada
  • Registro de dispositivo y timestamp del escaneo
v7 · Próximo

🔔 Push preventivo A&B (15 min antes)

  • Alerta 15 min antes de la apertura de cada servicio
  • Recuerda al operador A&B que la ventana se abre pronto
  • Integrado con el sistema de ventanas horarias existente
v8 · Planificado

🗄️ Migración a Supabase + Next.js + Vercel

  • Elimina Google Sheets y Apps Script completamente
  • API Next.js en Vercel — sin límite de invocaciones simultáneas
  • Carga de dashboard en milisegundos (vs 8-15s actual)
  • Historial ilimitado sin degradación de rendimiento
  • Websockets para modo colaborativo real sin polling
v8 · Planificado

🤖 IA Predictiva Avanzada

  • Patrones recurrentes por zona, turno y operador
  • Predicción de fallas basada en historial (ML)
  • Comparativa de desempeño por operador con métricas
  • Integración con sistema de reservas para ajustar dotación
12

Flujos Operacionales y Arquitectura

Diagramas técnicos del sistema. Flujo completo de ronda, árbol de decisión por campo, protocolo de respuesta ante incidencias y arquitectura de capas con stack completo.

📋 Flujo Completo de una Ronda
Loop con bezier curve de retorno. Todos los nodos de decisión con sus condiciones exactas — anti-mafia, ventanas A&B, Warning, duplicados.
INICIO Login Nombre + PIN de 4 dígitos Ver Estado de Turnos AM-1 · AM-2 · PM-1 · PM-2 ¿Turno ya realizado hoy? Turno ya registrado Ver PDF · contactar supervisor No Iniciar Ronda horaInicio = timestamp actual Abrir Zona del Checklist Siguiente ítem del turno activo ¿Zona dentro de ventana horaria A&B? No Zona bloqueada ⏰ Pasa a siguiente zona ↩ Sí / N/A Registrar 5 Campos Estado · Dotación · Provisión Operación · Equipos ¿Incidencia = Warning? Descripción obligatoria ≤ 80 caracteres · campo forzado Botón bloqueado hasta completar No ¿Han transcurrido ≥ 30 segundos? No Anti-mafia activo Esperar · botón bloqueado Guardar Zona Registrar en Google Sheets 🔔 Push si Warning/OBS ¿Quedan zonas pendientes? No · todas completas Cerrar Ronda horaCierre = timestamp Generación Automática 📄 PDF en Drive · 📧 Correo Postmark 🔔 Push cierre a suscriptores RONDA COMPLETA ✓
🔍 Árbol de Decisión: ¿Qué registrar en cada campo?
3 salidas: OUT OF SERVICE (sin novedad), OBS (irregularidad menor), WARNING (crítico con descripción obligatoria).
Inspeccionando zona Estado visual y operacional ¿Algún campo con irregularidad menor? No ¿Incidencia crítica visible? No Out of service ✓ Zona sin novedad Registro OK Sí ↓ WARNING 🚨 Descripción obligatoria OBS ⚠️ Descripción ≤ 80c Alerta ámbar en dash Estado = OFF Registrar OFF Sin campos adicionales Guardar zona · Siguiente Anti-mafia 30s · luego ↩ loop
🏊 Protocolo de Respuesta ante Warning (Swim Lanes)
4 actores: Sistema automático / Supervisor / Área responsable / Siguiente turno. Tiempos objetivo: push ≤2 min, evaluación ≤5 min, acción correctiva ≤30 min si urgente.
ACTOR SISTEMA AUTOMÁTICO SUPERVISOR / GERENCIA ÁREA RESPONSABLE SIGUIENTE TURNO WARNING DETECTADO Trigger EVALUACIÓN INMEDIATA ≤ 5 min ACCIÓN CORRECTIVA según área VERIFICACIÓN Y CIERRE siguiente ronda HISTORIAL trazabilidad Warning registrado 🚨 Guardado en Google Sheets Push inmediato → OneSignal Área · zona · descripción Recibe push en celular Abre dashboard → ve zona Lee descripción del operador Tiempo: ≤ 2 minutos Dashboard actualizado Zona marcada en rojo KPI Warnings: +1 Tabla filtrable por alerta Evalúa urgencia ¿Riesgo para huéspedes? ¿Requiere acción inmediata? ¿Se puede diferir al turno? Recibe instrucción Llamada o mensaje del supervisor Contexto: zona + descripción + foto si adjuntó el operador Registrado en historial Protocolos por Área Hotelería → JH evalúa en terreno ≤20 min A&B → Chef/Maitre ajuste operacional Mantención / Equipos → OT creada · técnico asignado Seguridad / Piscinas → Cierre área si riesgo huésped Ejecuta acción correctiva · Resolución en terreno · Ajuste de personal si aplica · OT para equipo dañado · Comunicar a áreas afectadas Tiempo objetivo: ≤ 30 min si es urgente Antes del turno si no es crítico Verificación siguiente turno Operador inspecciona zona ¿Resuelto? → Out of service ✓ ¿No resuelto? → Nuevo Warning Confirma resolución Área informa al supervisor Estado: resuelto / pendiente Estimación si continúa Queda registrado en: · Google Sheets · PDF del turno · Correo enviado · Dashboard BI Trazabilidad completa: · Quién detectó · Hora exacta · Descripción · Fotos si adjuntó · Turno y fecha Disponible para: · Análisis IA (Gemini) · Panel BI histórico · Auditoría interna · Reportes gerenciales Ciclo cerrado · Warning documentado con trazabilidad completa en Google Sheets El sistema acumula historial → el panel BI detecta patrones recurrentes → la IA identifica causas sistémicas
🏗️ Arquitectura Técnica — 4 Capas
Cliente → API (Apps Script doPost router) → Datos (5 hojas Sheets) → Servicios externos (Postmark, OneSignal, Gemini, Drive). API keys en PropertiesService, nunca en frontend.
CAPA CLIENTE CAPA API CAPA DATOS SVCS EXT. App de Operadores HTML5 · Vanilla JS · CSS3 Optimizado móvil · PWA marketing.rosaagustina.cl/webapp/operaciones/ Intelligence Center Dashboard HTML5 · Chart.js BI + Gemini AI · Solo Supervisores …/operaciones/dashboard/ Manual Técnico HTML5 · Documentación Referencia operadores Entorno de ejecución Chrome / Safari / Firefox Celular · Tablet · Desktop Sin instalación · URL directa Google Apps Script · doPost() Router getUsuarios · login · saveZona · cerrarRonda · getRegistros · getRondaProgress · generarResumenIA LockService anti-concurrencia · validateSession · PropertiesService (API Keys) URL: script.google.com/macros/s/AKfycbzi…/exec Registros v6 Google Sheets Fecha · Turno · Operador 23 columnas · histórico Control Rondas v6 Google Sheets Estado turno · PDF URL Operador cierre Sesiones Token · Expiry Nombre · Rol 8h TTL Usuarios · Tokens · Drive Usuarios: Nombre · PIN · Rol · Email Tokens: reset PIN · uso único · 30min Drive: PDFs + fotos operadores 📧 Postmark Correo transaccional 🔔 OneSignal Push notifications 🤖 Gemini 2.5 Flash IA · resumen ejecutivo 📄 Google Drive PDFs + fotos operadores UrlFetchApp connector fetch() POST fetch() POST
🔒
Seguridad de API keys: Postmark, OneSignal y Gemini se almacenan en PropertiesService.getScriptProperties() en el servidor. El frontend solo llama al endpoint de Apps Script. Las keys nunca aparecen en el HTML ni en los logs del navegador.