# Política de privacidad — Descubre Bareyo

Documento técnico del tratamiento de datos. Para el aviso legal público de cara al usuario, generar página HTML basada en este contenido en una versión adaptada por la asesoría legal del Ayuntamiento.

## Principios

1. **Sin cookies** propias ni de terceros para tracking.
2. **Sin direcciones IP** almacenadas.
3. **Sin user-agent identificador** completo (solo se deriva el tipo de dispositivo: mobile/tablet/desktop).
4. **Sin datos personales** salvo los que el propio usuario introduce voluntariamente en el formulario de alta de negocio.
5. **Almacenamiento local** (`localStorage`, `sessionStorage`, `IndexedDB`): solo para el funcionamiento del propio dispositivo (caché de APIs, idioma, tutorial visto, sesión analytics), nunca enviado a terceros.

## Datos que SÍ se recopilan

### Eventos analíticos (a partir de S7)

Cada evento envía a Supabase:

| Campo | Contenido | Justificación |
|---|---|---|
| `ts` | timestamp UTC | medir actividad temporal |
| `type` | `pageview`, `detail_open`, `qr_scan`, `gpx_download`, `phone_click`, `audio_play`, etc. | medir conversiones |
| `entity_id` | id del item (`bareyo-1`, `faro-ajo`...) | saber qué se consulta |
| `entity_type` | `route`, `costa`, `biz`, `3d` | agregaciones |
| `qr_id` | id del QR físico (si entró por QR) | medir efectividad de placas |
| `device` | `mobile`, `tablet`, `desktop` | dimensionar UX |
| `lang` | `es`, `en`, `fr`, `de` | dimensionar idiomas |
| `session_id` | identificador al azar generado en cliente (`sess-<aleatorio>-<marca de tiempo>`), vive en el navegador | distinguir sesiones SIN identificar persona |
| `meta` | `{ duration?, query?, ... }` | ampliable según evento |

### Subpáginas de sección (js/seccion.js)

Las ocho páginas de detalle (patrimonio, rutas, playas y costa, negocios, cumbres, agenda, ODA y el tiempo) cuentan la visita con el `pageview` normal (`meta.path`) y, solo cuando la persona pulsa para ir al mapa, con un evento `seccion_mapa`: `entity_id` y `entity_type` del lugar al que va (`hiking`, `costa`, `3d`, `biz`, `pico`, `aerea` —la clave pública de la panorámica— o `agenda` —para un acto o exposición, el id del recinto—; `seccion` si pulsa «Ver todo en el mapa»), `meta`: `seccion` y `destino` (`ficha` o `rama`). Descargar un GPX o pulsar un teléfono reutilizan `gpx_download` y `phone_click` con `meta.origen: 'seccion'`. El botón «Compartir» de la cabecera cuenta `seccion_compartir` (`entity_id` = clave de la sección, `entity_type` `seccion`, `meta`: `seccion` y `metodo`, `nativo` si se usa la hoja de compartir del móvil o `copia` si se copia el enlace; no se guarda con quién ni por dónde se comparte, solo que se compartió). Las placas QR de sección (`qr-print.html`) abren `/<sección>?qr=sec-<clave>`: la página cuenta un `qr_scan` con ese `qr_id` (solo ids con forma de placa: letras, números y guiones; el texto libre no se guarda) y quita `?qr=` de la dirección, igual que el mapa. Cuando el mapa abre una categoría registra `landing_mode` con `meta.mode` (la categoría) y `meta.via` (`seccion` si venía de una subpágina, `portada` si no). No llevan nada más allá de los campos comunes de la tabla anterior. La página de Playas y costa consulta Open-Meteo (oleaje y temperatura del agua en Ajo, sin enviar datos de la persona) y la función `api/banderas` del propio sitio. La de El tiempo consulta Open-Meteo (previsión para el punto fijo de Ajo: no se envía la posición de la persona) y guarda la respuesta 20 minutos en `localStorage` (`bareyo_tiempo_pagina`). La de ODA lee los mismos ficheros que el visor aéreo (`aereas.json` y `aereas-ajustes.json`) y nunca enseña una panorámica marcada como oculta.

### Visor 360° y panorámicas de dron (js/aereo.js)

Tres tipos de evento, siempre con la clave pública de la toma, su ruta, el origen de la apertura y contadores. Además de los campos comunes de la tabla de arriba (`device`, `lang`, `session_id`), no llevan nada del dispositivo ni de dónde mira la persona:

| `type` | Qué lleva | Cuándo |
|---|---|---|
| `visor360_open` | `entity_type` (`suelo` \| `aereo`), `entity_id` (clave de la toma), `qr_id` (el id de la placa, solo si la dirección trae `?qr=<id>` con forma de id —letras, números, guiones—, y solo cuando el visor se abre al cargar la página con `#aerea=`), `meta`: `ruta`, `origen` (`mapa`, `pin`, `galeria`, `ficha`, `enlace`, `restaurado` —la pestaña se recargó o la restauró el sistema—, `qr`), `kiosk` (solo en el tótem) | al abrir el visor |
| `visor360_close` | `meta`: `ruta`, `tomas` (distintas vistas), `pasos`, `vecinas`, `seg` (duración, tope 3.600) | al cerrarlo o al cerrar la pestaña (un solo resumen: las flechas no generan eventos). En el tótem la duración incluye los 90 s de espera hasta que se reinicia solo: el panel no la usa |
| `capa360_toggle` | `entity_type`, `meta.origen` (`pastilla`) | cuando una persona enciende la capa |

**El visor NO envía**: latitud ni longitud, hacia dónde se mira (yaw/pitch/zoom), el nombre de la gráfica (WebGL) ni el navegador, el referrer, texto libre de la persona ni su posición.
Con la guía en modo demostración (sin Supabase) todo queda solo en el navegador de quien prueba.

**No se recopila**: IP, user-agent completo, geolocalización GPS exacta (salvo que el usuario active "Empezar ruta" — y solo se usa en su dispositivo, no se sube), email, nombre, ningún dato del navegador identificador.

El `session_id` es **anónimo**: un identificador al azar guardado en el navegador. Si el usuario borra el almacenamiento del navegador, se rota. No permite identificar a la persona.

### Formulario de negocios: alta, cambios de ficha y cierre

Quien representa a un negocio introduce **voluntariamente** en `formulario-empresas.html`:

- Datos del negocio, que **se publicarán** si el Ayuntamiento los aprueba: nombre, sector, dirección, posición en el mapa,
  descripciones, teléfono, correo público, web, redes sociales, vídeo, horario, etiquetas y fotos.
- Datos de quien envía la solicitud, que **no se publican**: nombre, cargo, teléfono y, si quiere, correo electrónico.
- Mensajes que cruce con el Ayuntamiento sobre esa solicitud y, en un cierre, el motivo.

Antes de enviar hay que marcar una casilla de consentimiento que enlaza a esta página. No se pide NIF/CIF.

**Dónde se guardan**: en Supabase (`business_requests`, `business_request_messages` y el bucket `business-photos`),
a través de una función del propio sitio (`/api/solicitudes`). La base de datos no admite lecturas ni escrituras
con la clave pública de la web: solo el Ayuntamiento, con la sesión del panel, ve los datos de quien envía.
Con la guía en modo demostración (sin servidor configurado) todo queda solo en el navegador de quien prueba.

**Enlace de seguimiento**: al enviar se entrega un enlace privado con un código al azar. Quien tenga ese enlace ve
el estado, los cambios pedidos y los mensajes de esa solicitud (nunca los datos de contacto de quien la envió) y
puede escribir al Ayuntamiento. El código no se guarda en el servidor (solo su resumen SHA-256), no se puede
recuperar si se pierde y conviene no compartirlo. El navegador recuerda los enlaces enviados desde ese dispositivo
(`bareyo_biz_mis_solicitudes`) y un borrador de la solicitud a medio rellenar (`bareyo_biz_borrador`, sin fotos);
ambos se borran desde la propia página o vaciando los datos del sitio.

**No se envían correos electrónicos**: no hay proveedor de correo. La comunicación es el hilo del enlace de seguimiento.

**Contra el envío automático** se usan un campo señuelo, un tiempo mínimo y un tope de solicitudes por dirección IP;
la IP se usa solo en memoria para ese recuento y no se guarda.

**Base legal** (RGPD): consentimiento de quien envía (casilla) + interés público del Ayuntamiento en mantener actualizado el directorio comercial.

**Plazo de conservación**: solicitudes pendientes hasta resolución; aprobadas/rechazadas, máximo 2 años desde la decisión, después se
anonimiza a quien la envió y se borran los mensajes. Las fotos de solicitudes rechazadas se borran al rechazarlas.

### Almacenamiento local (no se envía a nadie)

| Clave `localStorage` | Contenido |
|---|---|
| `bareyo_lang` | idioma elegido |
| `bareyo_tutorial_seen` | `1` si ya vio el tutorial |
| `bareyo_session_id` | identificador anónimo al azar (`sess-…`) |
| `bareyo_boundary_cache` | polígono Bareyo de Nominatim (24 h) |
| `bareyo_weather_cache` | clima Open-Meteo (30 min) |
| `bareyo_tiempo_pagina` | previsión de la página «El tiempo» (20 min) |
| `bareyo_aereas_ajustes` | última copia buena del fichero público de ajustes de las panorámicas (qué tomas están ocultas): sirve para no enseñarlas si el fichero no se puede leer. La guardan el mapa y la página ODA |
| `bareyo_*_cache` | cualquier otra API |

Caché de Service Worker: shell de la app, GPX, tiles del mapa visitados.

## Datos que NO se recopilan ni transmiten

- IP del visitante (Descubre Bareyo no la guarda; cada servicio de la tabla de «Terceros» sí la ve, como cualquier servidor al que se conecta un navegador).
- User-agent identificador.
- Cookies de Google / Meta / Facebook.
- Posición GPS continua (solo durante la función opcional "Empezar ruta", y nunca sale del dispositivo).
- Historial de navegación.
- Identificadores publicitarios.

## Terceros con los que se comparte

Servicios técnicos invocados por el navegador del usuario:

| Servicio | Por qué se llama |
|---|---|
| **Open-Meteo** | clima, mareas, aire (no log de IP según ToS) |
| **Sunrise-Sunset.org** | amanecer/atardecer |
| **Wikipedia** | extractos de patrimonio |
| **OpenStreetMap (Nominatim, tiles vía CARTO)** | mapa base |
| **ArcGIS** (Esri) | tiles de satélite |
| **CartoDB** | basemap |
| **Google Maps** (solo enlace de "Cómo llegar") | navegación |
| **Supabase** | almacenamiento de eventos y formularios |
| **Google Fonts** | tipografías (Signika, DM Sans) |
| **Webs de los negocios y aytobareyo.org** | fotos de algunos negocios y de las noticias del Ayuntamiento (las de aytobareyo.org se piden sin cabecera `Referer`) |
| **jsDelivr / unpkg** | librerías del mapa y del visor 360° |

Cada uno tiene su propia política. La invocación se hace desde el navegador del usuario directamente — Descubre Bareyo no actúa como intermediario.

## Derechos del usuario (RGPD)

- **Acceso, rectificación, supresión, oposición**: contactar con el Ayuntamiento de Bareyo (a definir email DPD).
- **Datos analíticos**: al ser anónimos no son revertibles a una persona específica; el usuario puede borrar `localStorage` para rotar su `session_id`.
- **Borrado de solicitud de alta no resuelta**: contactar al Ayuntamiento adjuntando el id de la solicitud (devuelto al usuario al enviar el form).

## Cookie banner

**No se necesita cookie banner** mientras se mantenga la política descrita (sin cookies de tracking, sin terceros publicitarios). Si en el futuro se introduce Google Analytics o similar, sería obligatorio.

## Contacto

- Responsable: Ayuntamiento de Bareyo.
- Encargado del tratamiento (analytics): Clotitec — https://clotitec.com.
- Delegado de Protección de Datos: a definir por el Ayuntamiento.
