Tema representativo de entrevista

Entrevista frontend: ¿Cómo debe cooperar action.navigate con el fallback de clic?

FrontendIntermedio
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Diseña una notificación de pedido con acciones de ver, confirmar y ayuda, luego explica la prioridad de navegación, el manejo de fallbacks y la idempotencia para cada acción.

1. Prompt y alcance

Una notificación de estado de pedido ofrece las acciones Ver pedido, Confirmar entrega y Contactar a soporte. La aplicación puede estar cerrada, una ventana puede ya existir o la sesión puede haber expirado. Diseña el flujo con acciones de Notification y explica cómo la navegación del navegador coopera con notificationclick.

2. Lo que el entrevistador está evaluando

  • Entender que el navigate del cuerpo y el navigate de la acción son URLs separadas, donde la URL de una acción tiene precedencia sobre el manejo personalizado.
  • Saber que una acción sin URL llega a notificationclick, y mantener vivo el trabajo asíncrono con event.waitUntil.
  • Validar URLs del mismo origen, permisos, estado de autenticación y el ciclo de vida del Service Worker.
  • Usar etiquetas, claves de idempotencia de negocio y recuperación de clientes para evitar confirmaciones o ventanas duplicadas.

3. Preguntas para clarificar primero

  1. ¿Puede Confirmar entrega ser una navegación GET, o debe ser una API POST con confirmación?
  2. ¿Debería una sesión expirada abrir el inicio de sesión primero y reanudar la acción después?
  3. ¿Puede la acción de soporte dirigirse a un dominio externo de servicio al cliente?
  4. ¿Debería enfocarse una ventana existente, enviársele un mensaje o debería abrirse una nueva ventana?

4. Respuesta en treinta segundos

Mapearía las acciones de solo lectura de ver y ayuda a URLs del mismo origen en lista permitida, mientras dejo la acción de confirmación que genera efectos secundarios sin navigate. El Service Worker maneja esa acción a través de una API idempotente y luego enruta a la página de resultados. Se verifica cada URL, el trabajo asíncrono se envuelve en waitUntil y se enfoca una ventana controlada existente antes de abrir un fallback.

5. Análisis detallado paso a paso

Paso 1: Declarar URLs de cuerpo y de acción

js
await self.registration.showNotification("Order #123", {
  body: "Choose an action",
  tag: "order-123",
  navigate: "/orders/123",
  data: { orderId: "123", version: 4 },
  actions: [
    { action: "view", title: "View order", navigate: "/orders/123" },
    { action: "confirm", title: "Confirm delivery" },
    { action: "help", title: "Contact support", navigate: "/support/orders/123" },
  ],
});

Las URLs del cuerpo y de las acciones deben ser rutas validadas del mismo origen. Usa tag para actualizar o agrupar notificaciones de un pedido, y limita data a identificadores no sensibles necesarios para la recuperación.

Paso 2: Separar acciones de solo lectura y con efectos secundarios

Las acciones de ver y ayuda solo navegan y pueden ser manejadas por el navegador. Confirmar no tiene navigate, por lo que llega a notificationclick; debe llamar a una API de servidor idempotente en lugar de codificar un cambio de estado en los parámetros de consulta.

Paso 3: Implementar fallback de notificationclick

js
self.addEventListener("notificationclick", (event) => {
  event.notification.close();
  const { orderId, version } = event.notification.data ?? {};
  if (event.action !== "confirm" || !orderId) return;

  event.waitUntil(confirmDelivery(orderId, version).then(() =>
    focusOrOpen(`/orders/${encodeURIComponent(orderId)}?confirmed=1`)));
});

El código de producción debe capturar fallas de red, versiones obsoletas y respuestas no autorizadas, y permitir que la página de resultados presente la recuperación. waitUntil mantiene vivo el evento del Service Worker hasta que la promesa se resuelva.

Paso 4: Manejar ventanas y recuperación de inicio de sesión

focusOrOpen debe coincidir con una ventana controlada del mismo origen, enviar una ruta validada a través de postMessage y llamar a clients.openWindow solo cuando no exista una ventana adecuada. Si el inicio de sesión expiró, transporta solo un estado objetivo de corta duración; después de iniciar sesión, la página debe obtener y autorizar el pedido nuevamente.

Paso 5: Seguridad, permisos e idempotencia

El permiso de notificación controla la visualización, no la autorización del pedido. Restringe el protocolo, origen y ruta; usa el ID del pedido, la versión o una clave de idempotencia para evitar confirmaciones duplicadas. El descarte, las etiquetas duplicadas y los clics simultáneos en dispositivos requieren un comportamiento explícito de máquina de estados en el servidor.

6. Respuesta modelo de alta calidad

Usaría navigate del mismo origen para ver y ayuda, y manejaría Confirmar entrega en notificationclick porque tiene un efecto secundario. El Service Worker usa waitUntil para llamar a una API idempotente con la versión y clave del pedido, luego enfoca una ventana existente o abre la ruta de resultados. Cada URL está en una lista permitida, el permiso no es autorización y la recuperación del inicio de sesión vuelve a verificar el acceso. Las pruebas cubren clics en el cuerpo y en acciones, repeticiones, modo fuera de línea, versiones obsoletas y múltiples ventanas.

7. Errores comunes

  • Desencadenar la confirmación a través de una URL GET → la precarga o repeticiones causan efectos secundarios → llama a un POST idempotente desde el evento.
  • Asumir que una acción sin URL abre la URL del cuerpo → el comportamiento es ambiguo → manéjalo explícitamente en notificationclick.
  • Poner el pedido completo en data → se filtra información sensible → transporta un identificador y vuelve a obtener los datos autorizados.
  • Omitir waitUntil alrededor del trabajo asíncrono → el Worker puede terminar prematuramente → gestiona cada promesa crítica.
  • Crear siempre una nueva ventana → estado dividido → busca y enfoca primero una ventana del mismo origen.

8. Preguntas de seguimiento

Pregunta de seguimiento 1: ¿Cuál tiene prioridad, action.navigate o notificationclick?

Cuando una acción tiene su propio navigate, el navegador puede usar esa URL. Una acción sin ella necesita un manejo personalizado de notificationclick.

Pregunta de seguimiento 2: ¿Por qué no poner la confirmación en la URL?

La navegación puede ser precargada, reproducida o recibir clics repetidos y no puede representar de forma segura un efecto secundario. La confirmación pertenece a una transición de estado de servidor autorizada e idempotente.

Pregunta de seguimiento 3: ¿Cómo te recuperas de un inicio de sesión expirado?

Almacena un estado objetivo de corta duración protegido contra alteraciones al abrir el inicio de sesión. Después de iniciar sesión, la página obtiene el pedido, verifica la autorización y luego restaura la ruta de resultados.

Pregunta de seguimiento 4: ¿Cómo demuestras que no hay ejecuciones duplicadas?

Desencadena clics en el cuerpo y en las acciones repetidamente a través de ventanas y dispositivos con la misma versión de pedido y clave de idempotencia, luego verifica que el servidor realice solo una transición de confirmación.

Fuentes públicas

Preguntas relacionadas