# Booking Engine Btec

## Objetivo

Construir un motor de reservas reutilizable para que los clientes de los clientes Btec puedan vender servicios desde su sitio web sin duplicar lógica por proyecto.

El motor debe:

- usar el mismo backoffice Btec como fuente operativa
- instalarse por módulo
- soportar branding por cliente
- exponer un canal público de reservas
- evitar que cada sitio web inserte SQL directo a mano

## Hallazgos del estado actual

### Backoffice actual

En `btec-core/releases/v1.2.0/func/module_manager.php` ya existe base para instalar por módulo:

- `reservas`
- `vehiculos`
- `choferes`
- `vehiculos_asignados`
- catálogo e instalación de módulos

Esto es valioso porque ya tienes:

- estrategia de releases
- activación por cliente
- migraciones idempotentes
- patrón `predeploy required`

### Canal público actual

En `loscabostransfer/mt` el sitio público hoy:

- consulta `cars`, `tarifas`, `hoteles` para cotizar
- inserta directo en `reservas`
- confirma pago y envía correos desde páginas PHP sueltas

Archivos clave:

- `loscabostransfer/mt/index.php`
- `loscabostransfer/mt/func/getRates.php`
- `loscabostransfer/mt/func/gen_res.php`
- `loscabostransfer/mt/my-reservation.php`
- `loscabostransfer/mt/confirm-activity.php`

## Problema de arquitectura a resolver primero

Hoy hay dos mundos mezclados:

1. El mundo administrativo Btec.
2. El mundo público del sitio web.

El sitio público depende de tablas heredadas y de scripts específicos por cliente. Si escalas así, terminarás manteniendo un motor distinto por cada web.

La decisión correcta es definir un **núcleo canónico** y hacer que el front público consuma ese núcleo por API.

## Decisión recomendada

Tomar `reservas` como entidad operativa principal y construir un nuevo módulo llamado provisionalmente:

- `booking-engine-public`

Este módulo no debe ser solo una página. Debe incluir 4 capas:

1. `Booking Domain`
   - reglas de cotización
   - validación
   - creación de reserva
   - cálculo de balance, extras y pagos

2. `Public API`
   - endpoints JSON para cotizar, reservar, consultar reserva y confirmar pago

3. `Embed UI`
   - widget o formulario instalable en el sitio del cliente

4. `Installer`
   - instalación técnica en clientes Btec desde release + predeploy

## Principio clave

El sitio público no debe hacer `INSERT` directo a tablas ni calcular tarifas desde archivos sueltos.

Debe consumir endpoints como:

- `POST /booking/api/quote`
- `POST /booking/api/reservations`
- `GET /booking/api/reservations/{idr}`
- `POST /booking/api/payments/confirm`

## Modelo funcional recomendado

### Módulo 1: Booking Core

Responsabilidad:

- normalizar reglas de negocio
- centralizar cotización
- centralizar creación de reserva
- registrar eventos del flujo

Tablas sugeridas nuevas:

- `btec_booking_channels`
- `btec_booking_quotes`
- `btec_booking_events`
- `btec_booking_payment_attempts`
- `btec_booking_settings`

Notas:

- `reservas` sigue siendo la tabla operativa final
- `btec_booking_quotes` sirve para auditoría y recuperación de cotizaciones
- `btec_booking_settings` guarda configuración pública por cliente

### Módulo 2: Pricing Engine

Responsabilidad:

- resolver tarifa final a partir de zona, servicio, vehículo, extras y moneda

Primera decisión fuerte:

- no seguir acoplado a `cars + tarifas + hoteles` como única forma de cálculo

Recomendación MVP:

- mantener compatibilidad con esas tablas en fase 1
- encapsular el cálculo en una sola función del core

Ejemplo:

- `btec_booking_build_quote(mysqli $conn, string $ida, array $input): array`

Así luego podrás migrar el origen de datos sin romper el widget público.

### Módulo 3: Public Widget

Responsabilidad:

- mostrar el formulario público
- consumir API
- heredar branding del cliente

Formatos posibles:

1. Página hospedada por el mismo cliente
2. Script embebible
3. Iframe

Recomendación inicial:

- empezar con página hospedada en el cliente
- después sacar un script embebible

Razón:

- menos fricción con CORS, estilos, sesiones y pagos

### Módulo 4: Installer

Responsabilidad:

- dejar listo el motor en un cliente Btec sin copiar archivos manualmente uno por uno

Debe ejecutar:

1. migraciones SQL
2. alta de configuración base
3. despliegue de endpoints públicos
4. despliegue del widget
5. alta de menú administrativo

Esto encaja como módulo `predeploy required`.

### Permisos de despliegue web

En Bitnami, Apache corre normalmente como usuario `daemon`, mientras que los sitios suelen pertenecer a `bitnami`. Antes de instalar módulos que crean carpetas públicas o wrappers administrativos desde el panel, preparar el cliente con:

```bash
/home/bitnami/htdocs/btec-core/bin/prepare-client-web-writes.sh /opt/bitnami/apache/htdocs/cliente/btec_v1
```

El deploy del motor de reservas también aplica estas ACL automáticamente:

```bash
/home/bitnami/htdocs/btec-core/bin/deploy-booking-engine-public.sh /opt/bitnami/apache/htdocs/cliente/btec_v1
```

## Qué sí reutilizar del sistema actual

- tabla `reservas`
- estructura multi-tenant por `ida`
- módulo instalador de `btec-core`
- flujo de releases
- correos y confirmaciones, pero refactorizados a helpers reutilizables

## Qué no conviene copiar tal cual

- `mt/index.php` como plantilla maestra
- SQL embebido en vistas
- `INSERT` directos con variables interpoladas
- confirmaciones de pago mezcladas con render HTML
- dependencias a tablas legacy sin capa intermedia

## Diseño técnico inicial

### A. Capa admin

Nueva pantalla del módulo:

- `pages/booking-engine.php`

Desde ahí el cliente Btec podrá configurar:

- colores y logo del widget
- servicios habilitados
- métodos de pago
- textos legales
- dominio o ruta pública
- canal de origen

### B. Capa API

Wrappers públicos sugeridos en el cliente:

- `booking/api/quote.php`
- `booking/api/create-reservation.php`
- `booking/api/get-reservation.php`
- `booking/api/confirm-payment.php`

Lógica real en el core:

- `func/booking/quotes.php`
- `func/booking/reservations.php`
- `func/booking/payments.php`

Esto sigue el patrón correcto: wrappers mínimos en cliente y lógica versionada en `btec-core`.

### C. Capa visual

Rutas públicas sugeridas:

- `booking/index.php`
- `booking/reservation.php`
- `booking/assets/*`

Primera versión:

- formulario multipaso
- cotización dinámica
- confirmación de reserva
- lookup por `idr`

## Compatibilidad con clientes actuales

No conviene reemplazar de golpe `mt`.

Hazlo en dos etapas:

### Etapa 1

Crear el nuevo motor y usar tablas actuales como backend de compatibilidad.

### Etapa 2

Migrar clientes uno por uno del `mt` viejo al `booking/` nuevo.

Eso reduce riesgo operacional.

## Estrategia de instalación

## Tipo de módulo

`booking-engine-public` debe declararse como `predeploy required`.

Motivo:

- necesita endpoints públicos
- necesita vistas PHP públicas
- probablemente necesita assets
- puede requerir enlaces desde sitio o menú

## Archivos mínimos por cliente

- `booking/index.php`
- `booking/reservation.php`
- `booking/api/*.php`
- `func/booking/*.php` o wrappers hacia `.btec-core`

## Parte instalable desde UI

La activación desde `modulos-btec.php` debe:

- crear tablas `btec_booking_*`
- registrar settings default
- registrar entradas de menú
- dejar estado del módulo como instalado

## Parte de predeploy

El release debe incluir:

- wrappers PHP
- assets del widget
- endpoints públicos

## MVP recomendado

No intentes incluir tours, restaurantes, cupones complejos y todos los casos desde el día 1.

Empieza con este MVP:

1. Transfer privado aeropuerto
2. `oneway`, `roundtrip`, `departure`
3. cotización por hotel/zona + vehículo + extras
4. creación de reserva en `reservas`
5. pago online o pago a destino
6. consulta de reserva por `idr`

Después agregas:

- actividades
- cupones
- multi-moneda más completa
- agencias afiliadas
- integración avanzada con PayPal o Stripe

## Orden de trabajo recomendado

### Fase 1. Canonicalizar reglas

Definir una sola función de cotización y una sola función de creación de reserva.

Entregable:

- helpers en `btec-core/releases/v1.2.0/func/booking/`

### Fase 2. API pública

Exponer endpoints JSON reutilizables.

Entregable:

- wrappers en cliente
- respuestas consistentes
- validación server-side

### Fase 3. UI pública

Construir nuevo `booking/index.php` desacoplado del SQL.

Entregable:

- frontend que solo consume API

### Fase 4. Instalador

Crear el módulo para instalar y activar por cliente.

Entregable:

- entrada en catálogo
- SQL idempotente
- documentación de predeploy

### Fase 5. Migración canary

Montarlo primero en un cliente controlado, idealmente el mismo `loscabostransfer`.

## Primer corte de implementación sugerido

Si quieres empezar con el menor riesgo, el primer sprint debería hacer solo esto:

1. crear helpers `quote` y `create reservation` dentro de `btec-core`
2. crear endpoint `booking/api/quote.php`
3. crear endpoint `booking/api/create-reservation.php`
4. clonar lo mínimo del formulario actual para consumir esos endpoints
5. probar con un cliente canary

## Conclusión

No empezaría por el instalador.

Empezaría por definir el **motor canónico de cotización y reserva** dentro de `btec-core`, porque el instalador solo vale la pena cuando ya existe algo estable que instalar.

El orden correcto es:

1. dominio de reservas
2. API pública
3. UI pública
4. instalador por módulo
