# 🤖 AGENT MANIFEST — HAP (La-vamos Cuidando)
## Manifiesto Maestro de Reglas de Negocio, Arquitectura y Directrices del Proyecto

> **Documento Oficial de Referencia para Desarrolladores y Agentes de IA.**  
> Este manifiesto condensa todas las reglas de negocio, arquitectura técnica, modelos de datos, flujos operativos, políticas financieras y directrices de ingeniería de la plataforma **HAP**. Cualquier modificación al código debe respetar estrictamente los principios descritos en este archivo.

---

## 📑 Tabla de Contenidos
1. [Identidad del Negocio y Misión](#1-identidad-del-negocio-y-misión)
2. [Arquitectura Técnica y Entornos](#2-arquitectura-técnica-y-entornos)
3. [Actores y Roles del Sistema](#3-actores-y-roles-del-sistema)
4. [Estructura Tripartita del Sistema (Torre de Control | User App | Happer App)](#4-estructura-tripartita-del-sistema-torre-de-control--user-app--happer-app)
5. [Modelo de Datos y Tablas Clave](#5-modelo-de-datos-y-tablas-clave)
6. [Catálogo de Vehículos, Tapicerías y Servicios](#6-catálogo-de-vehículos-tapicerías-y-servicios)
7. [User App: Modalidades de Servicio, Portal de Bienvenida y Reglas de Despacho](#7-user-app-modalidades-de-servicio-portal-de-bienvenida-y-reglas-de-despacho)
   - 7.5 [Exclusividad Operativa por Vehículo, Prevención de Doble Solicitud e Idempotencia](#75-regla-de-negocio-inquebrantable-exclusividad-operativa-por-vehículo-prevención-de-doble-solicitud-e-idempotencia)
   - 7.6 [Control Estricto de Cobertura Geográfica por Código Postal (15 C.P. Autorizados)](#76-regla-de-negocio-mandatoria-control-estricto-de-cobertura-geográfica-por-código-postal-15-cp-autorizados)
   - 7.7 [Control de Capacidad por Horario (Máx 2 Reservas) y Toque de Queda Matutino Post-16:00](#77-regla-de-negocio-mandatoria-control-de-capacidad-por-horario-máximo-2-reservas-y-toque-de-queda-matutino-post-1600)
8. [User App: Ecosistema de Membresía HAP](#8-user-app-ecosistema-de-membresía-hap)
9. [User App: Políticas de Cancelación y Reembolso de Servicios](#9-user-app-políticas-de-cancelación-y-reembolso-de-servicios)
10. [Happer App: Flujo Operativo, App 2.0 y Protocolo de 5 Pasos](#10-happer-app-flujo-operativo-app-20-y-protocolo-de-5-pasos)
11. [Torre de Control Operativa (Mission Control)](#11-torre-de-control-operativa-mission-control)
12. [Pasarela de Pagos (Stripe) y Seguridad Financiera](#12-pasarela-de-pagos-stripe-y-seguridad-financiera)
13. [Programa de Referidos y Facturación CSF](#13-programa-de-referidos-y-facturación-csf)
14. [Reglas de Oro y Directrices para Futuros Agentes](#14-reglas-de-oro-y-directrices-para-futuros-agentes)
15. [Arquitectura Global de 4 Aplicaciones y Estándar Enterprise DB](#15-arquitectura-global-de-4-aplicaciones-y-estándar-enterprise-db)

---

## 1. Identidad del Negocio y Misión

### 1.1 ¿Qué es HAP?
**HAP (La-vamos Cuidando)** es una startup de car wash ecológico y detallado automotriz a domicilio con base en **Querétaro, México** (cobertura en Zibatá, El Refugio, Juriquilla, Campanario, Cumbres del Lago, Centro y zonas conurbadas).

### 1.2 Misión y Propuesta de Valor
- **Cuidado del Agua**: Lavado exterior en seco mediante polímeros y ceras biodegradables de alta tecnología que encapsulan las partículas de polvo y suciedad, levantándolas sin rayar la pintura (*sin usar agua a presión*).
- **Cero Pérdida de Tiempo para el Cliente**: El servicio se realiza directamente donde está el vehículo (cochera, estacionamiento de oficina, condominio) sin traslados ni filas.
- **Experiencia Digital Premium**: Plataforma web ágil donde el cliente solicita servicios bajo demanda en <15 segundos, programa citas futuras o gestiona su membresía en piloto automático.
- **Dignificación del Lavador (Happer)**: Los Happers son operadores capacitados que se desplazan en motocicleta con equipo autónomo, telemetría GPS en tiempo real y asignación justa de rutas.

### 1.3 URLs y Puntos de Acceso Oficiales
- **Web App Clientes / Acceso General**: `https://lavamoscuidando.com/HAP/SISTEMA/CLIENTE/` (Portal de bienvenida con selección de rol en `index.php`).
- **Torre de Control Operativa (Supervisión)**: `https://lavamoscuidando.com/HAP/SISTEMA/TORRE_CONTROL/` (Login dedicado en `login.php`).
- **HAP Driver App 2.0 (Conductores Oficial)**: `https://lavamoscuidando.com/HAP/SISTEMA/HAPPER_APP/` (Login y PWA ultra ligera).
- **App Clásica Happers (OBSOLETA/BLOQUEADA)**: `https://lavamoscuidando.com/HAP/SISTEMA/HAPPERS/` (Bloqueada con `modal_obsoleto.php`).
- **Correos de Notificación**: `admin@soyhap.com`, `facturacion@soyhap.com`, `dann.arenas@outlook.com`.

---

## 2. Arquitectura Técnica y Entornos

### 2.1 Stack Tecnológico
- **Backend**: PHP 8.1+ nativo / procedural estructurado con MySQLi.
- **Base de Datos**: MySQL 8.0 (Base de datos: `hap`, cotejamiento general: `utf8mb4_general_ci` / `utf8_spanish_ci`).
- **Frontend**: Vanilla JavaScript (ES6+), CSS3 moderno (Variables CSS, Flexbox, Grid, Cyberpunk dark mode en Torre de Control, Clean UI Mobile-First en Cliente/Happer).
- **Mapas y Geoespacial**: Leaflet.js 1.9.4 con mosaicos de **CartoDB Voyager** (`https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png`) y respaldo automático a **Esri World Street Map** vía CloudFront Edge en Querétaro.
- **Pagos**: Stripe API (SDK Stripe-PHP, Stripe Elements, PaymentIntents, Customers, PaymentMethods, cargos off-session y Webhooks).
- **Audio y Notificaciones**: Web Audio API sintetizado en tiempo real (chime melódico sin archivos de audio externos) y Web Push API.

### 2.2 Servidor de Producción
- **Host**: `95.111.214.233` (Ubuntu 22.04.1 LTS).
- **Ruta Web**: `/var/www/html/hap/`.
- **Acceso SSH**: `root@95.111.214.233` mediante llave privada `/Users/dann/.ssh/hap_key.pem`.
- **Servidor Web**: Apache 2.4 con PHP 8.1+ y extensiones (`mysqli`, `curl`, `json`, `mbstring`, `openssl`).

### 2.3 Entorno de Desarrollo Local & Conectividad
- **Directorio Local**: `/Users/Dann/Server/ha-p/`.
- **Túnel SSH a Producción**: Script `./conectar_produccion.sh` que mapea el puerto local `3307` directamente al MySQL de producción en `95.111.214.233:3306`.
- **Conector MySQL (`Connections/higo.php`)**:
  - **Prioridad #1**: `127.0.0.1:3307` (consume la base de datos viva de producción en tiempo real).
  - **Fallback #2**: `127.0.0.1:3306` / `localhost` (base de datos local en caso de desconexión).
- **Script de Respaldo**: `./respaldar_produccion.sh` clona la base de datos de producción a local bajo demanda.

### 2.4 Protocolo de Despliegue Estricto
1. **Validación Previa**: Verificar que no existan errores de sintaxis (`php -l [archivo]` y `node -c [archivo]`).
2. **Transferencia Segura**: Usar `scp -i ~/.ssh/hap_key.pem` hacia la ruta destino en `/var/www/html/hap/...`.
3. **Propiedad de Archivos**: Ejecutar inmediatamente en el servidor `chown -R www-data:www-data /var/www/html/hap/...`.
4. **Cache-Busting Obligatorio**: En los llamados a assets en PHP, inyectar siempre versión dinámica `?v=<?= time() ?>` para obligar al navegador a recibir el código nuevo sin requerir vaciado manual de caché.

---

## 3. Actores y Roles del Sistema

```mermaid
flowchart TD
    Cliente["👤 Cliente (Usuario Final)"]
    Happer["🛵 Happer (Operador de Lavado)"]
    Torre["🛰️ Torre de Control (Supervisor)"]
    Stripe["💳 Pasarela Stripe"]
    DB[("🗄️ Base de Datos MySQL")]

    Cliente -->|"Pide Express / Programa Cita / Membresía"| DB
    DB -->|"Despacho y Asignación"| Torre
    Torre -->|"Asigna Ruta"| Happer
    Happer -->|"Telemetría GPS / Escaneo QR"| DB
    Happer -->|"QR Finaliza Lavado"| Stripe
    Stripe -->|"Captura / Cargo Off-Session"| DB
```

### 3.1 Cliente (`clientes`)
- Usuario final registrado en la plataforma.
- Gestiona su perfil, libreta de direcciones (`clientes_direcciones`) y vehículos en Mi Garage (`clientes_autos`).
- Solicita servicios en modalidades: HAP Express (bajo demanda), Cita Programada o Canjes de Membresía HAP ($0.00 MXN).
- Dispone de código único de referidos (`HAPxxxxx`) y crédito acumulado.
- Puede cargar su Constancia Fiscal (CSF) para solicitar facturas en 1 clic.

### 3.2 Happer (`usuarios` con rol `happer`)
- Operador móvil que viaja en motocicleta con uniforme y mochila técnica de productos.
- Transmite periódicamente su ubicación GPS (`happer_ubicaciones`).
- Cuenta con agenda de servicios asignados y un pool de servicios programados de la semana (desbloqueados 24h antes).
- Escanea el código QR del cliente al iniciar (`INICIADO` / `PROCESO`) y al terminar (`FINALIZADO`).
- Recibe alertas de bajo stock con cooldown de 12 horas.

### 3.3 Supervisor / Operador (`usuarios` con rol `admin`)
- Monitorea la operación global en vivo desde la **Torre de Control** (`/HAP/SISTEMA/TORRE_CONTROL/`).
- Despacha y asigna Happers a órdenes huérfanas en <10 segundos.
- Controla reprogramaciones, cancelaciones asistidas y llamadas directas de soporte vía WhatsApp.
- Supervisa la capacidad semanal por día para los socios con DÍA HAP.

---

## 4. Estructura Tripartita del Sistema (Torre de Control | User App | Happer App)

La arquitectura de software de **HAP** está dividida estrictamente en tres módulos independientes con fronteras de responsabilidad bien delimitadas. Cualquier nuevo desarrollo o agente de IA debe identificar en cuál de estos tres pilares se sitúa su tarea:

```mermaid
graph TD
    subgraph MOD_TORRE ["🛰️ TORRE DE CONTROL (Supervisión & Despacho)"]
        TC_DIR["/HAP/SISTEMA/TORRE_CONTROL/"]
        TC_LOGIN["login.php / logout.php"]
        TC_RADAR["index.php (Radar Leaflet + Kanban)"]
        TC_DASH["dashboard.php (Analíticas, CRM & Gamificación)"]
        TC_CLIENTE["cliente.php (Expediente 360°)"]
        TC_API["api.php & api_dashboard.php (<20ms, No N+1)"]
    end

    subgraph MOD_USER ["👤 USER APP (Experiencia del Cliente)"]
        UA_DIR["/HAP/SISTEMA/CLIENTE/"]
        UA_INDEX["index.php (Bifurcación: Usuario vs Happer)"]
        UA_AUTH["login.php / registro.php (Referidos HAPxxxxx)"]
        UA_EXPRESS["hapiar.php (HAP Express Bajo Demanda)"]
        UA_PROGRAM["programar_servicio.php (Citas 5 Pasos)"]
        UA_GARAGE["mi_garage.php (Autos, Tamaños, Tapicerías)"]
        UA_MEMB["membresias.php & suscripcion_dia_hap.php"]
    end

    subgraph MOD_HAPPER ["⚡ HAPPER APP (Conductores 2.0 & Legacy Lock)"]
        HA_DIR2["/HAP/SISTEMA/HAPPER_APP/ (Oficial 2.0)"]
        HA_LOGIN["login.php (Sesión Única: session_token)"]
        HA_RADAR["index.php (Radar & Aceptación de Citas)"]
        HA_MISION["mision.php (HUD Unidireccional 5 Pasos)"]
        HA_API["api.php (validar_qr_pin, verificar_fotos_inspeccion)"]
        
        HA_LEGACY["/HAP/SISTEMA/HAPPERS/ (LEGACY BLOQUEADO)"]
        HA_LOCK["modal_obsoleto.php (Capa de Bloqueo Absoluta)"]
    end

    MOD_USER -->|"Crea Orden (requires_capture / $0.00)"| DB[("MySQL Database (venta_desc)")]
    DB -->|"Telemetría & Alertas"| MOD_TORRE
    MOD_TORRE -->|"Smart Dispatch / Conclusión Admin"| DB
    DB -->|"Asignación / Señal Remota (modal_torre_signal)"| MOD_HAPPER
    MOD_HAPPER -->|"Validación QR / 4 Fotos / Término"| DB
    MOD_HAPPER -->|"Captura Definitiva"| Stripe["💳 Pasarela Stripe"]
    MOD_TORRE -->|"Captura Forzada"| Stripe
```

### 4.1 🛰️ Módulo 1: Torre de Control (Mission Control)
- **Directorio Raíz**: `/HAP/SISTEMA/TORRE_CONTROL/`
- **Público Objetivo**: Supervisores operativos, despachadores logísticos, directores de zona y gerencia de operaciones.
- **Puntos de Acceso Clave**:
  - `login.php` & `logout.php`: Portal seguro independiente con estética Dark Glassmorphic, sin dependencias de scripts externos obsoletos. Autenticación multiformato (usuario o email) contra `usuarios` con hash bcrypt seguro.
  - `index.php` (Radar Operativo & Despacho en Vivo): Pantalla dividida con Mapa Leaflet (mosaicos CartoDB Voyager y fallback Esri Edge), marcadores de conductores con telemetría en tiempo real, y tablero Kanban interactivo en 4 columnas (`POR ASIGNAR`, `EN TRASLADO`, `EN LAVADO`, `COMPLETADOS`) con scroll vertical independiente.
  - `dashboard.php` (Suite de Mando Integral): KPIs ejecutivos en vivo, gráficos de facturación y mix de especialidades (Chart.js reactivo al cambio de tema), ranking por Código Postal con motor de corte mensual automatizado (`execute_monthly_closure`), CRM directorio maestro de clientes (~665 usuarios) con exportación CSV UTF-8 BOM y alta rápida (`+ Nuevo Cliente`).
  - `cliente.php` (Expediente 360°): Radiografía analítica del cliente, Health Score predictivo de churn (0-100%), inventario de autos con conteo de lavados, galería fotográfica de calidad y notas confidenciales en tiempo real (`clientes.nota`).
  - `api.php` & `api_dashboard.php`: Backends ultra acelerados con latencia <20 ms (eliminación de consultas N+1 con agregaciones `GROUP BY`).
- **Reglas de Oro del Módulo**:
  1. *Cero Bucles N+1*: Terminantemente prohibido ejecutar consultas SQL dentro de bucles sobre happers o clientes. Usar siempre agregación `GROUP BY`.
  2. *Estabilidad Cartográfica*: Prohibido reintroducir mosaicos de OpenStreetMap oficial (bloqueados en navegadores modernos) o asociar `ResizeObserver` a `#leaflet-map`.
  3. *Conclusión Administrativa Asistida (`finalizar_servicio_admin`)*: Permite cerrar servicios ante contingencias de campo, ejecutando obligatoriamente la captura en Stripe (`$intent->capture()`), asentando el motivo en `venta_desc.comentarios` y liberando la flota.
  4. *Watchdog Logístico Preventivo*: Monitoreo automático en telemetría que cancela órdenes huérfanas >24h y restituye lavados de membresía automáticamente.

### 4.2 👤 Módulo 2: User App (Web App Clientes)
- **Directorio Raíz**: `/HAP/SISTEMA/CLIENTE/`
- **Público Objetivo**: Clientes particulares, usuarios recurrentes y socios de membresía HAP.
- **Puntos de Acceso Clave**:
  - `index.php`: Portada de bienvenida Dark Glassmorphic mobile-first con slider de propuesta de valor y bifurcación limpia de roles en 1 toque:
    - Botón `[ 🚗 SOY USUARIO ]` -> canaliza al flujo de clientes (`login.php`).
    - Botón `[ ⚡ SOY HAPPER ]` -> canaliza directamente a la app de conductores (`/HAP/SISTEMA/HAPPER_APP/`).
  - `hapiar.php` (HAP Express): Solicitud inmediata bajo demanda en pantalla única fluida (<15 segundos), cálculo de tiempo de llegada estimado (40 - 120 min).
  - `programar_servicio.php` (Citas Programadas): Wizard guiado en 5 pasos (Auto, Servicio, Domicilio, Fecha/Hora con anticipación mínima de 3h, Método de Pago/Membresía).
  - `sincronizador_dias_hap.php` & `membresias.php`: Motor de suscripción recurrente semanal para el DÍA HAP, selección de días de lavado fijos y control de bolsas de membresía.
  - `mi_garage.php`: Registro y administración de autos en 3 categorías homologadas (`CHICO`, `MEDIANO`, `GRANDE`) y tapicerías (`💺 TELA` / `🛋️ PIEL`).
  - `historial_servicios.php` & `datos_facturacion.php`: Historial de órdenes, calificación en estrellas y solicitud de facturas CFDI con adjunto de CSF.
- **Reglas de Oro del Módulo**:
  1. *Regla Inquebrantable de Membresía (Upgrade & Copago)*: Todo socio con membresía activa tiene 100% cubierto el `LAVADO HAP` base de su categoría ($0.00 MXN). Si el socio selecciona un servicio superior (`ENCERADO`, `PROTECTOR`, `COMBOS`, `INTEGRAL`), el sistema bonifica el valor comercial del lavado base y cobra en Stripe **únicamente la diferencia económica** ($P_{\text{servicio}} - V_{\text{lavado\_base}}$), descontando 1 lavado de su membresía.
  2. *Stripe en 2 Fases (Retención Manual)*: Al solicitar el servicio con tarjeta, el cobro se crea siempre con `capture_method: manual` (retención previa). El cobro real en firme se captura única y exclusivamente al concluir el lavado.
  3. *Regla de $0.00 MXN*: Jamás crear un `PaymentIntent` en Stripe con monto `0`. Marcar la orden directamente con estatus de membresía o cupón sin llamar a Stripe.
  4. *Política de Cancelación*: Reagendar es siempre $0.00 MXN. Si cancela definitivamente: $0 si es con >3h, $75 si es <3h, 100% si el Happer ya arribó.

### 4.3 ⚡ Módulo 3: Happer App (App Conductores 2.0 & Deprecación Legacy)
- **Directorio Oficial 2.0**: `/HAP/SISTEMA/HAPPER_APP/`
- **Directorio Clásico (BLOQUEADO/OBSOLETO)**: `/HAP/SISTEMA/HAPPERS/`
- **Público Objetivo**: Operadores móviles de lavado (Happers en motocicleta con equipo autónomo).
- **Puntos de Acceso Clave**:
  - `HAPPER_APP/login.php`: Acceso móvil ergonómico con control estricto de sesión única por dispositivo (`session_token`).
  - `HAPPER_APP/index.php`: Radar de misiones activas y pool de citas programadas disponibles, telemetría y switch de disponibilidad.
  - `HAPPER_APP/mision.php`: Interfaz operativa de misión estructurada como HUD unidireccional de 5 pasos con cronómetros, checklist y captura de evidencias.
  - `HAPPER_APP/api.php`: Endpoints móviles ultrarrápidos (`validar_qr_pin`, `subir_evidencia`, `verificar_fotos_inspeccion`, `finalizar_lavado`, `consultar_estado_mision`).
  - `HAPPERS/modal_obsoleto.php`: Componente de intercepción y bloqueo forzado inyectado en todos los archivos legacy (`happer.php`, `index.php`, `login_happer.php`, `aceptar_servicio_happer.php`) con capa `z-index: 9999999` y botón de migración a la app 2.0.
- **Reglas de Oro del Módulo**:
  1. *Sesión Única por Dispositivo (`session_token`)*: Ningún Happer puede operar en dos teléfonos o pestañas a la vez. Al abrir sesión en un nuevo dispositivo, la sesión previa se revoca inmediatamente respondiendo con `HTTP 401 Unauthorized` (`SESSION_DUPLICATED`).
  2. *Exclusividad Operativa (1 Solo Servicio Activo)*: Un Happer jamás puede tomar o tener asignado más de un servicio activo (`ACEPTADO`, `EN_CAMINO`, `PROCESO`, `INICIADO`) del día en curso.
  3. *Protocolo de Misión Estrictamente Unidireccional de 5 Pasos*:
     - **Paso 1 (En Camino / Arribo)**: Happer marca salida y llegada (`EN_CAMINO` -> `EN_SITIO` con timestamp `espera`).
     - **Paso 2 (Inspección Previa de 4 Ángulos)**: Obligatoriedad de fotografiar `FRENTE`, `COSTADO_IZQ`, `COSTADO_DER` y `TRASERA`.
     - **Paso 3 (Identidad y Arranque)**: Escaneo de QR o PIN de 4 dígitos del cliente para arrancar (`PROCESO`).
     - **Paso 4 (Lavado Ecológico Activo)**: Cronometría mínima obligatoria de 30 minutos + Checklist de calidad 4/4.
     - **Paso 5 (Entrega y Finalización)**: 4 fotos de entrega final (`FINAL_*`), validación de QR/PIN de entrega y captura bancaria (`FINALIZADO`).
  4. *Verificación Asíncrona de Fotos en Servidor (`verificar_fotos_inspeccion`)*: Antes de permitir avanzar del Paso 2 al Paso 3, el sistema consulta físicamente la tabla `fotos` en MySQL. Si falta algún ángulo por fallos de red celular, bloquea el avance y alerta con Toast qué cuadrante específico falta para re-tomarlo.
  5. *Bloqueo Total de Retroceso*: Los pasos completados en el HUD quedan sellados con estado `.completed` y checkmark verde. Si el Happer toca un paso completado, se bloquea el retroceso con alerta de protocolo progresivo unidireccional. Las fotos de inspección inicial quedan inmutables.
  6. *Ventana de 45 Minutos para Citas Programadas*: Las citas agendadas futuras no bloquean al Happer hoy y solo pueden iniciarse 45 minutos antes de la hora acordada.
  7. *Sincronización Reactiva Remota (`modal_torre_signal`)*: Si Torre de Control finaliza o cancela el servicio remotamente, el Happer recibe la señal al instante, se detienen cronómetros y se muestra el modal explicativo, liberándolo para nuevas misiones.
  8. *Deprecación Absoluta de la App Clásica*: Ninguna operación debe permitirse en `/HAP/SISTEMA/HAPPERS/`. Toda actividad debe canalizarse a `/HAP/SISTEMA/HAPPER_APP/`.
  9. *Optimización para Gama Baja, Ahorro Extremo de Datos y Resiliencia a Cortes de Red*:
     - La flota opera en smartphones Android modestos (2-3 GB RAM, CPU básica), con planes de datos móviles prepago reducidos y cortes recurrentes de red celular en carretera, casetas o sótanos.
     - PWA ultraligera (<200 KB) en Vanilla JS y CSS nativo sin frameworks pesados ni dependencias superfluas.
     - Compresión fotográfica local en Canvas obligatoria (máx 1280-1600px, JPEG 0.72) reduciendo fotos de ~10 MB a <200 KB (ahorro >95% de datos móviles).
     - Persistencia de estado y cronómetro en `localStorage` ante reinicios o cierres involuntarios.
     - Tolerancia a fallos: retener previews locales y ofrecer reintento en 1 clic ante pérdidas de señal sin resetear formularios.
  10. *Persistencia Continua de Sesión en Campo (Zero-Logout Policy & Auto-Restore Indefinido)*:
      - La sesión del dispositivo activo DEBE permanecer abierta y autenticada indefinidamente (365 días).
      - Los operadores en campo nunca deben ser desconectados por inactividad, bloqueo de pantalla, reinicio del teléfono o cierre del navegador.
      - Si la sesión en memoria PHP expira, el sistema auto-restaura silenciosamente la sesión en segundo plano (<1ms) utilizando el `session_token` persistente.
      - Únicamente se invalida por: (1) Cierre voluntario (`logout.php`), (2) Inicio en otro dispositivo (Monosesión), o (3) Baja administrativa (`status = 'BAJA'`).

---

## 5. Modelo de Datos y Tablas Clave

### 5.1 `venta_desc` (Tabla Maestra de Servicios y Órdenes)
Es la tabla neurálgica de la operación.
- `id` (int, PK): Número de servicio visible para el cliente y en Torre de Control (`#ID`).
- `cliente` (int): ID foráneo a `clientes.id`.
- `fecha` (date) y `hora` (time): Fecha y hora pactada para la ejecución del servicio.
- `auto` (varchar): Detalles del vehículo (alias, modelo, placas).
- `tipo` (varchar): Nombre del servicio (ej. `LAVADO HAP`, `ENCERADO HAP`, `COMBO BRILLO & PLASTICOS`).
- `estatus` (varchar):
  - `PENDIENTE`: Servicio solicitado en espera de asignación de Happer.
  - `PROGRAMADO`: Cita futura agendada o Día HAP generado.
  - `INICIADO` / `PROCESO`: Happer en el sitio lavando el vehículo.
  - `FINALIZADO`: Lavado concluido exitosamente mediante escaneo QR.
  - `CANCELADO`: Servicio cancelado con registro de motivo y fee.
- `happer` (varchar/int): Usuario o ID del Happer asignado.
- `total` (decimal): Importe total cobrado (`0.00` en canjes de membresía o cupones 100%).
- `lat` y `lon` (varchar): Coordenadas geográficas del domicilio de atención.
- `es_dia_hap` (tinyint): `1` si corresponde a una rutina semanal recurrente de membresía.
- `membresia_id` (int): ID foráneo a `clientes_membresias.id`.
- `alta` (datetime): Timestamp exacto de creación de la orden.
- `asignado_at`, `inicio_at`, `fin_at`: Marcas de tiempo de transición operativa.
- `factura_solicitada` (tinyint): `1` si el cliente ya solicitó factura CFDI.
- `cancel_motivo`, `cancel_reembolso`, `cancel_fee`, `cancel_at`: Datos de auditoría de cancelación.

> **Índices Obligatorios de Alto Desempeño en `venta_desc`**:
> - `idx_happer_estatus (happer, estatus)`
> - `idx_alta_estatus (alta, estatus)`
> - `idx_cliente (cliente)`

### 5.2 `clientes`
- `id` (int, PK): Identificador único.
- `nombre`, `correo`, `telefono`: Datos de contacto y autenticación.
- `ref` / `referido_codigo`: Código único del cliente (ej. `HAP82414`).
- `referido_credito` (decimal): Saldo acumulado por invitar a nuevos clientes ($50 MXN por cada 1er servicio completado).
- `status`: `1` activo, `0` inactivo.

### 5.3 `clientes_autos`
- `id` (int, PK): Identificador del auto.
- `cliente_id` (int): Relación con `clientes`.
- `apodo` (varchar): Nombre cariñoso del auto (ej. *Mr Rayo*, *La Consentida*).
- `marca`, `submarca`, `modelo`, `color`, `placas`: Ficha técnica.
- `tipo` (enum): **`CHICO`**, **`MEDIANO`**, **`GRANDE`**. *(Nota: El tipo desfasado `CAMIONETA` fue totalmente homologado a `GRANDE`)*.
- `vestiduras` (enum): **`TELA`** o **`PIEL`**. Determina el filtro inteligente de combos y el tratamiento que aplicará el Happer.
- `foto`: Ruta relativa de la foto del vehículo.

### 5.4 `clientes_membresias`
- `id` (int, PK): Identificador de la membresía.
- `cliente_id` (int): Relación con `clientes`.
- `plan` (enum): `CHICO`, `MEDIANO`, `GRANDE`.
- `stripe_sub_id`: ID de la suscripción recurrente en Stripe (`sub_...`).
- `status`: `ACTIVE`, `PAST_DUE` (cobro fallido), `CANCELED`.
- `lavados_incluidos`: 36 lavados anuales.
- `lavados_disponibles`: Saldo decreciente conforme se canjean servicios.
- `dia_hap`: Día preferido de la semana (`LUNES`, `MARTES`, `MIERCOLES`, `JUEVES`, `VIERNES`, `SABADO`, `DOMINGO`) o `NULL` si eligió modo flexible.
- `hora_hap`: Horario pactado de atención recurrente (entre `08:00 AM` y `04:00 PM`).
- `auto_id`: Vehículo predeterminado para el Día HAP.
- `direccion_id`: Domicilio predeterminado para el Día HAP.
- `fecha_inicio`: Fecha de contratación (para cálculo de días transcurridos y penalizaciones).

### 5.5 `clientes_tarjetas`
Bóveda segura tokenizada con Stripe (PCI-DSS compliant).
- `id` (int, PK)
- `cliente_id` (int): Relación con `clientes`.
- `stripe_customer_id`: `cus_...` en Stripe.
- `stripe_payment_method_id`: `pm_...` en Stripe.
- `brand`: Marca de la tarjeta (`visa`, `mastercard`, `amex`).
- `last4`: Últimos 4 dígitos para visualización del cliente.
- `exp_month`, `exp_year`: Vencimiento.
- `es_predeterminada` (tinyint): `1` para la tarjeta de cobro automático.

### 5.6 `usuarios` (Happers & Admins)
- `id`, `nombre`, `usuario`, `pass`, `rol` (`happer`, `admin`).
- `telefono`, `foto`: Perfil y contacto.
- `lat`, `lon`, `ultima_conexion`: Última señal registrada para el radar.

---

## 6. Catálogo de Vehículos, Tapicerías y Servicios

### 6.1 Categorías Oficiales de Vehículos
Toda la plataforma opera estrictamente con **3 categorías**:
1. 🚗 **`CHICO`**: Sedanes compactos, coupés y hatchbacks (ej. Nissan March, Suzuki Swift, SEAT Ibiza, Chevrolet Spark/Aveo, Peugeot 208, Kia Rio).
2. 🚙 **`MEDIANO`**: Sedanes medianos, wagons y crossovers compactos (ej. VW Jetta, Toyota Corolla, Nissan Sentra, Honda Civic, Honda HR-V, Nissan Kicks, Hyundai Creta, Mazda CX-30).
3. 🚐 **`GRANDE`**: SUVs medianas y grandes, camionetas familiares, pickups y vans (ej. Honda CR-V, Toyota RAV4, Hyundai Tucson, Kia Sportage, Ford Explorer, Jeep Grand Cherokee, Toyota Hilux/Tacoma, Ford F-150, Toyota Sienna).

### 6.2 Tipos de Tapicería (`vestiduras`)
- 💺 **`TELA`**: Requiere aspirado industrial, desmanchado de fibras textiles y secado rápido sin dejar humedad residual.
- 🛋️ **`PIEL`**: Requiere limpiador neutro para cuero, hidratación con crema humectante especial y acondicionador UV para evitar cuarteaduras.

### 6.3 Catálogo Homologado de Servicios
- **Básicos**:
  - `LAVADO HAP`: Exterior completo en seco con polímeros y cera biodegradable + aspirado profundo de alfombras, asientos y cajuela + limpieza de cristales interior/exterior + abrillantador de llantas base agua.
- **Avanzados**:
  - `ENCERADO HAP`: Lavado HAP completo + aplicación manual de cera de carnauba de grado profesional con abrillantado espejo y protección contra lluvia ácida y rayos UV.
  - `PROTECTOR HAP`: Lavado HAP completo + recubrimiento sintético de polímeros selladores para pintura y cristales.
- **Los 4 Combos Comerciales Únicos**:
  1. 🌟 **Combo Brillo & Plásticos**: *Lavado HAP + Encerado Carnauba + Hidratación y Restauración de Plásticos Exteriores*.
  2. 💺 **Combo Brillo & Asientos**: *Lavado HAP + Encerado Carnauba + Limpieza y Detallado Profundo de Asientos (Tela o Piel)*.
  3. 🧼 **Combo Interiores Profundo**: *Lavado HAP + Detallado Profundo de Asientos + Hidratación de Tablero, Paneles y Plásticos Interiores*.
  4. 👑 **HAP Integral (Todo Incluido)**: *Lavado HAP + Encerado Carnauba + Detallado de Asientos + Plásticos Interiores y Exteriores Completos*.

---

## 7. User App: Modalidades de Servicio, Portal de Bienvenida y Reglas de Despacho

### 7.1 Matriz Comparativa de Modalidades

| Modalidad | Badge / Color | Tiempo de Llegada / Ventana | Costo de Lavado | Regla de Anticipación |
| :--- | :---: | :---: | :---: | :---: |
| **HAP Express (Rayo Demanda)** | ⚡ `RAYO DEMANDA`<br>Amarillo/Ámbar | **40 a 120 minutos** | Precio regular con tarjeta | Inmediato (bajo demanda en vivo) |
| **Cita Programada** | 📅 `CITA PROGRAMADA`<br>Azul Cielo | Fecha/Hora pactada (`08:00 AM – 04:00 PM`) | Precio regular con tarjeta | **Mínimo 3 horas** de anticipación |
| **DÍA HAP (Rutina Fija)** | 💎 `DÍA HAP`<br>Púrpura Neón | Día y hora fija semanal | **$0.00 MXN** (Membresía) | Recurrente semanal (+7 días) |
| **Socio VIP (Flexible)** | 💎 `SOCIO VIP`<br>Cian / Diamante | Express (40-120 min) o Programado | **$0.00 MXN** (Membresía) | Express o $\ge 3$h si programa |

### 7.2 Reglas de la Cita Programada (`programar_servicio.php`)
1. **Horario Hábil**: Exclusivamente de **08:00 AM a 04:00 PM**.
2. **Anticipación Mínima**: Se exigen al menos **3 horas de anticipación** entre la hora actual del servidor y la hora de la cita.
3. **Preselección por Defecto**: Al seleccionar cualquier categoría de vehículo, el sistema DEBE preseleccionar de forma automática el servicio **`LAVADO HAP`** como primera opción.

### 7.3 Motor Recurrente del DÍA HAP (`sincronizador_dias_hap.php` & `QR/code.php`)
1. **Generación Idempotente**: Cada socio con membresía activa y DÍA HAP configurado debe tener siempre **exactamente 1 cita futura** registrada en `venta_desc` con estatus `PROGRAMADO` y `es_dia_hap = 1`.
2. **Ciclo Perpetuo al Escanear QR**: Cuando el Happer escanea el QR al terminar el lavado en `HAPPERS/QR/code.php`, el backend finaliza el servicio actual y genera de inmediato la cita de la semana siguiente (**Fecha actual + 7 días**) en el mismo horario y dirección, descontando 1 lavado de `lavados_disponibles`.
3. **Endpoint CRON**: `HAP/cron/generar_dias_hap.php` se ejecuta periódicamente con token de seguridad para asegurar citas en caso de fallas de red del operador.

### 7.4 Portal de Bienvenida y Selección de Rol (`CLIENTE/index.php`)
- **Experiencia de Entrada Mobile-First Dark Glassmorphic**:
  - Interfaz de cristal oscuro con desenfoque (`backdrop-filter: blur(16px)`), gradientes de fondo y tipografía `Plus Jakarta Sans`.
  - Slider interactivo de propuesta de valor (Lavado ecológico sin agua, Cero traslados, Garantía HAP de clase mundial).
- **Bifurcación Limpia y Exclusiva de Roles (2 Botones Principales)**:
  1. **`[ 🚗 SOY USUARIO ]`**: Canaliza al flujo del cliente final (`login.php` / registro / app cliente).
  2. **`[ ⚡ SOY HAPPER ]`**: Canaliza directamente al portal oficial de conductores (`/HAP/SISTEMA/HAPPER_APP/` o su login).
- **Depuración de Elementos Obsoletos**:
  - Eliminados enlaces secundarios confusos a versiones anteriores.
  - Retirado el badge redundante *"Driver 2.0"*.
  - Garantiza que cualquier operador nuevo o cliente que descargue la app o abra la URL raíz elija su perfil en 1 toque sin fricciones.

### 7.5 Regla de Negocio Inquebrantable: Exclusividad Operativa por Vehículo, Prevención de Doble Solicitud e Idempotencia

> [!IMPORTANT]
> **Principio de Integridad Operativa y Transaccional**: Un vehículo automotor es un recurso físico exclusivo en el tiempo y el espacio. Bajo ninguna circunstancia el sistema debe permitir registrar más de una orden activa simultánea para el mismo vehículo, ni superponer citas en un mismo bloque horario, ni procesar peticiones duplicadas por rebotes de red o doble clic en la interfaz.

#### 1. Condición de Bloqueo por Servicio Activo en Curso
- **Regla**: Si un vehículo ya cuenta con una orden activa en estatus `PENDIENTE`, `ACEPTADO`, `EN_CAMINO`, `PROCESO` o `INICIADO`, el sistema **DEBE BLOQUEAR** categóricamente cualquier nueva solicitud (tanto bajo demanda como programada para el día en curso) asociada a dicho vehículo.
- **Respuesta Operativa**: Se interrumpe la transacción y se notifica al usuario:
  > *"⛔ Vehículo con Servicio en Curso: Tu vehículo [Alias / Modelo] ya tiene un servicio activo (Folio #[ID]). Por favor espera a que concluya antes de solicitar uno nuevo."*

#### 2. Condición de Bloqueo por Superposición de Citas Programadas (Buffer de 1 Hora)
- **Regla**: Ningún vehículo puede tener dos citas programadas para el mismo día y bloque horario. Si ya existe una orden en estatus `PROGRAMADO` para ese vehículo en la misma fecha cuya hora pactada se encuentre dentro de un margen de **±60 minutos** de la nueva solicitud, el sistema **DEBE RECHAZAR** la nueva reserva.
- **Respuesta Operativa**: Se interrumpe la transacción y se notifica al usuario:
  > *"📅 Horario Ocupado: Tu vehículo [Alias / Modelo] ya tiene una cita agendada para el [Fecha] a las [Hora] (Folio #[ID]). Por favor selecciona otro horario con al menos 1 hora de diferencia o elige otro de tus vehículos."*

#### 3. Ventana Anti-Doble Clic e Idempotencia (Throttle de 60 Segundos)
- **Regla**: Queda estrictamente prohibido generar dos folios de venta para el mismo cliente y vehículo con una diferencia menor a **60 segundos** entre marcas de tiempo de creación (`alta`).
- **Comportamiento en Backend**:
  - Antes de ejecutar cualquier `INSERT INTO venta_desc`, el backend verifica si en los últimos 60 segundos ya se registró una orden con idénticos parámetros (`cliente`, `vehiculo`).
  - Si se detecta una solicitud duplicada, el sistema aborta el segundo insert, **no descuenta lavados adicionales de la membresía**, **no genera cargos duplicados en Stripe** y retorna la información del primer folio ya creado.

### 7.6 Regla de Negocio Mandatoria: Control Estricto de Cobertura Geográfica por Código Postal (15 C.P. Autorizados)

> [!IMPORTANT]
> **Mandato de Operación y Despacho Logístico**: La plataforma HAP opera con **cobertura cerrada y exclusiva** en exactamente **15 Códigos Postales** autorizados en el estado de Querétaro y zonas asignadas. Queda estrictamente prohibido crear, autorizar cobros en Stripe o insertar órdenes en `venta_desc` (en cualquier modalidad: Express, Cita Programada o Canje de Membresía) si el Código Postal del domicilio o ubicación GPS no se encuentra en el catálogo oficial.

#### 1. Catálogo Homologado de los 15 Códigos Postales Autorizados

| Código Postal (C.P.) | Municipio / Región Principal | Zonas / Fraccionamientos Representativos |
| :---: | :--- | :--- |
| **`76269`** | El Marqués / Querétaro | Zibatá |
| **`76230`** | Querétaro | Juriquilla, Cumbres del Lago, Jurica Acueducto |
| **`76146`** | El Marqués / Querétaro | El Refugio, La Vista Residencial |
| **`76226`** | Querétaro | El Campanario, Hacienda El Campanario |
| **`76100`** | Querétaro | Álamos 1ª y 2ª Sección, Arboledas |
| **`76060`** | Querétaro | Centro Histórico Oriente, Carretas, Observatorio |
| **`76215`** | Querétaro / Santa Rosa Jáuregui | Querétaro Norte, Parque Industrial Querétaro (P.I.Q.) |
| **`76246`** | Querétaro / El Marqués | Milenio III, El Mirador |
| **`76900`** | Corregidora | El Pueblito Centro, Residencial Santa Fe |
| **`76902`** | Corregidora | Corregidora, Pirámides, Camino Real |
| **`76904`** | Corregidora | Tejeda, Paseos del Bosque, Candiles |
| **`76910`** | Corregidora | Balvanera, La Negreta, Los Pájaros |
| **`76090`** | Querétaro | Centro Sur, Colinas del Cimatario, Estadio Corregidora |
| **`76170`** | Querétaro | Querétaro Centro Histórico, San Francisquito, Niños Héroes |
| **`87380`** | Zona Especial HAP | Matamoros / Zona Asignada |

#### 2. Triple Barrera de Protección de Cobertura
1. **Frontend en Tiempo Real (`hapiar.php`, `programar_servicio.php`, `charge.js`)**:
   - Cada tarjeta de dirección guardada evalúa `hap_es_cp_permitido()`. Si el C.P. está fuera de zona, se exhibe el badge de alerta `⛔ Sin cobertura`.
   - Al seleccionar una dirección fuera de zona o ingresar un C.P. no cubierto mediante GPS o modal manual, el sistema intercepta el flujo antes de cualquier llamada a Stripe y despliega el **Modal de Salida Amigable y Retención**.
2. **Backend API (`crear_stripe_intent.php`)**:
   - Antes de llamar al SDK de Stripe para crear un `PaymentIntent`, el endpoint ejecuta `hap_es_cp_permitido($cp, $higo, $usuarioapp)`.
   - Si el CP no es válido, rechaza con HTTP 400 y mensaje explicativo, impidiendo cualquier retención bancaria.
3. **Persistencia Final (`stripe.php` & `programar_servicio.php`)**:
   - Validación transaccional obligatoria previa al `INSERT INTO venta_desc`.
   - Bloquea categoricamente canjes de membresía ($0.00) y pagos con tarjeta si el CP recibido estuviese adulterado o fuera de catálogo.

#### 3. Plan de Salida Amigable y Retención de Usuarios Fuera de Zona
Ante un Código Postal sin servicio activo, el sistema nunca debe mostrar un error áspero ni abandonar al usuario. Debe desplegar el modal interactivo con tres vías de retención:
1. **`🏢 Solicitar en mi Oficina o Trabajo`**: Permite al usuario seleccionar o escribir la dirección de su lugar de trabajo (oficinas, parques industriales o plazas comerciales que sí tienen cobertura).
2. **`🔔 ¡Avísenme cuando abran mi C.P.!`**: Registra de forma inmediata el usuario, C.P. y dirección en la tabla `kpicp` para análisis de expansión de rutas y le confirma que será notificado con beneficios de apertura.
3. **`🗺️ Ver las 15 Zonas con Cobertura Activa`**: Desglose transparente de todas las colonias y C.P. con servicio activo.

### 7.7 Regla de Negocio Mandatoria: Control de Capacidad por Horario (Máximo 2 Reservas) y Toque de Queda Matutino Post-16:00

> [!IMPORTANT]
> **Optimización Logística y Protección de Capacidad Instalada**: La asignación de citas programadas está estrictamente regulada para proteger los tiempos de traslado de la flotilla de Happers y asegurar el cumplimiento de la garantía de puntualidad. Todo horario ofertado en la plataforma debe respetar el límite máximo de reservas simultáneas y la restricción de preparación logística nocturna.

#### 1. Regla de Capacidad Máxima (2 Reservas por Bloque Horario)
- **Restricción**: En cualquier fecha determinada (`YYYY-MM-DD`), cada bloque horario individual (`08:00 AM`, `08:30 AM`, `09:00 AM`, ..., `04:00 PM`) admite como **máximo estricto 2 reservas simultáneas**.
- **Cómputo en Base de Datos**: Se contabilizan todas las órdenes en `venta_desc` asociadas a esa fecha y hora cuya orden se encuentre en estatus activo (`estatus NOT IN ('CANCELADO')`).
- **Comportamiento en Frontend**:
  - Si un bloque horario ya cuenta con 2 reservas registradas, el chip del horario se muestra visualmente **inhabilitado** (`.time-slot-chip.disabled` con opacidad reducida y texto tachado).
  - Si el usuario hace clic o toca dicho horario inhabilitado, el sistema **DEBE INTERCEPTAR** la acción y desplegar el modal SweetAlert2 interactivo:
    - **Título**: `Horario No Disponible`
    - **Cuerpo**: `Tenemos alta demanda en este momento y por ahora no puedes programar en este horario, pero te invitamos a programar tu servicio en la siguiente hora disponible.`
    - **Botón**: `Entendido`

#### 2. Regla de Toque de Queda Matutino Post-16:00 para el Día Siguiente
- **Restricción**: Si y solo si la hora actual del servidor supera las **16:00 horas** (4:00 PM), queda categóricamente **bloqueada la reservación de horarios matutinos (08:00 AM a 11:00 AM)** para el día siguiente (`fecha == mañana`).
- **Bloques Afectados**: `08:00 AM`, `08:30 AM`, `09:00 AM`, `09:30 AM`, `10:00 AM`, `10:30 AM` y `11:00 AM`.
- **Razón Operativa**: A las 16:00 hrs se realiza el corte logístico de abastecimiento, ruteo y preparación de mochilas de insumos para las primeras misiones de la mañana del día siguiente.
- **Comportamiento en UI**:
  - Al seleccionar la fecha de "Mañana" después de las 16:00 hrs, los chips de 08:00 a 11:00 AM aparecen inhabilitados.
  - Al hacer clic sobre cualquiera de ellos, se despliega el mismo modal `Horario No Disponible`.
  - El usuario puede seleccionar con total normalidad horarios a partir de las `11:30 AM` en adelante para el día siguiente, o cualquier horario disponible para fechas posteriores (día + 2, día + 3, etc.).

#### 3. Ámbito de Aplicación Universal
Esta regla rige de manera obligatoria y transversal sobre:
1. **Citas Regulares** pagadas con tarjeta bancaria en `programar_servicio.php`.
2. **Citas de Membresía HAP ($0.00 MXN)** o upgrades con copago de diferencia en `programar_servicio.php`.
3. **Reagendamiento y Reprogramación de Servicios** en `reagendar_servicio.php` y `reprogramar_servicio_ajax.php`.

### 7.8 Regla de Negocio Mandatoria: Protección de Horario Nocturno Express y Embudo de Conversión a Citas Programadas (Funnel Anti-Churn)

> [!IMPORTANT]
> **Prohibición de Bloqueos Ciegos / Retención Obligatoria del Cliente**: Si un usuario intenta solicitar un servicio bajo demanda («PIDE TU HAPPER», «LAVAR ESTE AUTO» o acceso directo a `hapiar.php`) durante el receso operativo nocturno (entre las **22:00 hrs y las 06:00 hrs**), el sistema **NUNCA DEBE MOSTRAR UN ERROR ESTÉRIL O DE CALLEJÓN SIN SALIDA**. En su lugar, el sistema debe desplegar un modal persuasivo de alta conversión que explique el horario de descanso de la flotilla e invite inmediatamente al usuario a **programar su servicio** (`programar_servicio.php?auto=ID`), preservando el vehículo seleccionado.

#### 1. Comportamiento y Copywriting del Modal
- **Título**: `¡Nuestros Happers están descansando! 🌙`
- **Mensaje**: Explicación transparente de que el servicio express opera de 6:00 a 22:00 hrs para seguridad y descanso de los Happers, destacando la oportunidad de asegurar el lugar para la mañana siguiente o fecha posterior y despertar con el auto impecable.
- **Micro-beneficios**: ⏰ Horario asegurado, 📍 En tu cochera o trabajo, 💧 Ecológico sin agua.
- **Acción Primaria (CTA)**: `📅 Programar Mi Lavado` con gradiente HAP oficial y redirección a `programar_servicio.php?auto=ID`.
- **Acción Secundaria**: `Quizás más tarde` (cierre sin fricción o redirección a `perfil.php` si se estaba en `hapiar.php`).

#### 2. Puntos de Contacto Homologados
1. **Dashboard de Inicio (`perfil.php`)**: Botón principal `#pedido-btn` interceptado mediante `hapVerificarHorarioServicio()`.
2. **Mi Cochera (`mis_autos.php`)**: Botón `LAVAR ESTE AUTO` en cada tarjeta de vehículo interceptado mediante `hapVerificarHorarioServicio()`.
3. **Solicitud Inmediata (`hapiar.php`)**: Intercepción automática al cargar si se accede por enlace directo fuera de horario, ofreciendo agendar o regresar al inicio.

---

## 8. User App: Ecosistema de Membresía HAP

### 8.1 Planes y Precios Oficiales (Contrato Anual, 36 Lavados)
- 🚗 **Membresía Chica**: **$495.00 MXN / mes** (Ahorro del 15% anual). Cobertura exclusiva para autos `CHICO`.
- 🚙 **Membresía Mediana**: **$563.00 MXN / mes** (Ahorro del 15% anual). Cobertura para autos `CHICO` y `MEDIANO`.
- 🚐 **Membresía Grande**: **$597.00 MXN / mes** (Ahorro del 15% anual). Cobertura universal para autos `CHICO`, `MEDIANO` y `GRANDE (SUVs / Camionetas)`.

### 8.2 Regla Estricta de Jerarquía de Cobertura
```mermaid
graph TD
    subgraph Coberturas
        PG[Plan GRANDE $597] -->|Cubre| AG[Autos GRANDES]
        PG -->|Cubre| AM[Autos MEDIANOS]
        PG -->|Cubre| AC[Autos CHICOS]
        
        PM[Plan MEDIANO $563] -->|Cubre| AM
        PM -->|Cubre| AC
        PM -.->|BLOQUEA| AG
        
        PC[Plan CHICO $495] -->|Cubre| AC
        PC -.->|BLOQUEA| AM
        PC -.->|BLOQUEA| AG
    end
```
- Si un socio con membresía Chica o Mediana intenta canjear a $0.00 MXN un auto de mayor tamaño no cubierto, el sistema **bloquea el canje gratuito** y despliega la pasarela para pagar el servicio individual con tarjeta bancaria a tarifa normal.

### 8.3 Regla Inquebrantable: Bonificación del Lavado Base y Copago por Diferencia en Servicios Superiores (Upgrade de Membresía)

#### 8.3.1 Fundamento Comercial y Propósito
El beneficio de la Membresía HAP incluye de base el servicio **`LAVADO HAP`** a costo `$0.00 MXN`. Sin embargo, para fomentar la fidelidad, el consentimiento del vehículo y la venta cruzada (*upselling*), el socio **NUNCA** debe ser obligado a pagar el 100% de un servicio superior si cuenta con lavados disponibles en su membresía.
- Si el socio desea solicitar o programar un servicio de mayor valor (ej. `ENCERADO HAP`, `PROTECTOR HAP`, `COMBO BRILLO & PLÁSTICOS`, `COMBO BRILLO & ASIENTOS`, `COMBO INTERIORES PROFUNDO`, `HAP INTEGRAL`):
  1. Se toma el **valor comercial del `LAVADO HAP`** correspondiente a la categoría del auto como crédito/bonificación a favor del socio.
  2. El socio únicamente paga la **DIFERENCIA** económica resultante (*Upgrade Fee / Tarifa de Mejora*) al momento de solicitar o programar.
  3. Al completar la orden, **SÍ se descuenta 1 lavado** de la bolsa de lavados disponibles de la membresía (`lavados_disponibles = lavados_disponibles - 1`).

#### 8.3.2 Fórmula Matemática y Mecánica de Cálculo
$$\text{Total a Pagar (Diferencia)} = \max(0, P_{\text{servicio}} - V_{\text{lavado\_base}})$$

Donde:
- $P_{\text{servicio}}$: Precio de lista oficial del servicio superior elegido.
- $V_{\text{lavado\_base}}$: Precio de lista oficial del servicio base **`LAVADO HAP`** para la categoría del vehículo:
  - 🚗 Auto **`CHICO`**: $V_{\text{lavado\_base}} = \$194.00 \text{ MXN}$
  - 🚙 Auto **`MEDIANO`**: $V_{\text{lavado\_base}} = \$221.00 \text{ MXN}$
  - 🚐 Auto **`GRANDE`**: $V_{\text{lavado\_base}} = \$234.00 \text{ MXN}$

#### 8.3.3 Matriz de Ejemplos Prácticos

| Categoría de Auto | Servicio Elegido | Precio de Lista ($P$) | Bonificación Lavado Base ($V_{base}$) | Diferencia a Pagar por el Socio | Cargo en Bolsa de Membresía |
| :--- | :--- | :---: | :---: | :---: | :---: |
| 🚗 **CHICO** | `LAVADO HAP` | $194.00 MXN | -$194.00 MXN | **$0.00 MXN (100% Incluido)** | -1 Lavado |
| 🚗 **CHICO** | `ENCERADO HAP` | $359.00 MXN | -$194.00 MXN | **$165.00 MXN** | -1 Lavado |
| 🚗 **CHICO** | `COMBO 1 (Brillo & Plásticos)` | $465.00 MXN | -$194.00 MXN | **$271.00 MXN** | -1 Lavado |
| 🚙 **MEDIANO** | `LAVADO HAP` | $221.00 MXN | -$221.00 MXN | **$0.00 MXN (100% Incluido)** | -1 Lavado |
| 🚙 **MEDIANO** | `ENCERADO HAP` | $399.00 MXN | -$221.00 MXN | **$178.00 MXN** | -1 Lavado |
| 🚙 **MEDIANO** | `COMBO 2 (Brillo & Asientos)` | $520.00 MXN | -$221.00 MXN | **$299.00 MXN** | -1 Lavado |
| 🚐 **GRANDE** | `LAVADO HAP` | $234.00 MXN | -$234.00 MXN | **$0.00 MXN (100% Incluido)** | -1 Lavado |
| 🚐 **GRANDE** | `HAP INTEGRAL (Todo Incluido)` | $690.00 MXN | -$234.00 MXN | **$456.00 MXN** | -1 Lavado |

#### 8.3.4 Casos Borde y Reglas de Blindaje Operativo
1. **Disponibilidad de Saldo en Bolsa**: La bonificación del lavado base exige que el socio tenga al menos **1 lavado disponible** (`lavados_disponibles >= 1`). Si el saldo es 0, no aplica bonificación y el servicio se cobra al 100% de su precio de lista.
2. **Momento y Pasarela de Cobro de la Diferencia**:
   - **En HAP Express (`hapiar.php`)**: La diferencia se cobra de inmediato con la tarjeta seleccionada mediante `Stripe PaymentIntent`.
   - **En Cita Programada (`programar_servicio.php`)**: La diferencia se procesa con la tarjeta registrada del cliente al confirmar la reserva.
   - **En Rutina Fija DÍA HAP**: La cita semanal automática se genera siempre con el servicio base `LAVADO HAP` a $0.00 MXN. Si el socio desea un upgrade para una cita específica, puede solicitar la mejora desde su app pagando la diferencia de esa fecha particular sin alterar la rutina base de las semanas siguientes.
3. **Restricción por Jerarquía de Vehículos**: La bonificación del lavado base SOLO aplica si la categoría del vehículo está **cubierta por el plan contratado**. Si un socio con Membresía Chica solicita un servicio para un auto Grande, no aplica la bonificación de lavado a $0 y debe pagar la tarifa completa del vehículo Grande (o migrar su membresía).
4. **Política de Reembolso en Cancelación con Upgrade**:
   - **Sin Happer asignado (`PENDIENTE`)**: Se reembolsa el **100% de la diferencia pagada** a la tarjeta bancaria y se **restaura de inmediato el +1 lavado** a la membresía (`lavados_disponibles = lavados_disponibles + 1`).
   - **Con Happer asignado y tiempo transcurrido $\le 30$ minutos**: Se retiene el 20% de compensación sobre la diferencia económica pagada (se reembolsa el 80% en dinero) y el lavado de membresía se restaura íntegro.
   - **Con Happer asignado y tiempo transcurrido $> 30$ minutos**: Se retiene el 100% de la diferencia económica y el lavado de membresía se considera consumido por el desplazamiento del Happer.
5. **Transparencia en UI / Desglose Visual**:
   En el resumen de compra (Sticky Bottom Dock), en el modal de confirmación y en la Torre de Control, la orden debe exhibir el desglose transparente:
   ```
   Servicio: COMBO BRILLO & PLÁSTICOS ......... $465.00 MXN
   Membresía HAP (Lavado Base Bonificado) ..... -$194.00 MXN (-1 Lavado)
   -----------------------------------------------------------
   TOTAL A PAGAR (Diferencia de Upgrade) ......  $271.00 MXN
   ```
   En Torre de Control y App del Happer se añade el badge: `💎 UPGRADE MEMBRESÍA` para alertar al operador y al Happer sobre los insumos especiales requeridos (carnauba, desmanchador de plásticos, limpiador de vestiduras).

### 8.4 Percepción de Saldo de Lavados
- Si restan **$>30\%$ de la bolsa anual ($>10$ lavados)**: La interfaz oculta el contador numérico para generar sensación de servicio ilimitado y tranquilidad ("*Membresía Activa*").
- Si restan **$\le 30\%$ ($\le 10$ lavados)**: Se activa automáticamente el contador exacto y una barra de progreso transparente alertando el consumo.

### 8.5 Penalizaciones por Cancelación de Membresía
Las membresías se otorgan a precio preferente con base en un compromiso anual (12 mensualidades).
- **Cancelación en primeros 6 meses ($\le 182$ días)**: Aplica penalización del **70% del valor anualizado restante**.
- **Cancelación después de 6 meses ($> 182$ días)**: Aplica penalización del **10% del valor anualizado restante**.
- **Modal de Retención Obligatorio**: Siempre que el socio inicie la cancelación, la interfaz debe desplegar el desglose transparente del cobro por penalización y destacar como botón principal de acción **`✨ MANTENER MI MEMBRESÍA ($0 CARGO)`**.

### 8.6 Estado `PAST_DUE` por Falla de Cobro en Stripe
- Si la tarjeta bancaria es declinada en la fecha de renovación, la membresía pasa de inmediato a `PAST_DUE`.
- Se suspenden automáticamente los canjes a $0.00 MXN y se pausan las citas de Días HAP hasta que el socio actualice su tarjeta en `metodos_pago.php`.

---

## 9. User App: Políticas de Cancelación y Reembolso de Servicios

### 9.1 Opción #1 Prioritaria: Reagendar ($0.00 MXN)
Ante cualquier solicitud de cancelación por parte del cliente o en Torre de Control, el sistema **debe ofrecer primero** la opción **`📅 REAGENDAR SERVICIO ($0)`**, permitiendo elegir otra fecha y horario sin aplicar ninguna penalización.

### 9.2 Escala Oficial de Cobros por Cancelación Definitiva

```mermaid
flowchart LR
    Solicitud[Solicitud de Cancelación]
    Asignado{¿Tiene Happer Asignado?}
    
    Solicitud --> Asignado
    Asignado -->|NO - Estatus PENDIENTE| SinCobro["🟢 CANCELACIÓN GRATIS ($0 MXN)<br>100% Reembolso o Saldo Restaurado"]
    Asignado -->|SÍ| Tiempo{¿Tiempo transcurrido desde asignación?}
    
    Tiempo -->|<= 30 Minutos| Cobro20["🟡 RETENCIÓN DEL 20% (Fee de traslado)<br>80% Reembolsado al Cliente"]
    Tiempo -->|> 30 Minutos| Cobro100["🔴 RETENCIÓN DEL 100% (Sin reembolso)<br>Compensación total al Happer"]
```

1. **Sin Happer Asignado (`PENDIENTE`)**: **100% Gratuita**. Cargo de $0.00 MXN, reembolso íntegro o restauración automática del lavado de membresía.
2. **Con Happer Asignado y tiempo $\le 30$ minutos**: Se retiene un **20%** por gastos de desplazamiento del Happer y se devuelve el **80% restante** al cliente.
3. **Con Happer Asignado y tiempo $> 30$ minutos**: Se retiene el **100%** del importe ($0.00 reembolso) debido al tiempo reservado y desplazamiento en motocicleta.

---

## 10. Happer App: Flujo Operativo, App 2.0 y Protocolo de 5 Pasos

### 10.1 Toma de Citas Programadas (Regla de 24 Horas)
- Los servicios programados aparecen en la sección *"Pool de Citas de la Semana"* en `happer.php` e `index.php`.
- **Faltan $\le 24$ horas**: El botón verde **`✅ TOMAR SERVICIO`** se activa y el Happer puede apartarlo en su agenda personal.
- **Faltan $> 24$ horas**: El botón permanece estrictamente **bloqueado** con la leyenda `🔒 DISPONIBLE 24H ANTES` y la hora exacta de apertura.

### 10.2 Protocolo de Doble Escaneo QR y PIN de Seguridad de 4 Dígitos (Anti-Fraude)
El cliente tiene en su app la pantalla de seguimiento (`tracking.php`) con un código QR seguro único y su **PIN de Seguridad de 4 dígitos** (`pin`):
1. **QR de Inicio (Llegada)**: El Happer lo escanea al llegar a la cochera del cliente. El estatus cambia a `INICIADO` / `PROCESO` y se registra `inicio`.
2. **PIN de Seguridad Alternativo (4 Dígitos)**: Si el Happer no puede escanear el código QR (por condiciones de iluminación o reflejos), el cliente le dicta su PIN exclusivo de 4 dígitos mostrado en casillas tipo token en `tracking.php`.
   - **Regla Estricta Anti-Fraude**: El cliente recibe la instrucción clara de **NO compartir el PIN** por llamada o WhatsApp, sino únicamente cuando el Happer haya arribado físicamente a la ubicación y se encuentre frente al vehículo.
   - **Candado de Llegada en Servidor**: El backend (`api.php?action=iniciar_lavado`) rechaza cualquier intento de validar el PIN o QR si el operador no registró previamente su llegada en el Paso 1 (`espera IS NOT NULL`).
3. **QR de Conclusión (Entrega)**: El Happer lo escanea tras verificar que el vehículo quedó impecable. El estatus cambia a `FINALIZADO`, se registra `fin`, se ejecuta el cobro off-session en Stripe (si era tarjeta) y se auto-genera la cita de la siguiente semana si es Día HAP.

### 10.3 Control de Calidad de Tiempo
- El tiempo estándar de lavado completo es de **~30 minutos**. Si un servicio se finaliza en menos de 20 minutos, el sistema registra una bandera de auditoría en bitácora para supervisión.

### 10.4 Alertas de Inventario Bajo
- Si el stock de cera o toallas del Happer está bajo, se muestra un *toast* flotante no intrusivo con enfriamiento (*cooldown*) de **12 horas** para no estorbar el flujo de trabajo en la moto.

### 10.5 Candado de Exclusividad y No Concurrencia de Servicios (Regla de Máximo 1 Servicio Activo)
- **Mandato Operativo Inquebrantable**: Ningún Happer puede aceptar, tomar o recibir en asignación más de **1 servicio activo simultáneo** (estatus `ACEPTADO`, `EN_CAMINO`, `PROCESO` o `INICIADO`).
- **Bloqueo a Nivel de App Móvil del Happer (`aceptar_servicio_happer.php`, `aceptada.php`, `happer.php`)**:
  - Antes de registrar la aceptación o guardarla en base de datos, el backend verifica si el operador ya posee un servicio activo.
  - Si el Happer intenta tomar un nuevo servicio teniendo uno en curso, se aborta la transacción y se redirige con `err=happer_ocupado&serv={id_activo}`.
  - En `happer.php`, se despliega de inmediato un modal SweetAlert2: *"⛔ Servicio en Curso: Tienes el servicio #{id} en proceso. Debes finalizarlo antes de poder tomar uno nuevo."*
- **Bloqueo a Nivel de Torre de Control (`api.php`, `torre.js`)**:
  - En el modal de asignación (*Smart Dispatch*), los Happers con servicios activos se renderizan con opacidad reducida, borde distintivo y un badge `⛔ Ocupado (#{id})`. El botón de acción queda deshabilitado en modo `Bloqueado 🔒`.
  - El endpoint `api.php?action=asignar_happer` ejecuta una validación de seguridad transaccional previa: si el Happer seleccionado ya tiene un servicio activo, la asignación es rechazada categóricamente con HTTP 200 y `success: false` acompañado del mensaje explicativo para el operador.

### 10.6 HAP Driver App 2.0 (`/HAP/SISTEMA/HAPPER_APP/`) y Protocolo de Misión Unidireccional

#### 10.6.1 Sesión Única por Dispositivo (`session_token`)
- **Mecanismo de Unicidad Absoluta**:
  - Cada inicio de sesión exitoso en `login.php` genera un token criptográfico de 32 bytes (`bin2hex(random_bytes(32))`), almacenado en `usuarios.session_token` y sincronizado en `$_SESSION['happer_session_token']` y cookie HTTPOnly.
  - En cada petición HTTP a `config.php`, `api.php` y `mision.php`, se verifica que el token del cliente coincida exactamente con el de la base de datos.
  - Si el Happer ingresa en un segundo dispositivo, la base de datos sobrescribe el token.
  - En la siguiente llamada del primer dispositivo, el backend detecta la discrepancia, destruye la sesión y devuelve `HTTP 401 Unauthorized`:
    ```json
    { "success": false, "error": "SESSION_DUPLICATED", "session_duplicated": true }
    ```
  - La interfaz expulsa al operador de inmediato y lo redirige a `login.php?error=session_duplicated`.

#### 10.6.1.1 Persistencia Continua y Auto-Restauración Transparente (Regla de Oro #18)
- **Zero-Logout Policy en Campo**:
  - Para evitar que los Happers sean desconectados en la calle por inactividad o porque Android mata el navegador para liberar RAM, la configuración de sesión PHP se extiende a 365 días (`session.gc_maxlifetime = 31536000`, `session.cookie_lifetime = 31536000`, `SameSite=Lax`, `HttpOnly`).
  - **Mecanismo de Auto-Restauración Silenciosa (`require_happer_auth`)**:
    - Si la sesión en memoria PHP se encuentra vacía pero existe la cookie persistente `happer_session_token`, el backend consulta a la base de datos `usuarios` buscando el token activo.
    - Si coincide y el Happer está activo, la sesión PHP completa (`happer_id`, `happer_usuario`, `happer_nombre`, `happer_cargo`, `happer_session_token`) se reconstruye de manera transparente en <1 ms.
    - El Happer nunca ve la pantalla de login ni sufre retrasos en la toma de misiones.
  - **Revocación Limpia**: Al pulsar voluntariamente `Cerrar Sesión` (`logout.php`), el `session_token` en BD se establece a `NULL`, invalidando tanto la sesión como la cookie persistente.

#### 10.6.2 Protocolo de Misión de 5 Pasos (Flujo Estrictamente Unidireccional)
La ejecución del servicio dentro de `mision.php` opera como una máquina de estados estrictamente progresiva:

```
[1. Arribo] ──> [2. Inspección Previa] ──> [3. Identidad QR/PIN] ──> [4. En Proceso] ──> [5. Entrega Final] ──> [6. Celebración]
     │                    │                        │                      │                     │
  GPS + Hora           4 Ángulos en BD         Valida PIN             30 min + 4/4          4 Fotos Entrega
  (Sellado)            (Sellado)               (Sellado)              (Sellado)             (Captura Stripe)
```

1. **Paso 1: Arribo al Punto (`panel-paso-1`)**:
   - Registro de geolocalización satelital (`lat`, `lon`) y hora de llegada (`espera`).
   - Notifica en tiempo real a Torre de Control transicionando la orden a `EN_SITIO`.
   - Una vez confirmada la llegada, el Paso 1 queda permanentemente completado y sellado.
2. **Paso 2: Inspección Previa del Vehículo (`panel-paso-2`)**:
   - Captura fotográfica obligatoria de los 4 ángulos de la carrocería:
     - `FRENTE` (Frente y Placas)
     - `COSTADO_IZQ` (Costado Izquierdo)
     - `COSTADO_DER` (Costado Derecho)
     - `TRASERA` (Parte Trasera)
     - *(Opcional)*: Registro de daños previos (`DANOS`) con galería independiente.
   - **Verificación Estricta en Servidor (`verificar_fotos_inspeccion`)**:
     - Al presionar **`CONTINUAR A IDENTIDAD (QR / PIN)`**, el cliente NO avanza confiando en variables locales de memoria.
     - El botón pasa a estado de carga: `⏳ VERIFICANDO EN SERVIDOR...`.
     - Invoca `api.php?action=verificar_fotos_inspeccion&servicio_id=...`, el cual valida en la tabla `fotos` de MySQL que los 4 cuadrantes estén físicamente guardados.
     - Si falta algún ángulo por corte de red o falla de subida, el sistema bloquea el avance, muestra un Toast detallado (ej. *"⚠️ Falta procesar o subir la fotografía de: Costado Derecho"*), marca ese slot como pendiente y exige tomarlo nuevamente.
     - Si las 4 fotos están confirmadas, sincroniza los datos y avanza al Paso 3.
   - **Inmutabilidad de Inspección**: Una vez superado el Paso 2, las fotos iniciales quedan selladas contra eliminación (`solicitarEliminarFoto` y `eliminar_evidencia` bloqueadas).
   - **Protocolo de Vehículo No Encontrado**:
     - Si el Happer no localiza el auto, se despliega el acordeón de búsqueda con timer de 10 minutos.
     - **Regla Mandatoria**: Para activar el botón de reporte/cancelación, es OBLIGATORIO haber realizado al menos un intento de llamada telefónica al cliente mediante el botón oficial.
3. **Paso 3: Validación de Identidad del Cliente (`panel-paso-3`)**:
   - Escáner de cámara trasera con `BarcodeDetector` y fallback `jsQR`, o teclado táctil para PIN de 4 dígitos.
   - El PIN sugerido corresponde a los últimos 4 dígitos del teléfono del cliente o el token de la orden.
   - El backend (`validar_qr_pin`) verifica que el código sea correcto y que las 4 fotos de inspección previa existan en BD antes de cambiar el estatus a `PROCESO` y registrar `inicio = NOW()`.
   - Transiciona automáticamente al Paso 4.
4. **Paso 4: En Proceso (Cronómetro & Checklist de Calidad) (`panel-paso-4`)**:
   - Cronómetro segundo a segundo.
   - **Estándar de Calidad HAP**: El servicio requiere un tiempo mínimo de **30 minutos** de lavado activo.
   - Checklist de calidad de 4 puntos obligatorios (Pintura, Cristales, Llantas/Rines, Molduras).
   - Solo al completar los 4 puntos del checklist (4/4) se habilita el botón `🚗 ENTREGAR VEHÍCULO` para avanzar al Paso 5.
5. **Paso 5: Inspección Final & Entrega (`panel-paso-5`)**:
   - Captura obligatoria de las 4 fotos del auto terminado:
     - `FINAL_FRENTE` (Frente Terminado)
     - `FINAL_COSTADO_IZQ` (Costado Izq Terminado)
     - `FINAL_COSTADO_DER` (Costado Der Terminado)
     - `FINAL_TRASERA` (Trasera Concluida)
   - El botón `FINALIZAR SERVICIO` solo se activa cuando se cumplen conjuntamente:
     1. Los 30 minutos de lavado activo (`obtenerMinutosLavado >= 30`).
     2. Las 4 fotos finales cargadas y listas.
   - **Validación Final en Backend (`finalizar_lavado`)**:
     - El endpoint valida en base de datos que existan las 4 fotos finales antes de proceder.
     - Ejecuta la captura definitiva en Stripe (`$intent->capture()`).
     - Transiciona la orden a `FINALIZADO` (`fin = NOW()`).
     - Auto-genera el reagendamiento del DÍA HAP recurrente (+7 días) si aplica.
     - Avanza al Paso 6 (Pantalla de Éxito, resumen de misión y confetti).

#### 10.6.3 Bloqueo Definitivo de Retroceso (Protocolo Progresivo)
- **Prohibición de Regreso**: Un Happer nunca debe regresar a pasos completados (1, 2, 3, 4).
- En `intentarIrAlPaso(targetPaso)`: Si `targetPaso < MISION.pasoActivo`, se bloquea la navegación con vibración háptica y Toast:
  > *"🔒 Este paso ya fue completado. El protocolo HAP avanza en una sola dirección."*
- En el Stepper HUD: Los pasos completados muestran `.completed` con `cursor: default`, opacity reducida e icono `✓`.
- No es posible saltar pasos intermedios hacia adelante sin haber cumplido los candados del paso en curso.

#### 10.6.4 Deprecación Definitiva de la App Clásica (`/HAPPERS/`)
- Inyección del modal de obsolescencia `HAPPERS/modal_obsoleto.php` en los puntos de entrada:
  - `happer.php` (panel operativo legacy).
  - `index.php` (redirección inicial).
  - `login_happer.php` (pantalla de acceso anterior).
  - `aceptar_servicio_happer.php` (redirección forzada de folios hacia `HAPPER_APP/tomar_servicio.php`).
- El modal bloquea el fondo (`backdrop-filter: blur(14px)`, `z-index: 9999999`) y ofrece un único botón de acción principal:
  > **`🚀 ABRIR NUEVA APP DE HAPPERS`** (`../HAPPER_APP/`)

### 10.7 Arquitectura de Campo: Dispositivos de Gama Baja, Economía Extrema de Datos y Resiliencia a Cortes de Red (Offline-First / Spotty Network)

Los conductores de HAP operan en condiciones de campo altamente adversas:
- **Dispositivos Móviles Modestos**: Teléfonos inteligentes Android de gama de entrada con especificaciones limitadas (2 a 3 GB de RAM, procesadores de 4 u 8 núcleos de bajo consumo, almacenamiento básico y pantallas estándar de 60Hz).
- **Planes de Datos Limitados**: Paquetes móviles prepago reducidos donde el consumo irresponsable de datos agota el saldo del operador e inhabilita su jornada de trabajo.
- **Conectividad Intermitente y Cortes de Red Frecuentes**: Pérdidas constantes de señal 4G/LTE durante el traslado en motocicleta (bajo puentes, pasos a desnivel, carreteras) y dentro de puntos de servicio con blindaje electromagnético o mala recepción (sótanos de condominios, casetas de fraccionamientos o zonas conurbadas de Querétaro).

Por lo tanto, toda la ingeniería de la **HAP Driver App 2.0** (`/HAP/SISTEMA/HAPPER_APP/`) se rige estrictamente bajo tres pilares mandatorios:

#### 10.7.1 Pilar 1: Rendimiento Ultraligero en Hardware Restringido (CPU & RAM)
1. **PWA Ultra Compacta (<200 KB)**: La aplicación móvil no debe utilizar frameworks pesados (React, Vue, Angular) ni dependencias innecesarias de Node. Se implementa en **Vanilla JavaScript nativo (ES6+)** y CSS puro, reduciendo el peso de assets de más de 60 MB en la app clásica a menos de 200 KB.
2. **Manipulación del DOM Eficiente y Aceleración por Hardware**:
   - Evitar re-renders masivos del árbol DOM o mutaciones costosas.
   - Las animaciones y transiciones de estado deben realizarse exclusivamente con propiedades CSS aceleradas por GPU (`transform` y `opacity`), evitando `top`, `left`, `width` o `height` que provocan recálculos forzados de layout (*reflows*).
3. **Gestión de Memoria y Batería**:
   - Destruir y liberar URLs de objetos Blob generadas para previews (`URL.revokeObjectURL(url)`) inmediatamente después de su renderizado.
   - Limpiar temporizadores e intervalos (`clearInterval`, `clearTimeout`) cuando los componentes no estén en pantalla para prevenir drenado de batería bajo el sol.

#### 10.7.2 Pilar 2: Economía Extrema de Datos Móviles (Compresión Client-Side Obligatoria)
1. **Compresión Local de Fotografías en Canvas**:
   - Las cámaras nativas de teléfonos actuales capturan fotos en resoluciones de 12 a 48 megapíxeles con pesos entre **5 MB y 15 MB por fotografía**.
   - En un servicio estándar que requiere 4 fotos de inspección inicial + 4 fotos de entrega final (8 fotos en total), enviar imágenes en crudo consumiría hasta **120 MB por servicio** ($>2.4$ GB a la semana).
   - **MANDATO ESTRICTO**: Toda fotografía capturada por el Happer DEBE ser procesada y reescalada localmente en el navegador mediante un elemento `<canvas>` antes de emitirse por red:
     - Resolución máxima delimitada: **1280x720 px** o **1600x1200 px** manteniendo la relación de aspecto.
     - Formato y calidad: JPEG con compresión calibrada a **0.70 – 0.75**.
     - Peso resultante: **120 KB a 220 KB por foto** (reducción mayor al **98%** de peso).
     - Consumo total del protocolo de 8 fotos: **menos de 1.5 MB por servicio completo**.
2. **Payloads JSON Hiper-Compactos**:
   - Los endpoints de la API (`api.php`) deben devolver únicamente las propiedades requeridas para el estado actual de la pantalla, evitando responder con objetos inflados o históricos innecesarios.
3. **Estrategia de Caché Estática**:
   - El Service Worker (`firebase-messaging-sw.js` / Cache API) debe almacenar en caché los estilos, fuentes e iconos estáticos para no descargarlos repetidamente durante la jornada.

#### 10.7.3 Pilar 3: Resiliencia ante Desconexión y Recuperación de Estado (Zero Data Loss)
1. **Persistencia Inmediata de Estado de Misión**:
   - El estado de la misión activa (`pasoActivo`), el tiempo transcurrido del cronómetro de lavado y los checks de calidad completados deben persistirse en memoria local (`localStorage` / `sessionStorage`) en tiempo real.
   - Si el navegador se cierra accidentalmente, el teléfono se reinicia o el Happer apaga la pantalla para ahorrar batería, al reabrir la app el servicio se restaura exactamente en el estado en que se encontraba, sin reiniciar timers ni pedir pasos previos.
2. **Tolerancia a Cortes durante la Subida y Botón de Reintento**:
   - Si una petición de subida de imagen falla por corte de red celular (`net::ERR_INTERNET_DISCONNECTED`, timeout o fallo de DNS), la aplicación **NUNCA** debe resetear el paso ni borrar la fotografía del dispositivo.
   - El slot debe conservar la previsualización local, mostrar un estado de advertencia suave (*"Fallo de conexión al subir. Toca para reintentar"*) y proveer un botón de reintento en un toque.
3. **Validación Granular y Reconocimiento Parcial en Servidor**:
   - Cuando el Happer presiona continuar hacia Identidad, el endpoint `verificar_fotos_inspeccion` evalúa cada cuadrante de forma independiente en la base de datos MySQL.
   - Si 3 de las 4 fotos se subieron antes de que se cortara la señal, el sistema solo exige volver a transmitir el cuadrante faltante, sin invalidar las 3 fotos ya respaldadas exitosamente en el servidor.
4. **Feedback Amigable Sin Crasheos**:
   - Capturar todas las excepciones de red en los `fetch()` del cliente con bloques `try/catch`.
   - Mostrar Toasts discretos o indicadores de estado de conexión (*"Conexión inestable detectada. Conservando datos localmente..."*) en lugar de alertas intrusivas o errores crípticos de servidor.

---

## 11. Torre de Control Operativa (Mission Control)

Acceso: `/HAP/SISTEMA/TORRE_CONTROL/`

### 11.1 Arquitectura Visual de Pantalla Dividida
```
+-------------------------------------------------------------------------------+
| NIVEL 1: Logo HAP | 🟢 EN LÍNEA | 🕒 Reloj | 🔄 Sync | 🔔 Sonido | 🚪 Salir   |
| NIVEL 2: [Hoy][Mañana][Semana][Mes][Todos] | 🔍 Buscador en Vivo | [Vistas]   |
+-------------------------------------------------------------------------------+
| KPI Strip: [Servicios 7] [Por Asignar 0] [En Camino 1] [En Lavado 5] ...      |
+---------------------------------------+---------------------------------------+
| PANEL IZQUIERDO: RADAR EN VIVO        | PANEL DERECHO: DESPACHO KANBAN        |
| - Mapa Leaflet 100% elástico          | 🔴 POR ASIGNAR (Scroll independiente) |
| - Pines de Happers en tiempo real     | 🟡 EN TRASLADO (Tarjetas con timer)   |
| - Pines de servicios con tooltip      | 🔵 EN LAVADO   (Cronometría en vivo)  |
| - Chips flotantes de centrado en QRO  | 🟢 COMPLETADOS (Ficha de entrega)     |
+---------------------------------------+---------------------------------------+
```

### 11.2 Reglas Técnicas del Mapa Leaflet
- **Mosaicos Primarios**: CartoDB Voyager (`rastertiles/voyager/{z}/{x}/{y}.png`).
- **Respaldo Automático**: Conmutación a Esri World Street Map en caso de fallos de red.
- **PROHIBICIÓN ESTRICTA**: NUNCA instanciar `ResizeObserver` sobre el contenedor `#leaflet-map` para evitar bucles infinitos de redimensionamiento a 60 fps. Utilizar `window.addEventListener('resize')` y llamadas discretas a `TorreState.map.invalidateSize()` tras pintar marcadores o alternar vistas.
- **Layout Elástico**: Usar siempre `position: absolute; top: 0; left: 0; width: 100%; height: 100%;` dentro de un contenedor flex `flex: 1 1 0%; min-height: 0;`.

### 11.3 Rendimiento Backend (Regla de <50 ms)
- El endpoint `api.php?action=get_telemetry` DEBE resolver en menos de 50 ms (actualmente corre a **19.8 ms**).
- **PROHIBICIÓN ESTRICTA**: NUNCA volver a colocar consultas N+1 en bucles `foreach($happers)`. Toda agregación de servicios debe resolverse con `GROUP BY happer` en una sola consulta.
- Los modales de Detalles 360° y Cancelación DEBEN abrir en el frame 0 (<16 ms) leyendo de `TorreState.servicesData` en memoria local.

### 11.4 Portal de Autenticación y Control de Acceso (`login.php`, `logout.php`, `config.php`)
- **Punto de Entrada**: Todo acceso a `/HAP/SISTEMA/TORRE_CONTROL/` sin sesión activa autorizada es interceptado por `require_torre_auth()` en `config.php` y redirigido fluidamente a `login.php`.
- **PROHIBICIÓN ESTRICTA**: NUNCA volver a redirigir al operador a `../../loginerror.php`. La Torre de Control cuenta con su propio portal de acceso dedicado `login.php`.
- **Roles Autorizados**: Únicamente usuarios con `tipo` en `['ADMINISTRADOR', 'SUPERVISOR', 'Franquiciatario']` y `status = 'ACTIVO'` en la tabla `usuarios`.
- **Esquema de Autenticación Multiformato**: El motor de acceso soporta indistintamente nombre de usuario o correo electrónico (`WHERE usuario = ? OR email = ?`), y valida contraseñas con bcrypt moderno (`password_verify`), salt legado HAP (`concatPasswordWithSalt`), respaldo en columna `clabe` y coincidencia plana.
- **Variables de Sesión Requeridas**: Al autenticar exitosamente, se establecen:
  - `$_SESSION['MM_Username'] = $row['usuario'];`
  - `$_SESSION['MM_UserGroup'] = $row['tipo'];`
  - `$_SESSION['MM_Nombre'] = $row['nombre'];`
  - `$_SESSION['MM_UserId'] = $row['id'];`
- **Cierre de Sesión (`logout.php`)**: Destruye la sesión de PHP, revoca la cookie `PHPSESSID` y redirige a `login.php?logout=1` con alerta de confirmación.

### 11.5 Suite de Mando Integral & Conmutador Maestro de Consolas (`dashboard.php`, `index.php`, `api_dashboard.php`)
- **Acceso Unificado & Conmutador Maestro de Modos (`.mode-master-switcher`)**:
  - Ubicado en el Nivel 1 de cabecera en ambas pantallas para alternancia instantánea y simétrica:
    - `[ 🟢 🗺️ Radar Operativo ]` (`index.php`): Despacho logístico en tiempo real con radar Leaflet, tablero Kanban y cronómetros de 4 etapas por orden. Cuenta con pulso esmeralda `🟢 EN VIVO` y atajo de teclado **[R]**.
    - `[ 📊 Dashboard ]` (`dashboard.php`): Centro ejecutivo de analíticas, ranking por CP, directorio CRM y flota. Atajo de teclado **[D]**.
- **Pestaña de Acceso Prioritario en Dashboard (Nivel 2)**:
  - En la barra `.dashboard-tabs`, la primera opción es el enlace directo `[ 🟢 🗺️ Radar en Vivo (Despacho) ]` (`.tab-btn-radar-highlight`), garantizando máxima visibilidad para operadores nuevos.
- **Hero Callout Banner en Analíticas (`.radar-hero-callout`)**:
  - Banner en la vista principal de KPIs que contextualiza la operación y despliega el botón `🗺️ Abrir Radar Operativo & Despacho →` junto con el conteo de servicios activos del día provistos por `api_dashboard.php?action=get_overview` (`operacion_hoy`).
- **Analíticas Financieras & Operativas**:
  - Cálculo de facturación neta, MRR recurrente de membresías, ticket promedio, efectividad de servicio y tasa de retención.
  - Gráficas de tendencias históricas de facturación y volumen, mix de especialidades de servicio, distribución semanal y mapa de calor por colonias/CPs.
- **Segmentación y Leaderboard de Clientes por LTV**:
  - Segmentación automática: 👑 `VIP Diamond` (+$3,000 MXN), 💎 `Socio HAP` (con membresía activa), ⭐ `Frecuente` (3+ servicios), 🌿 `Nuevo` (1 servicio), y ⚠️ `En Riesgo` (>45 días de inactividad con historial previo).
  - Enlaces de comunicación directa a WhatsApp en 1 clic para fidelización y atención inmediata.
- **Expediente / Ficha 360° del Cliente**:
  - Ficha completa en `cliente.php` y drawer lateral que condensa identidad, Mi Garage (autos, categoría, tapicería), domicilios con coordenadas, estatus de suscripción de Días HAP e historial cronológico de órdenes.

### 11.6 Pantalla Completa de Expediente 360° y Radiografía Analítica (`cliente.php`, `cliente.css`, `cliente.js`)
- **Acceso Directo**: `/HAP/SISTEMA/TORRE_CONTROL/cliente.php?id={id_cliente}`.
- **Arquitectura de Pantalla Completa**:
  - Reemplaza la vista comprimida de drawer lateral cuando el operador requiere análisis profundo, auditoría de un cliente o atención ejecutiva.
  - Header superior con navegación de un clic a `Volver al Dashboard`, `Radar Operativo` y paginador secuencial de ranking (`◀ Anterior` / `Siguiente ▶`).
- **Hero Card del Cliente**:
  - Identidad (Nombre, Avatar de inicial, Email, Teléfono con link telefónico directo `tel:`).
  - Botón de WhatsApp Inteligente (`btn-hero-wa`): Redacta dinámicamente un mensaje personalizado según los días transcurridos desde su último servicio para reactivación inmediata.
  - Botón de impresión rápida (`window.print()`) optimizado para exportar ficha técnica en PDF.
  - **Health Score Operativo Predictivo (0 - 100%)**:
    - Algoritmo que calcula el ratio entre `días_sin_servicio` y la `frecuencia_habitual_en_días` del cliente.
    - `🟢 En Ciclo Óptimo` (98%): ratio $\le 1.1$.
    - `🟡 Retraso Leve` (50% - 89%): ratio entre $1.1$ y $1.8$.
    - `🔴 Riesgo de Abandono / Churn` ($\le 45\%$): ratio $> 1.8$ o más de 45 días inactivo.
    - Proyección en fecha exacta del próximo servicio sugerido.
  - Insignias dinámicas de Tier (`VIP Diamond`, `Socio Membresía HAP`, `Frecuente`, `Nuevo`) y puesto en el Ranking global de LTV.
  - Bloc de notas confidenciales de supervisión con **auto-guardado en tiempo real** hacia `clientes.nota` con debounce de 800 ms.
- **Pestañas Interactivas de Detalle**:
  1. `🔬 Radiografía & KPIs`: Dock de 6 tarjetas de alta fidelidad (LTV histórico facturado, Ticket Promedio, Frecuencia en días, Tasa de completitud de órdenes, Propinas acumuladas a happers, Ahorro económico bonificado por membresía), Happer preferido/de confianza con volumen de servicios atendidos, Gráfica mensual de gasto y Gráfica dona de especialidades solicitadas en Chart.js.
  2. `🚗 Autos en Cochera (Mi Garage)`: Tarjetas individuales de vehículos registrados con marca, alias, tamaño, color, tapicería y **conteo individual de lavados recibidos** por cada vehículo.
  3. `📍 Direcciones Guardadas`: Tarjetas con alias, calle, colonia, código postal, referencias de caseta/acceso y botón de enlace directo con geolocalización a **Google Maps**. Fallback automático a la dirección de perfil para clientes con registros legados.
  4. `📜 Historial de Servicios`: Tabla cronológica exhaustiva con folio de orden, fecha y hora, vehículo atendido, servicio contratado, monto pagado, happer asignado, estatus y calificación en estrellas.
  5. `📸 Galería de Calidad`: Mosaico fotográfico de evidencias de entrega y comprobantes tomados en campo por los Happers (`fotos` e `images_evidencias/`).
- **Monitoreo de Flota de Happers**:
  - Seguimiento de servicios ejecutados, facturación generada y calificación en estrellas por operador.

### 11.7 Gamificación: Ranking por Código Postal & Motor de Premiación Mensual (`dashboard.php`, `api_dashboard.php`)
- **Reglas del Juego HAP en la App de Clientes**:
  - Cada servicio finalizado en el mes calendario otorga **100 Puntos** al cliente.
  - El ranking se compite a nivel de **Código Postal / Zona de Cobertura** (ej. C.P. 76269 Zibatá, 76230 Juriquilla, 76146 El Refugio, 76060 Querétaro Centro, 76226 El Campanario, etc.).
  - **Regla Inquebrantable de Clasificación**: Para ser apto al premio mensual, el competidor **DEBE contar con mínimo 2 lavados finalizados en el mes** ($\ge 200$ Pts). Si un cliente acumula 1 lavado (100 Pts), aparece en la tabla pero con estatus `⏳ No clasificado (<2)` y NO puede ganar el premio del ciclo.
- **Premio Oficial Mensual**:
  - El competidor **#1 de cada Código Postal** gana **1 Lavado Ecológico Gratis**.
- **Motor de Corte Mensual Automatizado (`execute_monthly_closure`)**:
  - Detección automática de ciclos vencidos pendientes de cierre oficial (`can_close`).
  - Al ejecutar el corte:
    1. Archiva a los ganadores #1 en la tabla `ranking_cierres_mensuales` con `premio_otorgado = '1 Lavado Ecológico Gratis'`.
    2. Acredita la bonificación en automático:
       - Si el ganador cuenta con membresía activa en `clientes_membresias`: se incrementa `lavados_disponibles = lavados_disponibles + 1`.
       - Si el ganador NO tiene membresía: se bonifican **+$221.00 MXN** directamente a su monedero electrónico (`clientes.referido_credito`).
    3. Asienta la bitácora oficial en `clientes.nota`.
- **Salón de Campeones Histórico (Hall of Fame)**:
  - Registro perpetuo de los campeones mensuales de cada fraccionamiento/CP, visible para auditoría y transparencia.

### 11.8 Directorio Maestro de Clientes (CRM Operativo de Torre de Control v2.11.0)
- **Consolidación de Base de Datos (~665 clientes) en Pantalla Completa (100% Width)**:
  - Vista unificada en la pestaña `👥 Clientes` de `dashboard.php` expandida a todo el ancho de pantalla para máxima legibilidad operativa.
  - **11 Columnas Operativas con Ordenamiento Interactivo (Click-to-Sort)**:
    1. `# ID` (Checkbox de selección múltiple + ordenamiento por ID)
    2. `Cliente / Identidad`: Avatar, nombre en negrita, email y pill de tier (ordenamiento alfabético).
    3. `Contacto Directo`: Teléfono con enlace directo y botón de chat en 1 clic a WhatsApp (`wa.me/`).
    4. `Autos`: Badge compacto interactivo (`🚗 X autos` o `Sin autos`) con tooltip al pasar el cursor detallando marca, alias y tamaño de cada coche.
    5. `Ubicación & C.P.`: Código Postal y domicilio registrado (ordenamiento por C.P.).
    6. `Membresía`: Estatus del plan (`💎 Plan HAP`, día asignado y lavados disponibles) o `Individual`.
    7. `Monedero`: Saldo disponible en monedero de crédito/referidos ($ MXN, sortable).
    8. `Servicios & LTV`: Conteo de servicios finalizados y facturación total acumulada ($ MXN, sortable).
    9. `Ticket Promedio`: Gasto medio por orden finalizada ($ MXN, sortable).
    10. `Último Servicio & Salud`: Fecha relativa del último servicio y Health Score predictivo (`Saludable`, `Estable`, `En Riesgo`, `Inactivo`, sortable).
    11. `Acciones`: Botón `👤 Expediente` con enlace directo a la vista completa `cliente.php?id={id}`.
- **Barra de Acciones Masivas Flotante (Bulk Actions Dock)**:
  - Selección individual con checkboxes o masiva con el checkbox maestro de cabecera.
  - Al seleccionar $\ge 1$ cliente se despliega un dock flotante cyberpunk inferior:
    - **💬 Difusión WhatsApp**: Abre la lista con enlaces directos para enviar comunicados o promociones personalizadas a cada cliente seleccionado.
    - **💰 Bonificar Monedero Masivo (`action=bulk_credit_wallet`)**: Modal de acreditación que suma saldo a `clientes.referido_credito` de forma transaccional y asienta el concepto en `clientes.nota`.
- **Exportación de Datos a CSV / Excel**:
  - Botón `📥 Exportar CSV` que descarga instantáneamente la tabla filtrada y ordenada con codificación UTF-8 BOM (`\uFEFF`) para compatibilidad nativa con Microsoft Excel y Google Sheets.
- **Paginación Dinámica y Selector de Densidad**:
  - Control de filas por página (25, 50, 100, Todos) con paginador numérico y navegación rápida.
- **Modal de Alta Rápida de Clientes (`+ Nuevo Cliente`, `action=create_client`)**:
  - Modal para registro exprés desde Torre de Control: crea usuario con contraseña segura bcrypt, genera código de referido único `HAPxxxxx`, asocia su primer vehículo en `vehiculos` y registra su dirección en `clientes_direcciones`.
- **Filtros Inteligentes de Gamificación**:
  - `📢 Candidatos a Clasificar (1 lavado)`: Filtro de un clic en la pestaña de Ranking para identificar clientes con exactamente 1 servicio en el mes y redactarles mensaje de WhatsApp para que completen su 2do lavado y clasifiquen al premio de su C.P.
  - Enlaces de WhatsApp directo a campeones en el Salón de Campeones Histórico.

### 11.9 Motor de Temas Dual (Claro / Oscuro / Automático Horario) (`theme.css`, `theme.js`)
- **Arquitectura Universal de Temas**:
  - Soporte integral de Tema Claro (`[data-theme="light"]`) y Tema Oscuro (`[data-theme="dark"]` por defecto) en toda la suite de Torre de Control (`dashboard.php`, `index.php`, `cliente.php`).
- **Detección Automática por Franja Horaria (Día / Noche)**:
  - Modo predeterminado `auto`: evalúa la hora local del operador (`new Date().getHours()`).
  - **Día (07:00 a 18:59)**: Activa automáticamente el **Tema Claro** (fondos limpios Slate 100/blanco puro, tipografía Slate 900 de alto contraste, acentos azul zafiro `#0284c7` y esmeralda `#059669`).
  - **Noche (19:00 a 06:59)**: Activa automáticamente el **Tema Oscuro** (Cyberpunk Dark Slate, acentos cyan neón `#38bdf8` y fondos `#020617`).
  - Monitoreo en segundo plano cada 60 segundos para transiciones suaves al cambiar la franja horaria sin recargar la página.
- **Control Interactivo & Persistencia en LocalStorage**:
  - Píldoras de selección rápida en la cabecera (`.theme-switch-pills`): `☀️ Claro`, `🌙 Oscuro`, `🕒 Auto`.
  - Persistencia bajo la clave `localStorage.getItem('hap_torre_theme')`.
- **Prevención de Destello (Zero FOUC - Flash of Unstyled Content)**:
  - Script síncrono ultra ligero en `<head>` antes de los estilos para resolver e inyectar `data-theme` en `<html>` de forma instantánea a 0 ms.
- **Reactividad en Gráficas (Chart.js)**:
  - Despacho del evento `hapThemeChanged` que actualiza automáticamente las rejillas, leyendas, ejes y bordes de las gráficas de facturación, mix de servicios, distribución y zonas sin recarga de red.

### 11.10 Conclusión Administrativa y Watchdog de Reconciliación Logística
- **Vía de Escape para Excepciones de Campo**: En contingencias operativas (Happer sin batería, avería de dispositivo, fallo de red celular o cierre involuntario de la app), un servicio puede quedar atrapado en `EN_CAMINO` o `PROCESO` habiendo concluido físicamente en sitio.
- **Acción Rápida de Conclusión Administrativa (`[ ✅ Concluir ]`)**:
  - Implementada en las tarjetas Kanban (`EN_TRASLADO` y `EN_PROCESO`) y en la pantalla de Detalles 360° de la orden.
  - Al hacer clic, un modal SweetAlert2 solicita el motivo administrativo obligatorio (ej. *"Servicio concluido en sitio; Happer no pudo escanear QR por falta de batería"*).
  - Al confirmar, se dispara el endpoint `api.php?action=finalizar_servicio_admin`:
    1. **Captura Financiera en Stripe**: Si la orden tiene un `PaymentIntent` con retención previa (`status === 'requires_capture'`), se ejecuta `$intent->capture()`, debitando en firme los fondos de la tarjeta del cliente.
    2. **Actualización de Estatus**: La orden pasa a `FINALIZADO` con timestamp de término (`fin = NOW()`).
    3. **Bitácora y Trazabilidad**: Se registra el operador que ejecutó la acción, la fecha y el motivo exacto en `venta_desc.comentarios`.
    4. **Liberación Inmediata de Flota**: El Happer asignado queda liberado al instante para poder aceptar o recibir nuevos servicios.
    5. **Evento Logístico**: Se emite una alerta a Torre de Control y se refresca el tablero en 0 ms.
- **Watchdog Preventivo de Reconciliación Logística (`api.php?action=get_telemetry`)**:
  - En cada ciclo de telemetría, el backend ejecuta un barrido automático de citas huérfanas o rezagadas con más de 24 horas de antigüedad que permanezcan en estatus `PENDIENTE` o sin asignación de Happer.
  - Las citas rezagadas se auto-transicionan a `CANCELADO` por expiración logística con nota explicativa.
  - Si la cita correspondía a un canje de membresía Días HAP, el sistema **restituye de forma transparente el lavado** al cliente incrementando `clientes_membresias.lavados_disponibles`, garantizando que ningún socio pierda beneficios por citas no cubiertas.

### 11.11 Sincronización Reactiva con Happer en Tiempo Real (Cierre y Cancelación Remota)
- **Desbloqueo Inmediato de Flota en Misión**: Si Torre de Control concluye (`finalizar_servicio_admin`) o cancela administrativamente un servicio, la app del Happer asignado (`mision.php`) recibe la señal en su ciclo de sondeo en tiempo real (`consultar_estado_mision`).
- **Comportamiento Reactivo del Happer**:
  - Detiene al instante los cronómetros de lavado activos (`clearInterval(timerInterval)`).
  - Reproduce una alerta acústica y emite vibración háptica.
  - Actualiza el badge de cabecera a `FINALIZADO` o `CANCELADO`.
  - Muestra el modal de confirmación oficial `modal_torre_signal` con el motivo asentado por el supervisor.
  - Libera al operador para regresar al Radar de misiones sin quedar atrapado en la pantalla de servicio.

### 11.12 Auditoría Integral de Citas Programadas vs Bajo Demanda
- **Ventana de Ejecución de 45 Minutos (`$segundos_restantes <= 2700`)**:
  - Las citas agendadas para días futuros se conservan en estatus `PROGRAMADO` y no bloquean la disponibilidad operativa del Happer en el día actual.
  - Al llegar el día de la cita, la ventana se desbloquea exactamente 45 minutos antes de la hora pactada.
  - Si un Happer intenta iniciar antes de esta ventana (por QR o PIN), el sistema rechaza la operación con una advertencia explicativa indicando la fecha y hora oficial.
- **Mapeo de Estados y Columnas en Torre de Control**:
  - Cuando el Happer confirma su llegada en el Paso 1 de una cita programada, se asienta la hora en `espera` y se clasifica como `EN_SITIO`, actualizando las métricas y columnas del tablero Kanban.

### 11.13 Disclaimers de Contacto y Calidad Estándar HAP
- **Control de Calidad en Comunicaciones**: Tanto en la Torre de Control como en la App del Happer, cualquier intento de comunicación directa con el cliente (llamada telefónica o WhatsApp) despliega obligatoriamente el modal de disclaimer oficial:
  > *"Por estándares de calidad y seguridad HAP, las comunicaciones pueden ser monitoreadas. Recuerda presentarte como Happer oficial."*
- Estética glassmorphic unificada con botones de confirmación directa.

---

## 12. Pasarela de Pagos (Stripe) y Seguridad Financiera

### 12.1 Tokenización en Cliente
- Se utiliza el SDK oficial de **Stripe Elements** (`card-element`).
- Ningún número de tarjeta, CVV o fecha de vencimiento pasa por los servidores de HAP en texto plano. Se genera un `paymentMethod.id` (`pm_...`) en el navegador y se envía tokenizado al servidor.

### 12.2 Regla de Órdenes a $0.00 MXN
- Si una orden tiene total `$0.00 MXN` (por membresía HAP, canje de día HAP o cupón 100% de descuento):
  - **PROHIBICIÓN ESTRICTA**: NUNCA invocar `\Stripe\PaymentIntent::create()` con monto `0`. Stripe arroja error de monto mínimo (`amount must be at least 1000 cents`).
  - El backend debe marcar la orden directamente con estatus `PAGADO_MEMBRESIA` o `CUPON_TOTAL_FREE` sin interactuar con la pasarela bancaria.

### 12.3 Cobros Off-Session en QR
- Al programar citas con tarjeta bancaria, se autoriza el método de pago (`PaymentMethod`). El cargo real se captura de manera segura fuera de sesión (*off-session*) cuando el Happer escanea el QR al concluir el lavado en `HAPPERS/QR/code.php`.

### 12.4 Ciclo de Vida de Pagos en Stripe (Retención Previa vs. Captura Definitiva)
- **Mandato Financiero en Dos Fases**: En toda orden pagada con tarjeta bancaria, el proceso de cobro se divide estrictamente en dos fases:
  1. **Fase 1: Retención Previa / Autorización (`capture_method => 'manual'`)**:
     - Al momento de solicitar el servicio en la app (`CLIENTE/crear_stripe_intent.php`), el `PaymentIntent` se crea obligatoriamente con `capture_method: 'manual'`.
     - Esto congela los fondos en la tarjeta bancaria del cliente en estatus `requires_capture` (garantizando solvencia hasta por 7 días), sin debitar el dinero de manera definitiva.
  2. **Fase 2: Captura Definitiva al Concluir (`$intent->capture()`)**:
     - El cobro definitivo en firme se ejecuta **exclusivamente al finalizar el servicio**.
     - Vías autorizadas de captura:
       - **Vía Operativa**: Escaneo del QR de entrega por el Happer (`HAPPERS/QR/code.php` o `HAPPER_APP/api.php?action=validar_qr_pin`).
       - **Vía Administrativa**: Conclusión forzada desde Torre de Control (`api.php?action=finalizar_servicio_admin`).
     - Al capturarse, el `PaymentIntent` pasa a `succeeded` y se asienta el cobro definitivo.
  3. **Fase 3: Cancelación o Liberación de Fondos (`$intent->cancel()`)**:
     - Si la orden se cancela antes de su ejecución o expira sin servicio, se ejecuta `$intent->cancel()`.
     - Esto cancela la autorización bancaria de inmediato, liberando el saldo retenido al cliente sin cargos ni comisiones de procesamiento.

---

## 13. Programa de Referidos y Facturación CSF

### 13.1 Programa de Referidos HAP
- Cada cliente tiene su código alfanumérico en `clientes.referido_codigo` (ej. `HAP82414`).
- Si un usuario se registra con un enlace de referido (`registro.php?ref=HAPxxxxx`):
  1. El nuevo usuario obtiene **$50.00 MXN de descuento** en su primer servicio.
  2. Al concluirse exitosamente dicho primer servicio, el cliente que refirió recibe **+$50.00 MXN de saldo crédito** acumulable en `clientes.referido_credito`.
  3. Se genera el asiento correspondiente en `referidos_log`.

### 13.2 Módulo de Facturación Fiscal (CFDI)
- En `historial_servicios.php`, cada orden finalizada cuenta con el botón `🧾 FACTURAR SERVICIO`.
- Si el cliente no tiene datos fiscales, se le solicita su RFC, Razón Social, Régimen, CP y el PDF de su **Constancia de Situación Fiscal (CSF)** en `datos_facturacion.php`.
- Al confirmar, el backend `solicitar_factura.php`:
  1. Envía un correo multipart MIME Base64 a `facturacion@soyhap.com` (con copia a `dann.arenas@outlook.com`) adjuntando el PDF de la CSF.
  2. Incluye un botón pre-construido `mailto:` para que el contador de HAP responda al cliente con el PDF y XML de la factura en 1 clic.
  3. Marca `factura_solicitada = 1` en `venta_desc` y cambia el botón a `✅ FACTURA SOLICITADA` (deshabilitado).

---

## 14. Reglas de Oro y Directrices para Futuros Agentes

Si eres un agente de inteligencia artificial o desarrollador trabajando en este repositorio, debes cumplir rigurosamente con los siguientes mandatos:

1. 🚫 **No rompas el mapa Leaflet**: Nunca reintroduzcas `tile.openstreetmap.org` (está bloqueado en web). Usa CartoDB Voyager. Nunca coloques un `ResizeObserver` sobre `#leaflet-map` que ejecute `invalidateSize()`.
2. ⚡ **Mantén la Torre de Control ultrarrápida**: Nunca agregues consultas SQL dentro de bucles en `api.php`. Conserva la latencia en ~20 ms e indexa siempre cualquier columna nueva en `venta_desc`.
3. 💳 **Protege las transacciones financieras**: Respeta la regla de $0.00 MXN en Stripe. Nunca llames a Stripe para órdenes cubiertas al 100% por membresía ($0.00). Si la orden conlleva un copago por upgrade (diferencia económica), procesa exclusivamente la diferencia en Stripe.
4. 💎 **Regla Inquebrantable de Membresía (Bonificación Base + Diferencia / Upgrade)**: Todo socio con membresía activa tiene 100% incluido el `LAVADO HAP` de la categoría de su vehículo ($0.00 MXN). Si solicita un servicio superior (`ENCERADO`, `PROTECTOR`, `COMBOS`, `INTEGRAL`), el sistema DEBE bonificarle el valor comercial del `LAVADO HAP` y cobrarle únicamente la diferencia económica resultante ($P_{\text{servicio}} - V_{\text{lavado\_base}}$), descontando 1 lavado de su bolsa de membresía.
5. 🕒 **Zona Horaria Querétaro**: Todo cálculo de tiempo debe utilizar la zona horaria oficial `date_default_timezone_set('America/Mexico_City')`.
6. 🛡️ **Compatibilidad PHP 8**: Mantén `@mysqli_report(MYSQLI_REPORT_OFF)` y captura excepciones con `\Throwable $e` en scripts que procesan formularios para evitar pantallas blancas.
7. 🌐 **Sincronización Producción**: Tras modificar archivos locales, asegúrate de desplegarlos a producción en `95.111.214.233`, asignar `chown -R www-data:www-data` y actualizar el `CHANGELOG.md`.
8. 💬 **Estilo de Comunicación**: Dirígete al usuario en español, con tono ejecutivo, técnico, proactivo y profesional.
9. 🛵 **Máximo 1 Servicio Activo por Happer (Exclusividad Operativa)**: Jamás permitir que un Happer tome o reciba en asignación más de un servicio a la vez. Siempre validar que no cuente con órdenes en `ACEPTADO`, `EN_CAMINO`, `PROCESO` o `INICIADO` del día en curso.
10. 💳 **Cobros Stripe en 2 Fases (Retención y Captura)**: Al solicitarse un servicio con tarjeta bancaria, se debe crear el PaymentIntent con `capture_method: manual` (retención previa). La captura definitiva (`$intent->capture()`) se ejecuta única y exclusivamente cuando el servicio es marcado como `FINALIZADO` (vía QR de Happer o Conclusión Administrativa en Torre de Control).
11. ⏰ **Ventana de Ejecución de Citas Programadas (Máximo 45 min antes)**: Jamás permitir que un Happer inicie (`PROCESO`) un servicio programado con más de 45 minutos de anticipación a la fecha y hora pactada con el cliente (tanto en `happer.php` como en `QR/code.php`). Asimismo, las citas agendadas para días futuros deben conservar estatus `PROGRAMADO` y no bloquear la disponibilidad operativa del Happer en el día en curso.
12. 📱 **Sesión Única por Dispositivo en App Happer (`session_token`)**: Ningún Happer puede mantener abiertas sesiones concurrentes en dos teléfonos o pestañas simultáneamente. Todo login genera un nuevo `session_token` e invalida el anterior expulsando al dispositivo previo con `HTTP 401 Unauthorized` (`SESSION_DUPLICATED`).
13. 🔒 **Protocolo de Misión Estrictamente Unidireccional e Inspección Verificada en BD**: Jamás permitir retroceder a pasos anteriores completados en el HUD de misión (`mision.php`). Antes de permitir el avance al Paso 3 (Identidad), es mandatorio verificar en base de datos (`verificar_fotos_inspeccion`) que los 4 ángulos de inspección inicial estén físicamente guardados en la tabla `fotos`.
14. 🛑 **Deprecación Absoluta de la App Clásica (`/HAPPERS/`)**: Toda nueva funcionalidad para operadores debe desarrollarse y ejecutarse exclusivamente en `/HAP/SISTEMA/HAPPER_APP/`. El directorio legacy `/HAPPERS/` debe mantenerse bloqueado con el modal de obsolescencia (`modal_obsoleto.php`).
15. 🛰️ **Sincronización Reactiva Bidireccional Torre-Happer**: Toda acción administrativa ejecutada en Torre de Control sobre un servicio activo (finalización, cancelación, reasignación) debe propagarse en tiempo real a la app del Happer asignado (`modal_torre_signal`) para actualizar su estado y liberar al operador sin requerir recargas forzadas.
16. 🚪 **Bifurcación Limpia de Roles en Portal de Inicio**: La pantalla de bienvenida de la plataforma (`CLIENTE/index.php`) debe mantener clara la separación entre Clientes (`[ 🚗 SOY USUARIO ]`) y Operadores (`[ ⚡ SOY HAPPER ]`), sin enlaces secundarios obsoletos ni badges descontinuados.
17. 📱⚡ **Arquitectura de Campo HAP (Gama Baja, Ahorro Extremo de Datos y Resiliencia a Cortes de Red)**: Toda funcionalidad, pantalla o flujo desarrollado para los conductores (`HAPPER_APP`) debe diseñarse asumiendo el peor escenario operativo: smartphones Android modestos (2-3 GB RAM), planes de datos móviles limitados y caídas frecuentes de señal en carretera o cocheras. Es mandatorio: (a) Mantener el bundle ultraligero (<200 KB en Vanilla JS/CSS sin frameworks), (b) Comprimir localmente en canvas toda fotografía a máx 1280-1600px con JPEG 0.72 (<200 KB por foto) reduciendo el consumo de datos en >95%, (c) Persistir el progreso y cronómetro en `localStorage` ante cierres involuntarios, (d) Retener previews locales y ofrecer reintentos en 1 clic ante cortes de red sin resetear formularios, y (e) Validar granularmente en servidor para no retransmitir fotos ya recibidas.
18. 🔑⚡ **Persistencia Continua de Sesión en Campo (Zero-Logout Policy & Auto-Restore Indefinido)**: En la App de Happers (`HAPPER_APP`), la sesión del dispositivo activo DEBE mantenerse viva y autenticada de manera indefinida (cookies y tokens con vigencia de 365 días y auto-restauración silenciosa en base de datos). Los operadores en campo jamás deben ser desconectados por inactividad, bloqueo de pantalla, reinicio del teléfono o reciclaje del navegador por el sistema operativo. La sesión únicamente se invalida por tres causas explícitas: (1) Cierre de sesión voluntario (`logout.php`), (2) Detección de inicio de sesión en un nuevo dispositivo (Regla #12: Monosesión), o (3) Baja administrativa de la cuenta (`status = 'BAJA'`).
19. 🌐🏛️ **Convención Internacional de Base de Datos en Inglés (Enterprise DB Standard)**: Toda nueva tabla, columna, índice y relación de base de datos debe diseñarse estrictamente bajo las mejores prácticas internacionales en **idioma inglés**:
    - Nombres de tablas en minúsculas, `snake_case` y en **plural** (ej. `franchises`, `franchise_users`, `happers`, `admin_users`, `customers`, `services`, `service_photos`).
    - Clave primaria simple obligatoria: `id BIGINT UNSIGNED AUTO_INCREMENT`.
    - Claves foráneas: `<singular_table_name>_id` (ej. `franchise_id`, `happer_id`, `customer_id`, `service_id`). Queda estrictamente prohibido vincular entidades por cadenas de texto o correos en tablas nuevas.
    - Marcas temporales (Timestamps): Formato `_at` en UTC (`created_at`, `updated_at`, `started_at`, `completed_at`, `last_login_at`). Fechas sin hora en `_date` (`birth_date`).
    - Campos booleanos: Prefijados obligatoriamente con `is_`, `has_` o `can_` (ej. `is_active`, `is_default`, `has_damage`).
    - Montos financieros: Sufijo `_amount` o `_balance` en tipo `DECIMAL(10,2)` (ej. `total_amount`, `cash_balance`).
    - Estatus y Enums: Textos descriptivos en mayúsculas semánticas (`PENDING`, `ACCEPTED`, `EN_ROUTE`, `ARRIVED`, `IN_PROGRESS`, `COMPLETED`, `CANCELLED`).
20. 🧩📱 **Arquitectura de 4 Proyectos Independientes (BFF: Frontend PWA + Dedicated Backend API)**: La plataforma HAP se compone de cuatro aplicaciones completamente independientes y desacopladas entre sí:
    - **HAP Fleet**: WebApp/PWA (`fleet.hap.mx`) + Backend API dedicado (`api.fleet.hap.mx`) para socios de territorio y dueños de flotilla (monitoreo de sus lavadores, comisiones, liquidaciones de efectivo y KPIs de su zona).
    - **HAP Drivers**: PWA móvil (`driver.hap.mx`) + Backend API dedicado (`api.drivers.hap.mx`) para los lavadores en campo (inspección de 4 ángulos, QR/PIN, HUD de misión, telemetría y ganancias).
    - **HAP Control Tower**: WebApp corporativa central (`tower.hap.mx`) + Backend API dedicado (`api.tower.hap.mx`) para directores, finanzas y soporte nacional (mando integral, radar nacional, altas de franquicias y configuración global).
    - **HAP Users**: PWA (`app.soyhap.com`) + Backend API dedicado (`api.users.soyhap.com`) para clientes particulares y socios de membresía HAP (solicitud de servicios, Mi Garage, Días HAP, pasarela Stripe y facturación CSF).
    - **Patrón BFF y Microservicios**: Cada proyecto es un microservicio autónomo con su propia API especializada (Backend For Frontend). No existe una API monolítica central; todas las APIs se conectan directamente a la capa central de base de datos relacional (Amazon RDS).
21. 🛡️📦 **Principio de No Destrucción / Migración Segura (Non-Destructive Evolution & Mandatory Backups)**: En toda refactorización estructural o migración masiva de base de datos y código:
    - **Regla de Oro**: NUNCA sobreescribir el código o las tablas actuales de producción de manera destructiva o directa.
    - **Nuevos Directorios Independientes**: Todo nuevo backend, PWA o módulo desacoplado debe construirse en carpetas nuevas y autónomas (ej. `/hap-fleet/`, `/hap-drivers/`, `/hap-users/`, `/hap-control-tower/`), garantizando que la operación existente continúe funcionando al 100% en paralelo.
    - **Respaldos Previos Obligatorios**: Antes de cualquier cambio estructural, generación de tablas o migración de datos, es mandatorio generar un respaldo completo y verificado (SQL dump de base de datos y backup de archivos).
    - **Convivencia Pacífica**: Durante el periodo de transición hacia AWS, el sistema anterior en VPS continúa operando normalmente hasta el corte definitivo en Route 53 (*Zero Downtime*).
22. ☁️⚡ **Infraestructura Cloud-Native en AWS (Global Accelerator, Beanstalk, RDS, S3, Amplify)**: La arquitectura en la nube de HAP 3.0 se rige formalmente por la especificación detallada en [`INFRASTRUCTURE.md`](file:///Users/Dann/Server/ha-p/INFRASTRUCTURE.md):
    - **Frontend**: AWS Amplify Hosting (S3 + CloudFront Edge) para las 4 aplicaciones PWA independientes.
    - **Red y Tráfico Móvil**: AWS Global Accelerator con IPs Anycast estáticas conectado a un Shared Application Load Balancer (ALB) con enrutamiento por Host (`api.*.hap.mx`).
    - **Cómputo Backend**: 4 entornos independientes de Elastic Beanstalk (uno por cada BFF API), con escalado elástico asimétrico y aislamiento total de fallos (*Blast Radius Containment*).
    - **Base de Datos Central**: Amazon RDS Cluster (PostgreSQL + PostGIS o MySQL 8.0) con Instancia Primaria (Writer) y Réplica de Lectura (Reader) para reportes y dashboards.
    - **Almacenamiento Multimedia**: Amazon S3 con subida directa vía Presigned URLs (cero ancho de banda de fotos a través de las APIs) y archivado automático a S3 Glacier Flexible Retrieval a los 90 días.
    - **Telemetría en Vivo**: Amazon ElastiCache (Redis) para pings GPS de alta frecuencia y despacho en tiempo real a 0 ms.
23. 🚗🛡️ **Exclusividad Operativa por Vehículo, Anti-Doble Clic e Idempotencia (Zero Duplicados y No Superposición)**:
    - Ningún vehículo puede tener más de **1 servicio activo simultáneo** (`PENDIENTE`, `ACEPTADO`, `EN_CAMINO`, `PROCESO`, `INICIADO`).
    - Ningún vehículo puede tener dos citas `PROGRAMADO` en la misma fecha con diferencia menor a **±60 minutos**.
    - El backend DEBE implementar una ventana de guarda de **60 segundos** anti-rebote / doble clic que rechace peticiones duplicadas para el mismo cliente y vehículo sin debitar lavados de membresía ni realizar dobles retenciones bancarias.
    - Toda interfaz de cliente (Frontend) DEBE bloquear y deshabilitar inmediatamente el botón de confirmación/pago al primer toque, mostrando un overlay de pantalla completa modal no cerrable durante todo el tiempo que tome el procesamiento.
24. 📍🛡️ **Cobertura Obligatoria por Código Postal (Zero Órdenes Fuera de Zona)**:
    - La plataforma HAP cuenta con cobertura exclusiva y obligatoria en **15 Códigos Postales autorizados** (`76269`, `76230`, `76146`, `76226`, `76100`, `76060`, `76215`, `76246`, `76900`, `76902`, `76904`, `76910`, `76090`, `76170`, `87380`).
    - NUNCA permitir la creación, retención en Stripe o inserción en `venta_desc` de ningún servicio (Express, Programado o Membresía $0.00) fuera de estos 15 códigos postales.
    - Toda validación DEBE operar a través de la librería centralizada `Connections/cobertura.php` (`hap_es_cp_permitido()`, `hap_obtener_cps_permitidos()`).
    - En caso de C.P. fuera de cobertura, activar obligatoriamente el **Plan de Retención Amigable** (invitar a pedir en oficina/trabajo, registrar interés en lista de espera `kpicp` y mostrar el desglose de zonas autorizadas).
25. 🔒🔢 **PIN de Seguridad de 4 Dígitos y Regla Anti-Fraude de Validación en Sitio**:
    - Cada orden de servicio cuenta con un PIN numérico exclusivo y persistente de 4 dígitos (`venta_desc.pin`) que sirve de alternativa oficial cuando el Happer no puede escanear el código QR.
    - NUNCA confundir el PIN (4 dígitos) con el Folio de Orden (5 dígitos).
    - En la interfaz de seguimiento del cliente (`tracking.php`), se debe exhibir el PIN en casillas numéricas destacadas junto con la advertencia estricta de seguridad: *"No compartas este PIN con tu Happer por llamada o mensaje. Proporciónalo únicamente cuando el Happer haya llegado a tu ubicación y esté frente a tu vehículo."*
    - En la Happer App (`mision.php` y `api.php`), es mandatorio que el operador confirme primero su llegada al domicilio (Paso 1) antes de que el backend acepte la validación del PIN o QR para iniciar el lavado (Paso 3).
26. ⏰🛡️ **Control de Capacidad por Horario (Máx 2 Reservas) y Toque de Queda Matutino Post-16:00**:
    - Ningún horario puede tener más de **2 reservas activas simultáneas** por día en `venta_desc` (`estatus NOT IN ('CANCELADO')`).
    - Pasadas las **16:00 horas**, queda prohibido agendar citas de **08:00 a 11:00 AM para el día siguiente**.
    - Frontend DEBE inhabilitar visualmente el slot (`.time-slot-chip.disabled`) y desplegar el modal interactivo SweetAlert2: *"Horario No Disponible - Tenemos alta demanda en este momento y por ahora no puedes programar en este horario, pero te invitamos a programar tu servicio en la siguiente hora disponible."*
    - Backend DEBE validar atómicamente ambas condiciones antes de insertar cualquier orden en `venta_desc` o procesar canjes de membresía / cobros en Stripe. Aplica unificadamente para citas regulares, membresías ($0.00 MXN), upgrades y reagendamientos.

---

## 15. Arquitectura Global de 4 Aplicaciones y Estándar Enterprise DB

> [!IMPORTANT]
> Para la especificación técnica completa de la infraestructura en la nube, variables de entorno, balanceo de carga, pipelines CI/CD y políticas de seguridad, consulta el documento maestro:
> **👉 [`INFRASTRUCTURE.md`](file:///Users/Dann/Server/ha-p/INFRASTRUCTURE.md)**.

### 15.1 Diagrama de los 4 Proyectos Autónomos (BFF Microservices + Central RDS)

```
+---------------------------------------------------------------------------------------------------------+
|                                      HAP ECOSYSTEM 3.0 (AWS CLOUD)                                      |
+---------------------------------------------------------------------------------------------------------+
|                                                                                                         |
|   1. HAP Users              2. HAP Drivers            3. HAP Fleet              4. HAP Control Tower    |
|      (Client PWA)              (Driver PWA)              (Franchise WebApp)        (Central WebApp)     |
|      app.soyhap.com            driver.hap.mx             fleet.hap.mx              tower.hap.mx         |
|           │                         │                         │                         │               |
+───────────┼─────────────────────────┼─────────────────────────┼─────────────────────────┼───────────────+
            │ (REST JSON)             │ (REST JSON)             │ (REST JSON)             │ (REST JSON)
            ▼                         ▼                         ▼                         ▼
+───────────────────────+ +───────────────────────+ +───────────────────────+ +───────────────────────+
|     API Users BFF     | |    API Drivers BFF    | |     API Fleet BFF     | |  API Control Tower    |
| api.users.soyhap.com  | |  api.drivers.hap.mx   | |   api.fleet.hap.mx    | |   api.tower.hap.mx    |
| (Beanstalk Env 1)     | | (Beanstalk Env 2)     | | (Beanstalk Env 3)     | | (Beanstalk Env 4)     |
+───────────┬───────────+ +───────────┬───────────+ +───────────┬───────────+ +───────────┬───────────+
            │                         │                         │                         │
            └─────────────────────────┴────────────┬────────────┴─────────────────────────┘
                                                   │
                                                   ▼
+─────────────────────────────────────────────────────────────────────────────────────────────────────────+
|                                 CENTRAL ENTERPRISE DATA LAYER (AMAZON RDS)                              |
|                                                                                                         |
|       PRIMARY INSTANCE (WRITER)                             READ REPLICA (READER)                       |
|       - services (Transactions & Orders)                    - Dashboards & KPIs (Control Tower)         |
|       - service_photos (Evidence metadata)                  - Franchise Financial Reports (Fleet)       |
|       - happers & customers                                 - Heavy CSV Exports & Auditing              |
|       - franchises & franchise_users                                                                    |
+──────────────────────────────────────────────────┬──────────────────────────────────────────────────────+
                                                   │
                                                   ▼
+─────────────────────────────────────────────────────────────────────────────────────────────────────────+
|                              AMAZON ELASTICACHE REDIS & AMAZON S3 MEDIA                                 |
|  - Redis: High-Frequency GPS Pings (GEOADD / GEORADIUS), Live Radar Pub/Sub, Rate-Limiting              |
|  - S3: Direct Presigned URL Uploads for Angle Inspection Photos & Invoices PDF -> Glacier Lifecycle     |
+─────────────────────────────────────────────────────────────────────────────────────────────────────────+
```

### 15.2 Mapeo de Entidades Legadas vs Estándar Enterprise en Inglés

| Entidad Legada (Spanglish / Acoplada) | Nueva Entidad Enterprise (English Standard) | Dominio / Rol Responsable |
| :--- | :--- | :--- |
| `usuarios` (mezclaba admins y happers) | `admin_users` | Personal corporativo de Torre de Control |
| `usuarios` (con `cargo = 'HAPPER'`) | `happers` | Operadores y lavadores móviles en campo (HAP Drivers) |
| `usuarios` (con `consecion`) | `franchises` & `franchise_users` | Concesiones territoriales y socios flotilla (HAP Fleet) |
| `clientes` | `customers` | Clientes finales particulares y socios (HAP Users) |
| `vehiculos` | `customer_vehicles` | Garage de vehículos clasificados (CHICO, MEDIANO, GRANDE) |
| `venta_desc` | `services` | Núcleo transaccional de órdenes de lavado y estatus |
| `fotos` | `service_photos` | Evidencias fotográficas clasificadas por ángulo de inspección |
| `gps` / `bitacora_happer` | `happer_telemetry` | Pings de alta frecuencia, coordenadas y batería |




