# Etapa 7 · GPS y mapas de ZuliaGo

## Arquitectura y alcance

La Etapa 7 amplía la aplicación Python/PostgreSQL existente. Reutiliza JWT nativos, ámbito de portal firmado, `auth_version`, MFA OWNER, permisos y máquina de estados de pedidos. No utiliza Supabase Auth ni publica coordenadas a través de la Data API. La asignación sigue siendo manual: un repartidor aprobado acepta una entrega lista con versión esperada y bloqueo de fila. Omitir una solicitud solo la oculta para ese repartidor.

- Direcciones privadas de cliente: máximo 20, texto obligatorio, instrucciones y coordenadas opcionales, edición/eliminación propias.
- Ubicación del comercio: solo su propietario de comercio activo puede guardarla. No se inventan coordenadas para comercios existentes.
- Confirmación: dirección/coordenadas/instrucciones se copian en `order_destinations` en la misma transacción del pedido. Modificar/eliminar una dirección guardada no cambia pedidos históricos. Los pedidos anteriores sin punto conservan su dirección escrita y muestran que faltan coordenadas.
- GPS repartidor: permiso explícito, precisión máxima 100 m, lectura capturada hace máximo 30 s, frecuencia mínima servidor 5 s; cliente publica aproximadamente cada 10–20 s mientras la página está visible.
- Disponible: además de documentos, aprobación y latido existentes, requiere GPS en cobertura recibido hace menos de 90 s. Un latido no renueva GPS. Sin GPS puede ingresar y revisar su cuenta/historial, pero no recibir nuevas solicitudes.
- Seguimiento: SSE autenticado mediante `fetch` con Authorization; no JWT en URL. Solo cliente del pedido, comercio propietario, repartidor asignado y personal con `operations.read`. Reautorización cada tres segundos, conexiones de 25 s y reconexión con espera; máximo 2 conexiones por usuario y 32 por proceso. Se abortan al ocultar la pantalla o cambiar sesión. No mantiene conexiones de base de datos mientras espera en la red.
- Solo se revela GPS del repartidor en estados assigned/picked_up/on_the_way. Cerrar/cancelar el pedido elimina GPS de la respuesta y cierra el seguimiento. No hay consulta pública ni por ID arbitrario de repartidor.
- OWNER/empleados autorizados: mapa de repartidores disponibles recientes, pedidos abiertos (consulta limitada a los 200 más recientes), filtro por estado y aviso de revisión tras 30 min sin cambios. Este aviso no es una predicción de retraso respecto a una promesa de entrega.
- Cobertura técnica inicial: radio 15 km alrededor de 8.99868,-71.9089, configurable por OWNER con MFA reciente. No implica que todos los caminos sean transitables. Un domicilio con coordenadas fuera del radio se rechaza; sin coordenadas queda `unverified` para revisión del comercio. No se cambia el precio del domicilio ni la comisión.

## Mapas, licencias y costos

- Leaflet 1.9.4, copia local con licencia BSD-2-Clause y licencia incluida en `public/vendor/leaflet-1.9.4/LICENSE`.
- Cartografía OpenStreetMap: https://tile.openstreetmap.org/{z}/{x}/{y}.png. Atribución visible © OpenStreetMap contributors y enlace a corrección del mapa. Se usan únicamente mosaicos visibles, sin descargas masivas ni modo sin conexión, con caché normal del navegador y Referer de origen. Configurable mediante `ZULIAGO_MAP_TILES` por el operador para migrar a un proveedor compatible. No se admite una API de terceros elegida por usuarios.
- Rutas OSRM de FOSSGIS: https://routing.openstreetmap.de/routed-car/route/v1/driving/. Solicitud explícita por botón y consentimiento para compartir extremos de ruta; User-Agent de ZuliaGo, máximo una petición por 1,1 s por proceso, caché privada de 5 min, sin sondeo repetido por cada GPS. No se envían nombres, teléfonos, JWT ni número del pedido al proveedor.
- Ruta para automóvil basada en calles OSM, distancia/tiempo estimados sin tráfico. No se garantiza idoneidad legal para motocicletas, cierres, seguridad vial ni ETA exacta. Si faltan puntos o falla el proveedor, se informa y se ofrece navegación externa; no se dibuja una ruta ficticia en línea recta.
- Distancia al comercio en solicitudes: distancia geodésica aproximada claramente etiquetada, no distancia por carretera ni tarifa.
- Costos de contratación añadidos: 0. No hay nueva cuenta de pago ni facturación habilitada. Los proveedores públicos no tienen SLA y pueden bloquear uso intenso. El límite no equivale a una cuota comercial garantizada. Al crecer será necesario evaluar un proveedor contratado o infraestructura propia y obtener autorización antes de contratar. La limitación global de rutas está preparada para el servicio Render actual de un proceso; antes de escalar horizontalmente debe centralizarse.
- Verificación inicial real: el servicio devolvió código Ok, 1.955 m, 284,3 s y 29 puntos para un trayecto entre dos coordenadas de Santa Bárbara. Estas cifras describen la consulta técnica, no un pedido real ni una promesa de entrega.

Fuentes oficiales consultadas el 4 de noviembre de 2026:
https://operations.osmfoundation.org/policies/tiles/
https://routing.openstreetmap.de/about.html
https://github.com/Leaflet/Leaflet/tree/v1.9.4
https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API

## Privacidad y retención

Solo se guarda la última ubicación del repartidor; no hay historial de desplazamientos. Caduca lógicamente a los 90 s y se oculta aunque el servidor se reinicie. El trabajador de limpieza, cada minuto mientras Render está activo, borra coordenadas de más de cinco minutos. Si Render gratuito duerme, la limpieza física se realiza al volver a activarse; los puntos caducados siguen inaccesibles. Desconectar elimina de inmediato las coordenadas e invalida envíos antiguos de otras pestañas mediante una generación de seguimiento. Direcciones elegidas y domicilio del pedido tienen retención funcional permanente hasta la gestión autorizada de datos; no son el GPS temporal.

No se guardan coordenadas ni JWT en URLs de la aplicación, localStorage ni auditoría. LocalStorage conserva solo la preferencia de reanudar GPS por cuenta, sin coordenadas. Los eventos de dirección/cobertura/desconexión/omisión se auditan sin direcciones ni puntos. La cartografía y el cálculo de rutas son proveedores externos: sus políticas y posibles registros de IP/solicitudes se explican antes de usarlos. Las ubicaciones de navegador no constituyen prueba antifraude del lugar físico.

## Qué funciona según el dispositivo

| Contexto | Capacidad real |
| --- | --- |
| Página visible, permiso concedido y conexión | Solicitar GPS, enviar lecturas y actualizar mapa privado |
| Navegador en segundo plano | El controlador pausa el GPS y las suscripciones; disponibilidad caduca sin GPS reciente |
| Teléfono bloqueado | No se garantiza seguimiento web; no ha sido probado físicamente |
| Pérdida de conexión | Muestra el error, deja de afirmar frescura y reintenta al recuperar red/visibilidad |
| Futuras apps nativas | Pueden reutilizar APIs privadas y reglas de caducidad; GPS de fondo requerirá permisos, implementación nativa y pruebas propias |

## Cómo probar en iPhone

1. Cliente: entrar con su cuenta y abrir “Mis direcciones” o “Direcciones y mapa”. Escribir una dirección sin GPS o pulsar “Usar mi ubicación actual”, permitirla y revisar el marcador antes de guardar. Si estás fuera de Santa Bárbara, el GPS real indicará fuera de cobertura; puedes introducir manualmente una dirección real de Santa Bárbara y elegir su punto en el mapa.
2. Comercio EL SOL: entrar en su portal → Ubicación. Guardar su punto real en el mapa; no se ha asignado una ubicación de prueba al comercio.
3. Cliente: agregar un producto, abrir carrito, elegir la dirección guardada y confirmar un pedido de prueba coordinado, sin pago real.
4. Repartidor aprobado físicamente en cobertura: Conectarme con GPS, manteniendo la pantalla visible. Aceptar la entrega lista desde Pedidos. La aplicación no cambia las reglas de aprobación ni acepta pedidos automáticamente.
5. Abrir “Mapa y seguimiento privado” desde el pedido en cliente/comercio/repartidor, o Mapa en el portal del repartidor. Abrir mapa; solicitar la ruta por botón si se desea. Mantener la página visible para recibir SSE.
6. OWNER: Administración → Operaciones geográficas → Abrir mapa operativo. Usa MFA habitual; los empleados requieren permiso de operaciones.
7. Probar desconexión, volver a actualizar, cancelar/entregar el pedido y confirmar que desaparece la posición en vivo. No usar pedidos reales para simular pruebas.

## Migración y reversión

Migración aditiva `20261104061511_stage7_private_geolocation.sql`: cinco tablas nuevas, índices y columnas nullable de GPS/generación en driver_presence. RLS habilitado, sin acceso directo anon/authenticated. Sin alteración de cuentas, productos, fórmulas de comisión ni pedidos existentes. Se ejecuta idempotentemente al iniciar y queda registrada mediante la herramienta de migraciones de Supabase al publicar.

Para revertir código, conservar las tablas y sus datos, y volver al commit previo d75607923c9159e64d08383a4683d97660d44395. No ejecutar DROP ni restaurar registros. No empezar la Etapa 8 sin autorización.
